[英]Is it possible to force execute main thread (GUI thread) from render thread?
[英]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 是可選的。
兩個注意事項:
QMetaObject::invokeMethod
放棄信號,它刪除了樣板,但是可以通過引用在編譯時檢查的 class 方法來連接信號; QMetaObject 方法在運行時使用字符串匹配。 同樣使用公共信號,但受保護的插槽,您可以確保外部代碼不會意外地直接調用方法。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.