qApp versus QApplication.instance()(qApp 与 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) 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()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:qApp 与 QApplication.instance()
基础教程推荐
- Discord.py 缺少必需的参数 2022-01-01
- 在 Celery 工作人员中捕获 Heroku SIGTERM 以优雅地关 2022-01-01
- 用 Python 编写 Fortran 无格式文件 2022-01-01
- 将 x 轴刻度更改为自定义字符串 2022-01-01
- 由Python将MP3转换为MIDI(类型错误:无法加载插件:mtg-Melodia:Melodia) 2022-01-01
- 使用生成器和迭代器时 Python 多循环失败 2022-01-01
- pyserial - 可以从线程 a 写入串行端口,是否阻塞从线程 b 读取? 2022-01-01
- 与常规 dict 相比,Python manager.dict() 非常慢 2022-01-01
- numpy float:比算术运算中内置的慢 10 倍? 2022-01-01
- 尝试制作WhatsApp机器人 2022-01-01
