How to avoid Qt app.exec() blocking main thread
Most of the time, "main thread" == "GUI thread", so people use those terms interchangeably -- even the official documentation does that. I agree that it's confusing though, because they don't have to be the same.^ The actual rule is this:
GUI classes must only be accessed from the thread which instantiates
QApplication
/QGuiApplication
With a plugin like yours, here is what you need to do:
- Create a new
std::thread
(NOT aQThread
) - Run an
init
function in that thread. Let it instantiate yourQApplication
/QGuiApplication
and start the event loop - Ensure that all your GUI objects are accessed from that thread only.
Voila, you now have a GUI thread that is not your main thread.
^Note: It is a different story on Mac OS X. Due to restrictions in the Cocoa framework, the main thread MUST be the GUI thread. The steps I outlined above will work on Windows/Linux but not on Mac. For Mac, you need to inject your code into the main thread -- see Kuba Ober's comments below.
QApplication In Non-Main Thread
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.
QApplication in a non-main thread of second process with pyQt4: is this code legal, and if not, why does it work?
The concept of main thread is not clearly defined in Qt documentation. Actually, the main thread of a process (process that executes the Process.run function) can be different from the main Qt thread (thread that instantiates the first Qt object like a QApplication), although both "main" threads are often the same one.
Example of valid code structure:
function below will run in the process' non-main thread 'thread-1', that will become immediately Qt's main thread.
def startThread1():
app = QApplication(sys.argv)
app.exec_() # enter event loop
code below run in process' main thread, not to be confused with the main Qt and unique GUI thread of the process.
thread1 = Thread(target=self.startThread1)
thread1.start()
input('I am busy until you press enter')
Related Topics
Splitting a String by a Character
C++ #Include <Atlbase.H> Is Not Found
Unordered_Map Hash Function C++
Why Is Protected Constructor Raising an Error This This Code
Dereferencing an Invalid Pointer, Then Taking the Address of the Result
Why Do We Need to Use Boost::Asio::Io_Service::Work
Static Constexpr Member of Same Type as Class Being Defined
Sorting Two Corresponding Arrays
How to Call MAChine Code Stored in Char Array
May Std::Vector Make Use of Small Buffer Optimization
C++ Object Size with Virtual Methods
Aliasing T* with Char* Is Allowed. Is It Also Allowed the Other Way Around