我有一個應用程序,其中每個線程(主線程除外)需要創建它自己的窗口。我嘗試創建一個線程,然後在run
函數中調用this->exec()
。但是,在我接到該呼叫之前,我收到錯誤:ASSERT failure in QWidget: "Widgets must be created in the GUI thread."
如何在不同的QT線程中創建一個窗口?
我想彈出消息窗口。問題是源有多個線程,每個線程可能需要彈出自己的消息。
我有一個應用程序,其中每個線程(主線程除外)需要創建它自己的窗口。我嘗試創建一個線程,然後在run
函數中調用this->exec()
。但是,在我接到該呼叫之前,我收到錯誤:ASSERT failure in QWidget: "Widgets must be created in the GUI thread."
如何在不同的QT線程中創建一個窗口?
我想彈出消息窗口。問題是源有多個線程,每個線程可能需要彈出自己的消息。
如果你需要創建QWidget的(或其他一些GUI組件(S))在不同的(非主)線程(S),你可以在這樣的方式實現:
創建簡單的包裝,其保持GUI部件:
// gui component holder which will be moved to main thread
class gui_launcher : public QObject
{
QWidget *w;
// other components
//..
public:
virtual bool event(QEvent *ev)
{
if(ev->type() == QEvent::User)
{
w = new QWidget;
w->show();
return true;
}
return false;
}
};
創建在主線程
另一個線程體QApplication對象:
..
// create holder
gui_launcher gl;
// move it to main thread
gl.moveToThread(QApplication::instance()->thread());
// send it event which will be posted from main thread
QCoreApplication::postEvent(&gl, new QEvent(QEvent::User));
..
快樂,:)
你好,我做只是爲了好玩 \t模板
我不相信這是可能的。其他非GUI組件可以在其他線程中運行,並且通常通過信號/插槽機制進行通信。
Qt將只允許您在GUI線程中創建GUI元素 - 您需要從其他線程顯示什麼?有關使用非GUI線程中的數據更新進度條的示例,請參閱This answer之類的內容。
更新:
如果你想顯示每個窗口的消息,你可以有一個這樣的類:
class MyWorkerThread : public QThread
{
Q_OBJECT
signals:
void sendMessage(QString msg);
private:
void run()
{
/* do stuff */
emit sendMessage(QString("This thread is doing stuff!"));
/* do more stuff */
}
};
然後通過信號插槽將其連接在你的GUI機制類似於:
connect(workerThread, SIGNAL(sendMessage(QString)),
guiController, SLOT(showMessageBox(QString)));
其中showMessageBox
函數完成您所需要的功能。
上述答案可以與QAction
對象(或自定義類對象)被組合以任何動作傳遞到主界面線程中執行,而不是僅僅創建窗口小部件或顯示消息框。 (例如,通過發出sendAction(QAction*)
,或實現體現QAction*
的自定義QEvent
類。)
不要試圖從後臺/工作線程顯示UI。而是從主GUI線程顯示該UI。安排您的背景/工作人員發出GUI線程信號,以完成此任務。本示例顯示瞭如何執行此操作:http://doc.qt.nokia.com/4.7-snapshot/thread-basics.html#example-3-clock。 – 2012-03-19 21:48:16