如何在不同的QT线程中创建窗口?

时间:2012-03-19 21:02:57

标签: c++ multithreading qt user-interface

我有一个应用程序,其中每个线程(主线程除外)需要创建自己的窗口。我尝试创建一个线程,然后在this->exec()函数中调用run。但是,在我接到电话之前,我收到了一个错误:ASSERT failure in QWidget: "Widgets must be created in the GUI thread."

我想弹出一个消息窗口。问题是源有多个线程,每个线程可能需要弹出自己的消息。

3 个答案:

答案 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组件可以在其他线程中运行,并且通常通过信号/插槽机制进行通信。