我有一个应用程序,其中每个线程(主线程除外)需要创建自己的窗口。我尝试创建一个线程,然后在this->exec()
函数中调用run
。但是,在我接到电话之前,我收到了一个错误:ASSERT failure in QWidget: "Widgets must be created in the GUI thread."
我想弹出一个消息窗口。问题是源有多个线程,每个线程可能需要弹出自己的消息。
答案 0 :(得分:21)
如果你需要在不同的(非主要)线程中创建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 ) );
..
开心,:)
答案 1 :(得分:7)
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
函数执行您需要它执行的操作。
答案 2 :(得分:1)
我不相信这是可能的。其他非GUI组件可以在其他线程中运行,并且通常通过信号/插槽机制进行通信。