在我的PyQt应用程序中,我应该使用`app.exec()`还是`app.exec_()`?

60

我使用Python 3和PyQt5。这是我的测试PyQt5程序,重点关注最后2行:

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys

class window(QWidget):
def __init__(self,parent=None):
    super().__init__(parent)
    self.setWindowTitle('test')
    self.resize(250,200)

app=QApplication(sys.argv)
w=window()
w.show()
sys.exit(app.exec())
#sys.exit(app.exec_())

我知道 exec 是Python中的关键字。但在PyQt5官方文档中的代码 (特别是退出时的对象销毁部分),我看到了使用 app.exec() 的示例,这让我感到困惑。

当我在我的机器上测试时,我发现两者没有任何可见的区别。无论是否有下划线,输出结果都相同,也没有时间差异。

我的问题是:

  • 当我使用 app.exec() 时,是否存在错误? 是否与Python内部的 exec 冲突? 我怀疑这是因为两个exec 都在执行某些内容。
  • 如果没有问题,我可以随意使用它们吗?

17
在PyQt5中,您根本不需要使用sys.exit()。只需使用app.exec_()app.exec()即可正常运行。他们在PyQt5中进行了一些修复,因此您不再需要sys.exit()。如果您想让代码在PyQt4上运行,则需要在那里使用sys.exit()。另外,app.exec_()app.exec()是可以互换的,因此您可以使用任何一个。如果您想让您的代码在PyQt4上正常运行,请坚持使用app.exec_()。因此,要让您的代码在PyQt5 PyQt4上正常工作,请使用sys.exit(app.exec_()) - Boštjan Mejak
@ Boštjan Mejak.. 感谢您的评论和解释!肯定需要更多的赞!到目前为止,这是我发现的第一个解释我在代码中注意到的这些细微差别的评论。从pyqt4到pyqt5的变化就像重新学习阅读一样(必须承认.. 10年不编程会让人有点生疏.. 而且Python在引擎盖下也弹出了一些有趣的东西)。 - ZF007
5
如果不加入sys.exit(),那么调用app.exit(1)将无法产生相应的退出状态。即使在Python 3和PyQt5中也是如此,应该使用sys.exit(app.exec())。请注意保留原意并尽量通俗易懂。 - jfs
在PyQt5中,他们已经修复了Qt和Python停止进程的顺序,因此现在我们真的不需要再使用sys.exit()调用了。PyQt5文档中详细解释了这一点。 - Boštjan Mejak
3
@BoštjanMejak:错误。这里有一个最小代码示例。顺便说一句,如果你想让我收到你的评论通知,请使用@语法。 - jfs
3个回答

113

这是因为直到Python 3版本之前,exec是一个保留关键字,所以PyQt开发人员在其名称中添加了下划线。从Python 3版本开始,exec 不再是保留关键字(因为它是内置函数,与print相同),因此在PyQt5中提供了一个没有下划线的版本以保持与C++文档一致,但保留带有下划线的版本以保持向后兼容性。因此,在使用Python 3的PyQt5中,这两个exec函数是相同的。对于旧版PyQt,仅exec_()可用。


6
PyQt6дёЌе†Ќж”ЇжЊЃexec_()пјЊзЋ°ењЁеЏЄиѓЅдЅїз”Ёexec()гЂ‚ - Muslimbek Abduganiev

9

关于使用哪种方法的问题:使用exec_意味着如果您决定添加对PyQt4和/或Python >= 2.6的支持,并希望维护单个代码库,则少了一件事需要担心。


1
我想你是指Python <= 2.99,对吗?(或者Python2 >= 2.6)。 - FeRD
@FeRD。不,我的意思是exec_将与任何版本的Python(大于或等于2.6)结合使用pyqt4或pyqt5。早期版本的Python不受pyqt支持。因此,exec_与pyqt4和pyqt5以及任何版本的Python >= 2.6都是向前和向后兼容的(虽然我怀疑Python-3.0.x是否真的可行)。 - ekhumoro

2

但是我应该做什么呢? - eri0o
我已经澄清了我的回答。OP 想知道是否要使用 app.exec() 还是 app.exec_()。由于 app.exec_() 不再受支持,我在新应用程序中只使用 app.exec()。这样做可以使未来的事情更简单。 - eric

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