QtGui.QApplication 和 QtCore.QCoreApplication 之间的区别
Difference between QtGui.QApplication and QtCore.QCoreApplication
大家知道的QtGui是用来给GUI程序创建界面的,而QtCore是给非GUI程序用的,实际工作在界面下。但是要获取 运行 应用程序的实例,我发现我们可以使用 QtCore 和 QtGui 来 return 使用 QtCore.QCoreApplication
和 QtGui.QApplication
当前的 运行 实例.
那么实例 returned 使用它们有什么区别呢?
他们指的是同一件事吗?
没有区别,因为QApplication
中的instance()
方法继承自QCoreApplication
。您还可以通过以下方式证明这一点:
>>> from PyQt4.QtCore import QCoreApplication
>>> from PyQt4.QtGui import QApplication
>>> a = QApplication([])
>>> a
<PyQt4.QtGui.QApplication object at 0x02A75620>
>>> QApplication.instance()
<PyQt4.QtGui.QApplication object at 0x02A75620>
>>> QCoreApplication.instance()
<PyQt4.QtGui.QApplication object at 0x02A75620>
>>> b = QCoreApplication([])
>>> b
<PyQt4.QtCore.QCoreApplication object at 0x02A75670>
>>> QCoreApplication.instance()
<PyQt4.QtCore.QCoreApplication object at 0x02A75670>
>>> QApplication.instance()
<PyQt4.QtCore.QCoreApplication object at 0x02A75670>
请注意,无论您使用哪个 class 访问实例,PyQt 都会正确地对对象进行类型转换。在 C++ 中,您需要自己进行这种类型转换。
您可以使用 shiboken
模块来检查到底发生了什么:
>>> import shiboken
>>> from PySide import QtCore, QtGui
>>> app = QtGui.QApplication([])
>>> app
<PySide.QtGui.QApplication object at 0x7fc6031c98c8>
>>> print(shiboken.dump(app))
C++ address....... PySide.QtGui.QApplication/0x11446c0
hasOwnership...... 0
containsCppWrapper 1
validCppObject.... 1
wasCreatedByPython 1
>>> print(shiboken.dump(QtGui.QApplication.instance()))
C++ address....... PySide.QtGui.QApplication/0x11446c0
hasOwnership...... 0
containsCppWrapper 1
validCppObject.... 1
wasCreatedByPython 1
>>> print(shiboken.dump(QtCore.QCoreApplication.instance()))
C++ address....... PySide.QtGui.QApplication/0x11446c0
hasOwnership...... 0
containsCppWrapper 1
validCppObject.... 1
wasCreatedByPython 1
>>> print(shiboken.dump(QtGui.qApp))
C++ address....... PySide.QtGui.QApplication/0x11446c0
hasOwnership...... 0
containsCppWrapper 1
validCppObject.... 1
wasCreatedByPython 1
如您所见,每次都引用相同的底层 C++ 对象。如果您创建了一个 QCoreApplication
,那么每次也会引用相同的 QCoreApplication
。
这里的意图是永远应该只有 一个 应用程序对象。但是 Qt 类 并不是真正的单例。因此,如果您尝试创建另一个实例,PySide 会选择引发错误:
>>> app2 = QtGui.QApplication([])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: A QApplication instance already exists.
不过,在 PyQt 中,没有什么可以阻止您创建多个实例,在 C++ 中也必须如此。大概在某处记录了这通常会导致未定义的行为。
将 sip.dump
与 PyQt 结合使用显示了一些其他重要差异:
# NB: abbreviated output
>>> import sip
>>> from PyQt4 import QtCore, QtGui
>>> app = QtGui.QApplication([])
>>> sip.dump(app)
<PyQt4.QtGui.QApplication object at 0x7fc801a91678>
Reference count: 3
Address of wrapped object: 0x25190e0
Created by: Python
To be destroyed by: Python
>>> sip.dump(QtCore.QCoreApplication.instance())
<PyQt4.QtGui.QApplication object at 0x7fc801a91678>
Reference count: 3
Address of wrapped object: 0x25190e0
Created by: Python
To be destroyed by: Python
>>> sip.dump(QtGui.QApplication.instance())
<PyQt4.QtGui.QApplication object at 0x7fc801a91678>
Reference count: 3
Address of wrapped object: 0x25190e0
Created by: Python
To be destroyed by: Python
>>> sip.dump(QtGui.qApp)
<PyQt4.QtGui.QApplication object at 0x7fc801a91558>
Reference count: 3
Address of wrapped object: 0x25190e0
Created by: C/C++
To be destroyed by: C/C++
请注意,与 PySide 不同,qApp
实例是由 C++ 创建的,而不是 Python,并且 PyQt 包装器不一样。如果您决定创建自己的 QApplication
子类,请务必记住这一点,因为 qApp
会忽略它!如果想让qApp
引用自己的子类,需要显式设置,像这样:
myapp = MyCustomApplication(sys.argv)
QtGui.qApp = myapp
在 PySide 中,不需要这个小 hack。
大家知道的QtGui是用来给GUI程序创建界面的,而QtCore是给非GUI程序用的,实际工作在界面下。但是要获取 运行 应用程序的实例,我发现我们可以使用 QtCore 和 QtGui 来 return 使用 QtCore.QCoreApplication
和 QtGui.QApplication
当前的 运行 实例.
那么实例 returned 使用它们有什么区别呢? 他们指的是同一件事吗?
没有区别,因为QApplication
中的instance()
方法继承自QCoreApplication
。您还可以通过以下方式证明这一点:
>>> from PyQt4.QtCore import QCoreApplication
>>> from PyQt4.QtGui import QApplication
>>> a = QApplication([])
>>> a
<PyQt4.QtGui.QApplication object at 0x02A75620>
>>> QApplication.instance()
<PyQt4.QtGui.QApplication object at 0x02A75620>
>>> QCoreApplication.instance()
<PyQt4.QtGui.QApplication object at 0x02A75620>
>>> b = QCoreApplication([])
>>> b
<PyQt4.QtCore.QCoreApplication object at 0x02A75670>
>>> QCoreApplication.instance()
<PyQt4.QtCore.QCoreApplication object at 0x02A75670>
>>> QApplication.instance()
<PyQt4.QtCore.QCoreApplication object at 0x02A75670>
请注意,无论您使用哪个 class 访问实例,PyQt 都会正确地对对象进行类型转换。在 C++ 中,您需要自己进行这种类型转换。
您可以使用 shiboken
模块来检查到底发生了什么:
>>> import shiboken
>>> from PySide import QtCore, QtGui
>>> app = QtGui.QApplication([])
>>> app
<PySide.QtGui.QApplication object at 0x7fc6031c98c8>
>>> print(shiboken.dump(app))
C++ address....... PySide.QtGui.QApplication/0x11446c0
hasOwnership...... 0
containsCppWrapper 1
validCppObject.... 1
wasCreatedByPython 1
>>> print(shiboken.dump(QtGui.QApplication.instance()))
C++ address....... PySide.QtGui.QApplication/0x11446c0
hasOwnership...... 0
containsCppWrapper 1
validCppObject.... 1
wasCreatedByPython 1
>>> print(shiboken.dump(QtCore.QCoreApplication.instance()))
C++ address....... PySide.QtGui.QApplication/0x11446c0
hasOwnership...... 0
containsCppWrapper 1
validCppObject.... 1
wasCreatedByPython 1
>>> print(shiboken.dump(QtGui.qApp))
C++ address....... PySide.QtGui.QApplication/0x11446c0
hasOwnership...... 0
containsCppWrapper 1
validCppObject.... 1
wasCreatedByPython 1
如您所见,每次都引用相同的底层 C++ 对象。如果您创建了一个 QCoreApplication
,那么每次也会引用相同的 QCoreApplication
。
这里的意图是永远应该只有 一个 应用程序对象。但是 Qt 类 并不是真正的单例。因此,如果您尝试创建另一个实例,PySide 会选择引发错误:
>>> app2 = QtGui.QApplication([])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: A QApplication instance already exists.
不过,在 PyQt 中,没有什么可以阻止您创建多个实例,在 C++ 中也必须如此。大概在某处记录了这通常会导致未定义的行为。
将 sip.dump
与 PyQt 结合使用显示了一些其他重要差异:
# NB: abbreviated output
>>> import sip
>>> from PyQt4 import QtCore, QtGui
>>> app = QtGui.QApplication([])
>>> sip.dump(app)
<PyQt4.QtGui.QApplication object at 0x7fc801a91678>
Reference count: 3
Address of wrapped object: 0x25190e0
Created by: Python
To be destroyed by: Python
>>> sip.dump(QtCore.QCoreApplication.instance())
<PyQt4.QtGui.QApplication object at 0x7fc801a91678>
Reference count: 3
Address of wrapped object: 0x25190e0
Created by: Python
To be destroyed by: Python
>>> sip.dump(QtGui.QApplication.instance())
<PyQt4.QtGui.QApplication object at 0x7fc801a91678>
Reference count: 3
Address of wrapped object: 0x25190e0
Created by: Python
To be destroyed by: Python
>>> sip.dump(QtGui.qApp)
<PyQt4.QtGui.QApplication object at 0x7fc801a91558>
Reference count: 3
Address of wrapped object: 0x25190e0
Created by: C/C++
To be destroyed by: C/C++
请注意,与 PySide 不同,qApp
实例是由 C++ 创建的,而不是 Python,并且 PyQt 包装器不一样。如果您决定创建自己的 QApplication
子类,请务必记住这一点,因为 qApp
会忽略它!如果想让qApp
引用自己的子类,需要显式设置,像这样:
myapp = MyCustomApplication(sys.argv)
QtGui.qApp = myapp
在 PySide 中,不需要这个小 hack。