2015-06-04 59 views
0

我已經開發了一個Qt/C++應用程序,我已經使用信號/插槽機制來在兩個線程之間進行交互。第一個線程運行UI/TreeWidget,第二個運行框架Qt/C++如何在發出信號時等待一個插槽

我在一個動作中遇到了問題。

在UI方面,我開始行動之前,我的UI和框架之間的連接信號/槽,如下面的treewidget.cpp

connect(&m_Framework, &Framework::RequestIfNameExist, this, &TreeWidget::RequestIfNameExist); 
connect(this, &TreeWidget::SendAnswerIfNameExist, &m_Framework, &Framework::NotifIfNameExist); 

框架,啓動發送RequestIfNameExist:

emit RequestIfNameExist(tmpname, item, fileInfo.isDir()); 

while(WaitingResponse == false){ 
    usleep(200); 
} 

我添加了一個循環,因爲我需要等待反饋。奇怪的事情是,在treewidget.cpp,我從來沒有在

void TreeWidget::RequestIfNameExist(QString name, TreeWidgetItem *parent, bool isFolder) { 
#ifdef PULS_LOG 
    QLOG_INFO() << "[TreeWidget] [RequestIfNameExist] "; 
#endif 
    emit SendAnswerIfNameExist(isNameExist(name, parent), isFolder); 
} 

我從來沒有訪問RequestIfNameExist在TreeWidget但信號被髮射進入。

我也放了while循環的框架,從TreeWidget

void Framework::NotifIfNameExist(QTreeWidgetItem *item, bool isFolder){ 

    if(item != NULL) 
     item->isFolder = isFolder; 

    WaitingResponse = true; 

} 

等待反饋的任何想法,爲什麼由框架發出的信號無法送達的treewidget?它來自何時?

是否有這樣的「等待事件」 +超時

感謝

+0

Framework線程正在運行while循環,所以它將無法執行'NotifIfNameExist'。框架查詢UI元素loke Treewidget是很奇怪的。 UI通常會查詢類似框架的後端以獲取數據和UI狀態。 –

+1

我想你想爲每個信號「連接」信號類中的信號和插槽。 – zar

回答

4

我首先想到的是,在其他線程具有或者線程塊,直到操作完成的是一個貧窮的方式,同時不使用設計 - 它部分地破壞了具有多個線程的目的,即允許多個操作並行運行。如果你不小心的話,它也容易導致死鎖(例如,如果兩個線程都在同一時間決定發射並等待!)

更好的設計會使啓動方法執行emit RequestIfNameExit然後返回立即,以便啓動線程的事件循環可以繼續照常運行。然後,當另一個線程完成其工作時,通過發出自己的響應信號來進行響應,從而在第一個線程中調用適當的/連接的slot-method,此時結果在第一個線程中被處理。這就是說,如果你堅持要在方法內部阻止信號發射線程的執行,直到另一個線程完成相關的slot-method的執行,你可以通過設置信號/時隙連接的類型爲Qt::BlockingQueuedConnection(連接類型可通過connect()的可選附加參數指定)。如果你這樣做,那麼你發出的呼叫將不會返回,直到slot-method(在另一個線程中)完成執行。鑑於此,您可以通過將指針指向數據對象作爲信號/插槽方法簽名中的參數之一併讓其他線程根據需要填充該數據對象,從而獲得其他線程的結果。當發射返回時,您可以檢查該數據對象的內容以查看結果。