Разница между 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
будет работать точно так же, как QApplication.instance()
и первоначально возвращает 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
, заключается в том, что два объекта - разные оболочки python вокруг одного и того же базового объекта C++.
Это важно знать об этой точке, если вы когда-нибудь понадобится, чтобы создать свой собственный sublass из 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