如何在不同的 QT 线程中创建一个窗口?
Posted
技术标签:
【中文标题】如何在不同的 QT 线程中创建一个窗口?【英文标题】:How do I create a Window in different QT threads? 【发布时间】:2012-04-04 09:29:14 【问题描述】:我有一个应用程序,其中每个线程(主线程除外)都需要创建自己的窗口。我尝试创建一个线程,然后在run
函数中调用this->exec()
。但是,在我接到那个电话之前,我收到了一个错误:ASSERT failure in QWidget: "Widgets must be created in the GUI thread."
我想弹出一个消息窗口。问题是源有多个线程,每个线程可能需要弹出自己的消息。
【问题讨论】:
不要尝试从后台/工作线程显示 UI。而是从主 GUI 线程显示该 UI。安排您的后台/工作人员向 GUI 线程发出信号以完成此操作。这个例子展示了如何做到这一点:doc.qt.nokia.com/4.7-snapshot/…. 【参考方案1】:如果您需要在不同的(非主)线程中创建 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 线程的数据更新进度条的示例,请参见 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
函数在哪里执行您需要它执行的操作。
【讨论】:
抱歉等待,我正在测试你的答案。 这是从 QThread 调用 QMessageBox 的完整示例。它与您的示例非常相似。 ***.com/a/23992291/999943【参考方案3】:我不相信这是可能的。其他非 GUI 组件可以在其他线程中运行,并且通常通过信号/插槽机制进行通信。
【讨论】:
【参考方案4】:以上答案可以与QAction
对象(或自定义类对象)结合,将任何操作传输到要执行的主 GUI 线程,而不仅仅是创建小部件或显示消息框。 (例如,通过发出 sendAction(QAction*)
,或实现包含 QAction*
的自定义 QEvent
类。)
【讨论】:
以上是关于如何在不同的 QT 线程中创建一个窗口?的主要内容,如果未能解决你的问题,请参考以下文章