我有一个应用程序,其中每个线程(主线程除外)需要创建它自己的窗口。我尝试创建一个线程,然后在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