0

我有一个派生自的类QThreadclass 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工作。线程启动后,恕我直言Qt::QueuedConnection是正确的选择(跨线程)。

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

编辑 1:——截至海德的回答/尼科斯的评论

截至目前,我认为海德的回答/尼科斯的评论指出了根本原因。我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 循环中),并且只是QCoreApplication::processEvents();在“我的循环”中仍然无法正常工作。

=> 在此处查看新问题:如何结合自己的消息循环和 Qt 事件循环?

4

1 回答 1

2

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

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

相关阅读: https ://www.qt.io/blog/2010/06/17/youre-doing-it-wrong

另外:如果你重写 QThread::run(),你必须调用QThread::exec()那里,否则事件循环将不会运行,并且没有非直接信号被传递到具有该线程亲和力的任何 QObject。如果你想拥有自己的事件循环,那是可能的,你只需要调用QCoreApplication::processEvents()来处理 Qt 事件。

于 2012-10-20T18:55:47.710 回答