Sie können das shiboken
Modul überprüfen, was wirklich geschieht:
>>> 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
Wie Sie sehen können, das gleiche zugrunde liegende C++ Objekt wird jedes Mal verwiesen wird. Und wenn Sie eine QCoreApplication
erstellt haben, würde die gleiche QCoreApplication
jedes Mal auch referenziert werden.
Die Absicht hier ist, dass es immer nur ein Anwendungsobjekt geben sollte. Aber die Qt-Klassen sind keine echten Singletons. Als Folge hiervon wählt pyside einen Fehler zu erhöhen, wenn Sie versuchen, eine andere Instanz zu erstellen:
>>> app2 = QtGui.QApplication([])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: A QApplication instance already exists.
In PyQt, obwohl es nichts, was Sie Erstellen mehrere Instanzen zu stoppen, und das gleiche gilt in C wahr sein ++ . Vermutlich ist irgendwo dokumentiert, dass dies normalerweise zu undefiniertem Verhalten führt.
Mit sip.dump
mit PyQt zeigt einige andere wichtige Unterschiede:
# 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++
Beachten Sie, dass im Gegensatz zu pyside, die qApp
Instanz von C++ erstellt wird, anstatt Python und der PyQt Wrapper ist nicht das gleiche. Dies ist ein wichtiger Punkt, an den Sie sich erinnern sollten, wenn Sie sich jemals dazu entschließen, eine eigene Unterklasse von QApplication
zu erstellen, weil qApp
sie einfach ignoriert! Wenn Sie qApp
wollen eine eigene Unterklasse verweisen, müssen Sie explizit festlegen, wie folgt aus:
myapp = MyCustomApplication(sys.argv)
QtGui.qApp = myapp
In pyside, dieser kleine Hack ist nicht erforderlich.
Die Methode 'instance()' existiert in beiden Klassen, weil QApplication sie von QCoreApplication erbt. In beiden Fällen rufen Sie dieselbe Methode auf, die das zurückgibt, wofür Sie Ihre Anwendung instanziiert haben. Natürlich müssen Sie in C++ den Rückgabewert eingeben ... – user3419537
@ user3419537 Sie haben Recht. Ich nahm an, dass sie es überschreiben würden, um den richtigen Typ für die Klasse zurückzugeben, von der Sie es aufgerufen haben, aber ich denke, dass es keinen Sinn hat (vorausgesetzt, Sie können das sogar in C++ tun?) –
Danke .. einfach und erklärend –