簡體   English   中英

與不是主線程的 GUI 線程通信

[英]Communicating with a GUI thread that is not the main thread

我設法在工作人員 C++ std::thread中實現了一個基於 GUI Qt 的應用程序,如此所述。 現在我需要主線程和工作線程進行通信。

我的問題是:如何將消息(浮點數組)從主線程傳遞到工作線程,以便更新 GUI?

我有一個執行實時信號處理的應用程序。 我的目標是創建一個 Qt GUI,它可以插入到我的應用程序中,以在不影響實時方面的情況下可視化各種信號。 我研究了如何實現這一點的不同方法,並得出結論,這篇文章非常詳細地描述了我的需求並為此提供了解決方案。 但是,沒有關於主線程和工作線程如何相互通信的信息。

我嘗試使用此處描述的 Futures/Promises 方法來完成線程間通信。 雖然我能夠運行這個示例,但我無法將它集成到我的項目中。 原因是這種方法依賴於工作線程內部的繁忙循環,該循環不斷檢查主線程是否已發送新消息。 但是,在 Qt 應用程序中,一旦進入a.exec()中的主事件循環,程序就會阻塞。 這可以防止繁忙的循環檢查,從而導致程序死鎖。

這就是我生成 GUI 工作線程的方式(基於這篇文章)。

#include <thread>

// Start the Qt realtime plot demo in a worker thread
int argc = 0;
char **argv = NULL;
std::thread t1
        (
                [&] {
                    QApplication application(argc, argv);
                    MainWindow mainWindow;
                    mainWindow.show();
                    return application.exec();
                }
        );

您可以使用 Qt 自己的方法在線程之間進行通信。 每個 Qt object 都有一個線程親和性。 如果您在單獨的 GUI 線程中創建MainWindow object,它將附加到該線程。 如果您使用 Qt 信號和插槽,並將它們與Qt::QueuedConnection連接,則無論信號來自何處,都將通過該線程的主循環在對象的線程中調用插槽。

請注意,您可以在MainWindow class 中定義信號,但可以從外部調用它們,因為它們是公共的。 這意味着您不需要單獨發送 object。 MainWindow構造函數(例如)中,您可以將其自己的信號連接到插槽或 lambda 方法。

為了能夠發出MainWindow信號,您可以在 GUI 線程之外將MainWindow指針設置為 nullptr,並將該指針(通過 lambda 捕獲)設置為您在 GUI 線程內創建的新 object。 在你的線程之外,只要你想發出一個信號,你就可以做某事。 比如if (mainWindow) mainWindow->signal(…) 我假設您無論如何都需要檢查,因為您的 GUI 是可選的。

兩個注意事項:

  1. 您也可以使用QMetaObject::invokeMethod放棄信號,它刪除了樣板,但是可以通過引用在編譯時檢查的 class 方法來連接信號; QMetaObject 方法在運行時使用字符串匹配。 同樣使用公共信號,但受保護的插槽,您可以確保外部代碼不會意外地直接調用方法。
  2. 當您將信號連接到 lambda 時,請確保指定接收 object。 connect(this, &MainWindow::signal, this, [this] {…}); 將在接收線程中執行 lambda, connect(this, &MainWindow::signal, [this] {…}); 不會

對於信號處理,您通常不希望 qts 虛擬調用的開銷。 但除此之外,

一個很好的線程到 gui 通信的解決方案位於:git@github.com:midjji/convenient_multithreaded_qt_gui.git

那么它只是例如

enter code here
run_in_gui_thread(new RunEventImpl([](){
        QMainWindow* window=new QMainWindow();
        window->show();
    }));

可以隨時從任何線程調用,同時在 bg 中為您進行設置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM