How to avoid Qt app.exec() blocking main thread
-
Hi,
What exactly is your use case ?
-
Hi
Its not blocking it
its driving it. It makes all events go round and signal and slot works.So its 100% normal and needed for event driven app.
But you dont have to use it. but without it. no gui.
-
@SGaist My use case is, I want to build an application which has GUI (using Qt), also has a command line, in the command line, I can type some commands, like > start_window, it will pop up my Qt window, but I still need the command line be available, I mean can type other commands. some of the commands may work on my window, some of them may not
-
In that case you should rather have two applications that interact with each other.
-
@student said in How to avoid Qt app.exec() blocking main thread:
PyQt
I guess it just makes a default one behind the scenes for you.
Much of Qt needs event loop to function at all so there must be one.
-
@student said in How to avoid Qt app.exec() blocking main thread:
I see PyQt don't need the app.exec, we can just run window.show() will be fine. while in C++, it's a must. how does PyQt achieve this?
Here is the program you described:
import sys # from PySide2 import QtWidgets from PyQt5 import QtWidgets if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) window = QtWidgets.QWidget() window.show()
with no
app.exec()
. Unsurprisingly, this does not " we can just run window.show() will be fine", it runs and exits, under both PyQt5 & PySide2. Could you show your code which has noapp.exec_()
yet runs fine? -
@student
Yes, that is not a running program. You have stopped in the Python interpreter with it on the screen. You could accomplish the same from C++ by running from a debugger and breaking after the.show()
. So this does not illustrate anything about "not needing"app.exec()
. So that's your answer to how "PyQt achieves it but C++ does not". PyQt/PySide2/Python are not behaving any differently compared to C++ in this respect. -
@JonB thanks, in the python interpreter, I can still type other command, and the window is also active, I can play with the window, I can also type command (interact with window) in python shell.
While in C++, assume I have the following function, and I compiled it into python, and in python, I run: start_window, it will not pop up.
If I open app.exec(), it can pop up, but the python shell (main thread) was blocked by window.
anything wrong I made here? Thanksvoid start_window()
{
.....
// app.exec();
} -
@student
I'm sorry, I can't keep going through this. In Qt, whether C++/Python/PyQt5/PySide2, you need to spin the main event loop viaQApplication::exec()
to have a proper running application.and the window is also active, I can play with the window,
Show me how your way, with no
app.exec()
, you get the window to e.g. execute slots in response to signals raised, or raise signals which other windows you have opened get to execute their slots on?If you can achieve all this/that you need without an
app.exec()
in Python/PyQt, then you are fine/best of luck.I can also type command (interact with window) in python shell.
I don't know what "command" you can type, or what you count as "interact with window". What I think you want is to use the Python interpreter at this point (no idea why). I don't know how you can have on the one hand the full-fledged Python interpreter running and waiting for you type some Python into a shell, while at the same time having the UI operating properly without an
app.exec()
. You might achieve this by embedding a Python interpreter into the app for the user, but I don't see how you can do it from the invoking shell. -
Once upon a time I remember being confused about how GUI event loops work. It can initially be confusing and frustrating, then when something works it feels like black magic that still makes little sense.
For someone interested in coming to a full understanding, I will make the observation/recommendation that "Game Engine Architecture" by Jason Gregory has a chapter on "the Game Loop" which is a good overview of the event-loop concept. (ISBN 1138035459)
I'm not a game developer, but that book taught me a lot that I now use as a C++ application programmer.
After you call "app.exec()", you would implement the rest of the interactions in "event handlers" (which in Qt are usually "slots"). Either way, these are functions that you write that will get called by the endless loop that runs inside "exec".
"exec" is just an endless loop, as in:
while (true) { processAllEvents(); }
The Qt framework gives you many ways to "hook into" the event-processing part. You do not need to add new threads to do this. You may, but it is optional.
The concept really is too broad to tackle in one forum thread. Hopefully you can piece together enough clues from what all the respondents have said here.
I would also highly recommend building some of the Qt "examples" projects. Search them for "QCoreApplication" to find command-line/console apps. I found this just now:
qtbase/examples/dbus/complexpingpong/complexpong.cpp
https://doc.qt.io/qt-5.9/qtdbus-complexpingpong-complexpong-cpp.html