問題描述
使用 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)
print False
?
But why does print(QtWidgets.QApplication.instance() is QtWidgets.qApp)
print 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()
一樣工作并最初返回 無
.但是因為它是靜態的,所以它必須始終返回一個正確類型的對象,以便它以后可以引用與 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
最初只是一個 empty 包裝器:
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
的原因是,這兩個對象是圍繞相同底層的不同 python 包裝器C++ 對象.
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()的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!