我有一个从QThread
派生的类ParentThread
,使用以下run()
方法,大致如下:
void ParentThread::run()
{
QThread *childThread = new QThread;
QObject::connect(childThread, SIGNAL(finished()), this, SLOT(onChildThreadFinished());
QObject::connect(childThread, SIGNAL(finished()), childThread, SLOT(deleteLater());
childThread->start();
exec();
}
时隙onChildThreadFinished()
是在ParentThread
上定义的,并且应该在ParentThread
的上下文中运行。然而,使用上面的代码,只有在信号/插槽连接是Qt::DirectConnection
的情况下才会调用onChildThreadFinished
,但随后会在子线程的上下文中运行。如果信号/插槽连接被定义为Qt::QueuedConnection
,则该插槽永远不会被调用。我使用的是问题4.8.5。知道这里的问题是什么吗?
您声明槽onChildThreadFinished()是在ParentThread上定义的,并且应该在ParentThread的上下文中运行。这种假设是错误的。这就是为什么不鼓励对QThread
进行子类化的原因之一。
如果您想在线程中使用slot,子类化QThread
不是您想要做的。请使用worker对象方法。子类QObject
并调用QObject::moveToThread
将对象移动到新线程。
以下是Qt文档对此的看法:
重要的是要记住,QThread实例位于实例化它的旧线程中,而不是位于调用run()的新线程中。这意味着QThread的所有排队槽都将在旧线程中执行。因此,希望在新线程中调用槽的开发人员必须使用worker对象方法;新插槽不应该直接实现到子类QThread中