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

5
如果我打开一个Python解释器并输入以下几行代码:
from PyQt4 import QtGui
app = QtGui.QApplication([])
w = QtGui.QLineEdit()
w.show()

然后出现一个文本输入部件。我可以在与解释器交互时与之交互。如果我已经附加了任何事件处理程序,它们也会被调用。

如果我执行 import time; time.sleep(10),该部件将在10秒钟内变得无响应。

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

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

我还想了解Qt在哪里连接到CPython以允许解释器和GUI处于活动状态。我知道Python 2(可能还有3?)有所谓的 PyOS_InputHook 机制,大约每秒钟调用大约10次。IPython使用此机制运行GUI(需要大量努力以更快地处理GUI事件)。当我实例化 QApplication 时是否发生相同的事情?如果是,那么再次运行 app.exec_() 的意义是什么?


你使用的是哪个Python解释器?是IPython还是普通的Python?如果你将相同的代码放在.py文件中运行,那么你不会得到相同的行为,这是可以推测的。 - three_pineapples
这种情况在Python和IPython中都会发生。如果我将代码放入.py文件中并将该文件导入会话中,则会出现上述行为。如果我运行python script.py,则脚本会很快完成并且GUI窗口会立即消失。 - Gus
1个回答

8
当您在交互式会话中使用PyQt/PySide时,事件处理会在后台自动设置,以一种允许您直接与对象交互的方式。例如,在窗口仍然可见的情况下,您可以从python shell中创建并显示一个窗口,然后向其中添加其他小部件。但这种行为仅限于交互式会话 - 它只是为了让您轻松地实验,而不必费心设置事件处理。

根据PyQt文档, PyOS_InputHook 用于在交互式解释器等待用户输入时处理事件(请参见: 从Python Shell使用 PyQt5 ) - 并且假定PySide也使用类似的机制。
对于从脚本启动的普通PyQt/PySide应用程序,您必须显式调用 app.exec_() 才能开始事件处理。否则,脚本将在执行所有代码后立即退出(即像任何其他python脚本一样)。
(有关Qt事件处理的更深入探讨,请参见:线程,事件,QObjects)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接