我有一个源自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::QueuedConnection
(this
/ _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?
答案 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事件。