qApp与QApplication.instance() [英] qApp versus QApplication.instance()

查看:1060
本文介绍了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)打印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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆