虽然我对QObject
,QThread
以及如何在Qt中使用多线程有相当多的了解,但我无法理解某些场景。
考虑将class Myclass : QObject
移至另一个QThread
。
class MyClass : QObject
{
public slots:
void slot1();
bool slot2();
void slot3();
}
我有一个班级
class Window
{
signals:
void sig1();
bool sig2();
private:
MyClass *myObj;
public:
void func()
{
connect(this, SIGNAL(sig1()), myObj, SLOT(slot1()), Qt::DirectConnection);
emit sig1();
qDebug("SIGNAL1 emitted!");
connect(this, SIGNAL(sig2(bool)), myObj, SLOT(slot2(bool)));
bool result = emit sig2();
myObj->slot3();
}
}
发出sig1
后,我了解只有在qDebug()
执行后才会执行slot1()
。但是slot1
或Window thread
?
MyClass thread
如果sig2
保证result
将存储slot2
返回的值,或者此连接是否必须是直接的?
如图所示运行slot3
是否正确? slot3
修改myObj
的类变量,并发出SIGNAL
,该SLOT
与调用Window object
的{{1}}相关联。如果它是正确的,那么Window
的插槽何时执行以及在哪个线程中?
答案 0 :(得分:2)
当发出sig1时,我知道只有在执行slot1()之后才会执行qDebug()。
默认情况下不保证。只要Qt事件循环将其调回,就可以在函数或方法之前或之后在connect语句之后调用该槽。如果为最后一个参数Qt :: ConnectionType`指定直接连接,则将保证立即调用。有关详细信息,请参阅文档:
Qt :: DirectConnection 1当发出信号时,立即调用插槽。
但是,如果您没有明确指定,Qt::AutoConnection
是默认值。
但是在Window线程或MyClass线程中执行了slot1吗?
它再次取决于连接类型参数。有关详细信息,请参阅documentation。
简而言之,如果它排队,则在接收者的线程中执行,否则从与接收者不同的线程执行。
如果sig2保证结果将存储slot2返回的值,或者此连接是否必须是直接的?
这看起来不对。信号意味着要避免,并且您不能将它们的返回值存储为函数或方法返回值,期望它是连接槽的结果。
即使你可以,也会让人感到困惑,因为同一个信号可以连接多个插槽。更重要的是,信号可以连接到信号。
如图所示运行slot3是否正确? slot3修改myObj的类变量,并发出一个连接到调用Window对象的SLOT的SIGNAL。如果它是正确的,那么什么时候执行Window的插槽和哪个线程?
是的,您可以这样调用它,因为插槽只是常规函数,通常具有void返回值类型。
答案 1 :(得分:1)
问题#1。如果您没有在默认情况下强制DirectConnection,则在不久的将来某个时间将在包含MyClass的线程中执行插槽1。这种方式的工作方式是默认情况下信号/插槽将使用QueuedConnection作为交叉线程信号和插槽。
也是你的
qDebug("SIGNAL1 emitted!");
默认情况下执行slot1()后,不保证执行。如果包含MyClass对象的线程忙,则slot1()的执行将被延迟()。
但是,由于您强制DirectConnection slot1()将在发出信号的线程中执行,并且在qDebug返回之前也将保证执行。
问题#2。我认为连接需要是直接的,才能正确返回结果的值。我相信你必须强制直接连接才能发挥作用。并且还要记住,强制DirectConnection意味着插槽的执行将发生在发出信号的线程中,而不是发生拥有MyClass的线程。我相信文档不鼓励使用插槽中的返回值,所以我从未在生产代码中这样做过。不使用返回值的一个原因是,如果将多个插槽连接到同一信号,则会出现令人困惑的行为。
问题#3。你可以这样做但请记住,代码将在当前线程中执行,而不是拥有MyClass的线程。