Qt Thread对象只发送信号为Qt:DirectConnection - 为什么? [英] Qt Thread object only sending signal as Qt:DirectConnection - why?
问题描述
我有一个类派生自 QThread
: class MyClass:public QThread
此类连接与另一个对象的插槽。最初这是连接为 Qt :: AutoConnection
。但是,一旦线程启动( MyClass :: run()
) - 信号不再到达槽(为什么? strong>)。
//在myObject-> run之前连接
s = QObject :: connect b $ b _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: - 截至海德的回答/ Nikos的评论
回答/ 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();
工作。
=>请参阅这里的新问题: Qt:如何结合自己的消息循环和Qt事件循环?
很难说没有看到所有的代码,但它可能是因为:
QThread对象本身不是线程,它的线程控制器。最重要的是,QThread对象的线程亲和力应该不是它控制的线程。如果你的线程运行Qt事件循环,那么最好避免子类化QThread。相反,在另一个QObject中有你的逻辑(线程间隙等),你移动到创建它之后用moveToThread创建的线程。子类QThread的唯一真正原因是覆盖 相关阅读: 添加: I have a class derived from My first idea was that I need to force Any idea what is going wrong? The connection itself seems to be correct, otherwise it was not working at (mean even not with Edit 1: -- As of hyde's answer / Nikos' comment As of right now I think hyde's answer / Nikos' comment are pointing out the root cause. My Guess due to this infinite loop the Qt message loop is not running and no signal / slots are processed (is this correct?) When forcing The question is now, how can I combine the Qt and my own message loop (if this is feasible)? Cannot call exec() before the loop (because then it is in the Qt loop), and just the => see new Question here: Qt: How to combine own message loop and Qt event loop? Hard to say without seeing all the code, but it may be because of this: QThread object itself is not the thread, it's the thread controller. Most importantly, QThread object's thread affinity should not be the thread it controls. If your thread runs Qt event loop, then it's best to avoid subclassing QThread. Instead, have your logic (inter-thread slots etc) in another QObject, which you move to the thread you created with moveToThread after creating it. Only real reason to subclass QThread is to override Related reading:
http://blog.qt.digia.com/2010/06/17/youre-doing-it-wrong/ Additon:
If you override QThread::run(), you have to call 这篇关于Qt Thread对象只发送信号为Qt:DirectConnection - 为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! run()
方法,不使用 exec()
/ p>
http://blog.qt.digia.com/2010/06/17/youre-doing-it-wrong/
如果你重写QThread :: run(),你必须调用 QThread :: exec()
并且没有非直接信号被传递到具有该线程亲和力的任何QObject。如果你想有自己的事件循环,这是可能的,你只需要调用 QCoreApplication :: processEvents()
来处理Qt事件。QThread
: class MyClass : public QThread
This class is connected with a slot of another object. Originally this was connected as Qt::AutoConnection
. But then - as soon as the thread is started (MyClass::run()
) - the signal is no longer "reaching the slot" (why?).// 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
will be cross threaded). In this case it does not work at all. Only Qt::DirectConnection
works. After the thread is started, IMHO Qt::QueuedConnection
is the correct choice (cross thread).Qt::DirectConnection
).QThread
is running it's own message loop for another application. This is the reason why it is running in its own thread and is basically an infinite looprun() {
// exec(); // while not reached
while (_runMessageLoop && ...) {
hr = CallDispatch(.....);
if (hr== 0) QThread::msleep(100);
// QCoreApplication::processEvents();
}
}
Qt::DirectConnection
the methods are called directly with no Qt message loop required, this might be the reason why this is the only connection type working.QCoreApplication::processEvents();
in "my loop" is still not working.run()
method with one which does not call exec()
.QThread::exec()
there or event loop won't be running and no non-direct signal gets delivered to any QObject with that thread affinity. If you want to have your own event loop, that is possible, you just have to call QCoreApplication::processEvents()
to process Qt events.