使用 PyQt5,这两个都返回应用程序对象:
app = QtWidgets.QApplication.instance()
app = QtWidgets.qApp
for i in app.arguments()[1:]:
...
但是为什么要print(QtWidgets.QApplication.instance() is QtWidgets.qApp)
打印False
?
使用 PyQt5,这两个都返回应用程序对象:
app = QtWidgets.QApplication.instance()
app = QtWidgets.qApp
for i in app.arguments()[1:]:
...
但是为什么要print(QtWidgets.QApplication.instance() is QtWidgets.qApp)
打印False
?
QtWidgets.QApplication.instance()
和的区别在于QtWidgets.qApp
后者是一个静态模块变量,必须在首次导入模块时创建。这导致以下最初令人困惑的行为:
>>> from PyQt5 import QtWidgets
>>> inst = QtWidgets.QApplication.instance()
>>> qapp = QtWidgets.qApp
>>> (inst, qapp)
(None, <PyQt5.QtWidgets.QApplication object at 0x7ff3c8bd3948>)
所以即使QApplication
还没有创建对象,qApp
变量仍然指向一个QApplication
实例。如果模块更像类,以便它们可以具有动态属性,则可以qApp
完全像 do 一样工作QApplication.instance()
并最初 return None
。但是因为它是静态的,所以它必须总是返回一个正确类型的对象,以便它以后可以引用相同的底层 C++ 对象作为QApplication.instance()
.
但是,重要的是要注意qApp
最初只是一个空包装器:
>>> qapp.objectName()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: wrapped C/C++ object of type QApplication has been deleted
但是,一旦QApplication
创建,它们都将指向同一事物:
>>> app = QtWidgets.QApplication([])
>>> app.setObjectName('foo')
>>> qapp.objectName()
'foo'
所以(QtWidgets.QApplication.instance() is QtWidgets.qApp)
返回的原因False
是这两个对象是围绕同一个底层 C++ 对象的不同 python 包装器。
如果您需要创建自己的子类QApplication
,但仍想使用 ,请务必注意这一点qApp
:
>>> from PyQt5 import QtWidgets
>>> class MyApp(QtWidgets.QApplication):
... def hello(self): print('Hello World')
...
>>> myapp = MyApp([])
>>> myapp.hello()
Hello World
>>>
>>> QtWidgets.qApp
<PyQt5.QtWidgets.QApplication object at 0x7f5e42f40948>
>>> QtWidgets.qApp.hello()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'QApplication' object has no attribute 'hello'
>>>
>>> inst = QtWidgets.QApplication.instance()
>>> inst
<__main__.MyApp object at 0x7f5e42f409d8>
>>> inst.hello()
Hello World
解决这个问题的唯一方法是显式覆盖qApp
模块变量(并且显然确保在其他模块可以导入之前完成此操作):
>>> QtWidgets.qApp = myapp
>>> QtWidgets.qApp.hello()
Hello World