2016-03-02 187 views
0

我嘗試擴展在Ubuntu/Linux桌面下運行的Qt網絡支持的舊程序。經與這些庫LAN通信需要運行QEventLoop的.exec()真正開始工作(即:接受連接,接收,發送等)並行運行多個QEventLoops(用於QtNetwork)

問題

那麼這個問題是我不不知道這個事件循環在主程序中的位置,因爲我隱約知道它的設計,我更喜歡儘可能獨立的解決方案。

我的想法

我已經選中我不需要主QEventLoop,這是正常的,使一個又一個公正的網絡(即嵌套)。不幸的是,我不知道如何並行運行兩個循環,因爲我的程序停在嵌套 - .exec(),所以主程序也停止。

所以我的主要目的實際上是用Qt-Networking擴展主程序,我也對其他解決方案開放。

+0

@KubaOber是的,你是完全正確的。如果您將此作爲答案,我會將其標記爲解決方案。 – user3085931

回答

1

主程序是否互動?如果是,那麼它可能運行glib主事件循環。 Qt在Linux上使用相同的事件循環,因此您不需要在代碼中調用exec()。通過創建一個QEventLoop的實例,向其發佈退出調用,以及exec()這個事件循環,僅填充一次事件循環。然後將控制返回到主程序。當事件到達時(計時器超時,網絡數據包到達等),您的代碼仍然會運行。

您使用Qt獲得的關於本地事件循環集成的奇妙之處在於,如果其他人已經在旋轉循環,則不需要執行主要的exec()

所以,這裏的Qt的插件Linux上的GTK應用程序如何可能看起來像:

extern "C" void pluginInit() { 
    new QApplication; 
    QEventLoop loop; 
    QMetaObject::invokeMethod(&loop, "quit", Qt::QueuedConnection); 
    loop.exec(); 
} 

extern "C" void pluginDestroy() { 
    delete qApp; 
} 

一旦插件用戶來電pluginInit,他們可以調用你的插件使用Qt的任何功能,且事件將被調用應用程序的事件循環正確處理。

與線程相比,我更喜歡這樣的解決方案,因爲它聽起來更穩定一般。

如果線程對你來說不穩定,那麼你做得不對。網絡支持將在專用線程上運行良好。這可能是第二個線程的少數合法用途之一,因爲這樣您的網絡數據處理不會因爲用戶場景渲染器和合成器將屏幕上顯示的內容放在一起所花的甜蜜時間而延遲。

+0

工程像魅力。我從來沒有想過使用'invokeMethod(...)'。非常感謝你 – user3085931

2

如果您需要運行2個獨立的事件循環,我會建議使用QThread。

+0

是否可以保證我的輸入連接將被接受(通過信號/插槽過程),還是可能因爲線程當時沒有運行而導致請求丟失? – user3085931

+1

您必須確保線程正在運行。如果線程沒有運行,線程中的對象'生存'將不會被觸發。出於這個原因,你應該創建線程,將對象移動到線程並啓動線程。然後你可以建立你的連接。 – Paraboloid87