Issue
If I open a Python interpreter and enter the following lines:
from PyQt4 import QtGui
app = QtGui.QApplication([])
w = QtGui.QLineEdit()
w.show()
then a text entry widget appears. I can interact with it while I interact with the interpreter. If I had attached any event handlers, they would be called too.
If I do import time; time.sleep(10)
, the Widget becomes unresponsive for 10 seconds.
If I run app.exec_()
, that call blocks until I close the application.
My question is: what is the point of running app.exec_()
if the widget is already responding to events? What is different? Is it just a way of preventing the application from closing while still servicing Qt's event loop (while True: pass
would cause the event loop to block, as we understand from doing time.sleep(10)
)
I would also like to understand where Qt has hooked into CPython that allows the interpreter and the GUI to be active. I'm aware that Python 2 (and possibly 3?) has a so-called PyOS_InputHook
mechanism, which is called roughly 10 times a second. IPython uses this to run a GUI (with lots of effort to handle GUI events faster than 10 times a second). Is the same thing happening when I instantiate a QApplication
? If so, again, what is the point of calling app.exec_()
Solution
When you use PyQt/PySide in an interactive session, the event processing is set up automatically in the background in a way that allows you to interact directly with the objects. So for example you could create and show a window, and then add other widgets to it from within the python shell whilst the window is still visible. This behaviour is specific to interactive sessions, though - it's only there to allow you to easily experiment with things without the hassle of setting up the event processing yourself.
According to the PyQt Docs, PyOS_InputHook
is used to process events whilst the interactive interpreter is waiting for user input (see: Using PyQt5 from the Python Shell) - and presumably a similar mechanism is also used by PySide.
For a normal PyQt/PySide application started from a script, you must explicitly call app.exec_()
in order to start event handling. Otherwise, the script will just exit as soon as all the code has been executed (i.e. just like any other python script would).
(For a more in-depth look at Qt's event-processing, see: Threads, Events, QObjects).
Answered By - ekhumoro
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.