PyQt/PySide 事件循环 运行 在哪里?

Where is the PyQt/PySide event-loop running?

如果我打开 Python 解释器并输入以下行:

from PyQt4 import QtGui
app = QtGui.QApplication([])
w = QtGui.QLineEdit()
w.show()

然后会出现一个文本输入小部件。我可以在与口译员互动时与它互动。如果我附加了任何事件处理程序,它们也会被调用。

如果我这样做 import time; time.sleep(10),Widget 会停止响应 10 秒。

如果我 运行 app.exec_(),该调用会阻塞,直到我关闭应用程序。

我的问题是:如果小部件已经响应事件,运行ning app.exec_() 有什么意义?有什么不同吗?它只是一种防止应用程序关闭的方法,同时仍然为 Qt 的事件循环提供服务(while True: pass 会导致事件循环阻塞,正如我们从 time.sleep(10) 中理解的那样)

我还想了解 Qt 在何处挂接到 CPython 以允许解释器和 GUI 处于活动状态。我知道 Python 2(可能还有 3?)有一个所谓的 PyOS_InputHook 机制,大约每秒调用 10 次。 IPython 将其用于 运行 GUI(需要付出大量努力才能使 GUI 事件的处理速度快于每秒 10 次)。当我实例化 QApplication 时是否发生了同样的事情?如果是这样,那么调用 app.exec_()

的意义何在?

当您在交互式会话中使用 PyQt/PySide 时,系统会在后台自动设置事件处理,使您可以直接与对象进行交互。因此,例如,您可以创建并显示 window,然后在 python shell 中向其添加其他小部件,同时 window 仍然可见。不过,此行为特定于交互式会话 - 它只是让您可以轻松地进行实验,而无需自己设置事件处理的麻烦。

根据 PyQt 文档,PyOS_InputHook 用于在交互式解释器等待用户输入时处理事件(请参阅:Using PyQt5 from the Python Shell)——并且 PySide 可能也使用了类似的机制.

对于从脚本启动的普通 PyQt/PySide 应用程序,您 必须 显式调用 app.exec_() 才能启动事件处理。否则,脚本将在所有代码执行完毕后立即退出(即就像任何其他 python 脚本一样)。

(要更深入地了解 Qt 的事件处理,请参阅:Threads, Events, QObjects)。