How do I create a Window in different QT threads?

I have an application in which each thread (except the main thread) needs to create its own window. I tried creating a thread and then calling this->exec() in the run function. However, I get an error before I even get to that call: ASSERT failure in QWidget: "Widgets must be created in the GUI thread."

I want to popup a message window. The problem is that the source has multiple threads each of which may need to popup its own message.

Answers


If you need to create QWidget(or some other gui component(s)) in different(non-main) thread(s) you can implement it in such way:

  • Create simple wrapper which holds gui component:

    // 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;
      }
    };
    
  • create QApplication object in main thread

  • another thread body:

    ..
      // 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 ) );
    ..
    
  • be happy, :)


Qt will only let you create GUI elements in the GUI thread - what is it that you need to display from the other threads? See something like This answer for an example of updating a progress bar with data from a non-GUI thread.

Update:

If you want to show a message for each window, you can have a class like this:

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 */
  }
};

Then connect it up to your GUI via the signal-slot mechanism with something like:

connect(workerThread, SIGNAL(sendMessage(QString)),
        guiController, SLOT(showMessageBox(QString)));

Where the showMessageBox function does what you need it to do.


I don't believe this is possible. Other non-GUI components can run in other threads and will usually communicate via the signal/slot mechanisms.


The above answers can be combined with a QAction object (or custom class objects) to transfer any action to the main GUI thread to be executed, not just creating widgets or displaying a message box. (e.g. by emitting sendAction(QAction*), or implementing a custom QEvent class embodying a QAction*.)


Need Your Help

javascript get html or text from div

javascript image json api

This is easy in jquery but how about plain javascript?

Populating a list is Scala with random double taking forever

performance list scala

I am new to Scala and am trying to get a list of random double values: