qApp与QApplication.instance() [英] qApp versus QApplication.instance()
问题描述
使用PyQt5,这两个都返回应用程序对象:
With PyQt5, both of these return the application object:
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
之间的区别在于,后者是静态模块变量,必须在模块创建时创建首先导入.这将导致以下最初令人困惑的行为:
The difference between QtWidgets.QApplication.instance()
and QtWidgets.qApp
is that the latter is a static module variable that must be created when the module is first imported. This results in the following initially baffling behaviour:
>>> from PyQt5 import QtWidgets
>>> inst = QtWidgets.QApplication.instance()
>>> qapp = QtWidgets.qApp
>>> (inst, qapp)
(None, <PyQt5.QtWidgets.QApplication object at 0x7ff3c8bd3948>)
因此,即使尚未创建QApplication
对象,qApp
变量仍指向QApplication
实例.如果模块更像类,因此它们可以具有动态属性,则qApp
可能完全像QApplication.instance()
一样工作,并最初返回None
.但是,由于它是静态的,因此必须始终返回正确类型的对象,以便以后可以引用与QApplication.instance()
相同的基础C ++对象.
So even though no QApplication
object has been created yet, the qApp
variable still points to a QApplication
instance. If modules were more like classes, so that they could have dynamic properties, it would be possible for qApp
to work exactly like QApplication.instance()
does and initially return None
. But because it is static, it must always return an object of the correct type, so that it can later refer to the same underlying C++ object as QApplication.instance()
.
但是,请务必注意,qApp
最初只是一个空包装器:
However, it's important to note that qApp
is initially just an empty wrapper:
>>> 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
后,它们都将指向同一事物:
Once the QApplication
is created, though, they will both point to the same thing:
>>> app = QtWidgets.QApplication([])
>>> app.setObjectName('foo')
>>> qapp.objectName()
'foo'
(QtWidgets.QApplication.instance() is QtWidgets.qApp)
返回False
的原因是,两个对象是围绕同一基础C ++对象的不同python包装器.
So the reason why (QtWidgets.QApplication.instance() is QtWidgets.qApp)
returns False
, is that the two objects are different python wrappers around the same underlying C++ object.
如果您需要创建自己的QApplication
子集,但仍然想使用qApp
:
It's important to be aware of this point if you ever need to create your own sublass of QApplication
, but still want to use 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
模块变量(并显然确保在其他模块可以导入之前完成此操作):
The only way around this is to explicitly overwrite the qApp
module variable (and obviously ensure that this is done before it can be imported by other modules):
>>> QtWidgets.qApp = myapp
>>> QtWidgets.qApp.hello()
Hello World
这篇关于qApp与QApplication.instance()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!