我有一个程序,在该程序中,除了主线程外的每个线程都需要创建自己的窗口。我尝试创建一个线程,然后在run
函数中调用this->exec()
。然而,在我甚至没有到达该调用前就出现了错误:ASSERT failure in QWidget: "Widgets must be created in the GUI thread."
我想弹出一个消息窗口。问题是源代码有多个线程,每个线程都可能需要弹出自己的消息。
我有一个程序,在该程序中,除了主线程外的每个线程都需要创建自己的窗口。我尝试创建一个线程,然后在run
函数中调用this->exec()
。然而,在我甚至没有到达该调用前就出现了错误:ASSERT failure in QWidget: "Widgets must be created in the GUI thread."
我想弹出一个消息窗口。问题是源代码有多个线程,每个线程都可能需要弹出自己的消息。
如果您需要在不同(非主)线程中创建QWidget(或其他GUI组件),可以按照以下方式实现:
创建一个简单的包装器来保存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 ) );
..
保持快乐, :)
Qt只允许在GUI线程中创建GUI元素 - 您需要从其他线程显示什么内容?请参考此答案,了解如何使用来自非GUI线程的数据更新进度条的示例。
更新:
如果您想要为每个窗口显示一条消息,您可以拥有这样的一个类:
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
函数可以实现您所需的功能。
我不相信这是可能的。其他非GUI组件可以在其他线程中运行,并通常通过信号/槽机制进行通信。
QAction
对象(或自定义类对象)结合使用,以传输任何操作到主GUI线程以执行,不仅仅是创建小部件或显示消息框。(例如通过发射sendAction(QAction*)
,或实现一个包含QAction*
的自定义QEvent
类。)