2012-03-09 65 views
1

我有一個信號丟失的情況,我不明白爲什麼 - 通常在事件循環開始之前發送的信號剛剛排隊併發送。之前的信號QThread事件循環開始丟失

這是代碼的樣子(一個QThread的對象):

void OffloadHandler::run() 
{ 
    cout << "Start" << endl; 
    connect(this, SIGNAL(loopStarted()), SLOT(onLoopStarted()), Qt::QueuedConnection); 
    emit loopStarted(); 
    exec(); 
} 

void OffloadHandler::onLoopStarted() 
{ 
    cout << "Here!" << endl; 
} 

線程在其他地方開始,Start被寫入到控制檯,但Here1從來就是 - 信號沒有被接收。我在我的主要消息循環中使用了相同的模式,它可以工作,但在這個線程消息循環中看起來不起作用。

我的代碼裏有什麼明顯的錯誤嗎?

+0

這個「loopStarted」在哪裏發射? – Koying 2012-03-09 18:11:43

+0

在線程中。 – 2012-03-09 18:13:58

回答

0

好吧,我明白了,我被QThread的所有權怪異所困擾。連接到QThread對象本身時必須非常小心,因爲默認情況下該對象不屬於該線程。

因此,在其中創建線程,我必須線程移動到線程點:

OffloadHandler * oh = new OffloadHandler(); 
oh->moveToThread(oh); //MOVE TO SELF! 
oh->start(); 

一旦我做到這一點的信號正常工作。

+0

儘管Qt文檔建議子類化QThread,但通常認爲它與預期用途相反。將線程移動到自身肯定是一種常見的反模式,它會繼續傳播:)它可以解決您的直接問題,但它產生的問題更隱蔽。在SO上搜索Qt和線程,你會發現許多關於這篇文章的提及:http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/ – 2012-03-10 01:46:12

+0

雖然也許是一個很好的不想子類的想法我沒有看到你能夠在線程中啓動消息循環。 'exec'是一個受保護的成員函數 - 爲此創建一個新的QEventLoop似乎相當愚蠢。 – 2012-03-10 09:14:48

+0

我也不會購買關於不將線程移動到自身的位。線程沒有所有者線程,創建它的線程的特別之處在於它現在是它自己的獨立實體。 – 2012-03-10 09:15:17

1

你的代碼是有效的,它應該運行。你確定你有一個事件循環在oh被創建的線程中運行嗎?

原因emit loopStarted()應發送事件到oh的事件循環,該事件循環將被處理並將呼叫onLoopStarted()。我已經測試了你的代碼,並且適用於我。


順便說一句,這是通常建議您不要添加插槽您QThread,並避免使用moveToThread(this);

不幸的是,我真的不明白你的使用情況,所以我不能給出一個更好解。但是here是一些令人驚歎的文檔,它有關於QThread的好的DO和DONT。

+0

+0.5 :)這是一篇有趣的文章,但我希望它沒有給出''QThread'的實例。我相信那些以「QObject」子類中的工作爲中心並將其轉移到「QThread」實例的建議是更好的選擇。 – 2012-03-10 02:03:37