2012-10-19 155 views
0

我有一個派生自QThread的類:class MyClass : public QThread 此類與另一個對象的插槽相連。最初這被連接爲Qt::AutoConnection。但是 - 只要線程啓動(MyClass::run()) - 信號不再「到達插槽」(爲什麼?)。Qt線程對象只發送信號爲Qt:DirectConnection - 爲什麼?

// 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();仍然不起作用。

=>在這裏看到新的問題:How to combine own message loop and Qt event loop?

+1

連接的類型基於兩個對象的線程關係。請參閱http://qt-project.org/doc/qt-4.8/thread-basics。html#qobject-and-threads您是否確定在建立連接時建立了正確的線程關聯? –

+1

你的QThread的事件循環實際上在運行嗎?如果'MyClass :: run()'阻塞而不是調用'exec()',則不會發生事件調度。你的QThread子類幾乎像QApplication一樣行爲;它必須讓它的事件循環自然運行。 –

+0

我的消息循環沒有Qt特定的消息循環,但是一個用於Microsoft FSX(飛行模擬器)。基本上它就像while(running){dispatch fsxEvent;睡眠(somems)}。任何我可以包含的事件調度? –

回答

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事件。

+0

我已經嘗試過幾乎所有的排列組合。帶/不帶子類QThread的MoveToThread,在啓動線程之前/之後連接。總是一樣。線程啓動後通信崩潰。儘管如此,每一個好的提示和文章。 –

+1

根據上述問題的評論,將自定義事件循環的內容添加到我的答案中。 – hyde

+0

謝謝,我開始明白了。由於我有自己的循環,Qt的信號/插槽不會被處理。更新了原來的問題。感謝迄今爲止的所有努力,至少現在有一個想法,問題來自何處。 –