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

cha*_*m15 16 c++ user-interface qt multithreading

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

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

小智 22

如果您需要在不同(非主要)线程中创建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;
      }
    };
    
    Run Code Online (Sandbox Code Playgroud)
  • 在主线程中创建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 ) );
    ..
    
    Run Code Online (Sandbox Code Playgroud)
  • 要开心, :)

  • 你好我只是为了有趣的模板<typename mygui> class gui_launcher:public QObject {mygui*w; //其他组件public:void add2Gui(){this-> moveToThread(QApplication :: instance() - > thread()); QCoreApplication :: postEvent(这个,新的QEvent(QEvent :: User)); 虚拟bool事件(QEvent*ev){if(ev-> type()== QEvent :: User){w = new mygui; W->显示(); 返回true; } return false; }}; (2认同)

spb*_*ots 7

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 */
  }
};
Run Code Online (Sandbox Code Playgroud)

然后通过信号插槽机制将其连接到GUI,例如:

connect(workerThread, SIGNAL(sendMessage(QString)),
        guiController, SLOT(showMessageBox(QString)));
Run Code Online (Sandbox Code Playgroud)

showMessageBox功能在哪里完成您需要它做的事情.