Qt Thread对象只发送信号为Qt:DirectConnection - 为什么?

时间:2012-10-19 21:08:30

标签: c++ qt signals-slots

我有一个源自QThread的类:class MyClass : public QThread 该类与另一个对象的槽连接。最初这被连接为Qt::AutoConnection。但是 - 一旦线程启动(MyClass::run()) - 信号就不再“到达插槽”(为什么?)。

// connected before myObject->run()
s = QObject::connect(
_myObject, SIGNAL(signalLogMessage(const QString&, QtMsgType)), 
this, SLOT(slotLogMessage(const QString&, QtMsgType)), Qt::DirectConnection);

我的第一个想法是我需要强制Qt::QueuedConnectionthis / _myObject将是交叉线程的)。在这种情况下,它根本不起作用。只有Qt::DirectConnection有效。线程启动后,IMHO Qt::QueuedConnection是正确的选择(交叉线程)。

知道出了什么问题吗?连接本身似乎是正确的,否则它无法正常工作(即使不是Qt::DirectConnection)。

编辑1: - 从hyde的回答/ Nikos的评论

开始

截至目前,我认为hyde的回答/ Nikos的评论指出了根本原因。我的QThread正在为另一个应用程序运行它自己的消息循环。这就是为什么它在自己的线程中运行并且基本上是无限循环

的原因
run() { 
  // exec(); // while not reached    
  while (_runMessageLoop && ...) {
    hr = CallDispatch(.....);
    if (hr== 0) QThread::msleep(100); 
    // QCoreApplication::processEvents();
  }
}

猜测由于这个无限循环,Qt消息循环没有运行,没有处理信号/槽(这是正确的吗?)当强制Qt::DirectConnection时,直接调用方法而不需要Qt消息循环,这可能这就是为什么这是唯一可行的连接类型。

现在的问题是,如何将Qt和我自己的消息循环结合起来(如果可行的话)?无法在循环之前调用exec()(因为它在Qt循环中),而且“my循环”中的QCoreApplication::processEvents();仍然无效。

=>在此处查看新问题:How to combine own message loop and Qt event loop?

1 个答案:

答案 0 :(得分:2)

很难说没有看到所有代码,但可能是因为这个:

QThread对象本身不是线程,它是线程控制器。最重要的是,QThread对象的线程关联性应该是它控制的线程。如果你的线程运行Qt事件循环,那么最好避免继承QThread。相反,将您的逻辑(线程间插槽等)放在另一个QObject中,然后在创建它之后移动到使用moveToThread创建的线程。只有将QThread子类化的真正原因是使用不调用run()的方法覆盖exec()方法。

相关阅读: http://blog.qt.digia.com/2010/06/17/youre-doing-it-wrong/

Additon: 如果重写QThread :: run(),则必须在那里调用QThread::exec()或者事件循环不会运行,并且没有非直接信号传递给具有该线程亲和性的任何QObject。如果您想拥有自己的事件循环,那么您只需调用QCoreApplication::processEvents()来处理Qt事件。