PyQt5では、これらの両方がアプリケーションオブジェクトを返します。
_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
_の違いは、後者は静的モジュール変数であり、モジュールを最初にインポートするときに作成する必要があることです。これにより、最初は不可解な動作が発生します。
_>>> 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++オブジェクトを参照できるようになります。
ただし、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
を返す理由は、2つのオブジェクトが異なるpython同じ基になるC++オブジェクトのラッパーであるためです。
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
_