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()
i
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.
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.
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*
.)
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, :)