如何在线程和子线程之间设置信号/插槽连接



我有一个从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中

最新更新