I need to exec() a QApplication in a thread that is not main (my GUIs must be plugins that can be dynamically loaded and unloaded at runtime, so I have no access to the main thread). Does anyone know of a (relatively) painless way to hack around Qt's restriction against starting QApplication outside of main?
I'm developing in Linux with Qt4 in C++ using gcc4.3.4.
Adding my 2 cents with a fancy lambda and C++ threads:
Here
Mainwindow
can be yourQMainWindow
.If you are using QThread then you already have normal Qt event loop and can just run exec() inside QThread::run() function. While you can't work with GUI objects outside of the main thread you still can interact with them through queued signal/slot connections. Maybe you can try to store pointer to the main thread QThread object and call QObject::moveToThread() to move your GUI objects to the main thread instead of moving QApplication into another thread.
I think it's not really good idea to try to go against toolkit with different kind of hacks and kluges.
Patch Qt, I guess and remove the main thread check, and test if that works for you. According to http://bugreports.qt-project.org/browse/QTBUG-7393 that won't work on OS X/Cocoa though, as Cocoa assumes the first thread spawned to be the main/UI thread.
You can start a QApplication in a PThread as below
//main.cpp
//appthread.h
//appthread.cpp
Ok, I got something that works! It's not pretty, but it definitely does the job.
Create a QMainWindow derivative with all of your actual GUI code in it and overload the event() function of this class to call this->show()
Create a class (let's call it Runner) which will hold a pointer to your QMainWindow derivative, and give it a run function.
In the Runner::Runner(), start up a thread which will call Runner::run()
In Runner::run() (which is now running in it's own thread) construct a QApplication, and an instantiation of your QMainWindow derivative. Call the exec() function of the QApplication.
Now, when you want to start up your GUI, just post any event to your QMainWindow derivative, and it will show itself!
This solution seems to work very well in Linux, although it really seems to be exploiting some loophole in Qt and may not work on other platforms. Definitely easier than patching Qt though.