2016-04-11 29 views
1

Was über QtGui bekannt ist, ist, dass es für GUI-Programme verwendet wird, um Schnittstellen zu erstellen, und QtCore ist für Nicht-GUI-Programme und tatsächlich arbeitet unter der Schnittstelle. Aber um die Instanz der laufenden Anwendung zu erhalten, habe ich festgestellt, dass wir QtCore und QtGui verwenden können, um die aktuell laufende Instanz mit QtCore.QCoreApplication und QtGui.QApplication zurückzugeben.Unterschied zwischen QtGui.QApplication und QtCore.QCoreApplication

Was ist der Unterschied zwischen der Instanz, die mit ihnen zurückgegeben wird? Beziehen sie sich auf dasselbe?

Antwort

1

Es gibt keinen Unterschied, da die instance() Methode in QApplication von QCoreApplication vererbt wird. Sie können dies auch zeigen, wie folgt:

>>> 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> 

Beachten Sie, dass PyQt richtig das Objekt ist typecasting unabhängig davon, welche Klasse Sie die Instanz zugreifen. In C++ müssten Sie diese Typumwandlung selbst vornehmen.

+0

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

+0

@ 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?) –

+0

Danke .. einfach und erklärend –

2

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.