Objektbäume & Besitzverhältnisse
Übersicht
QObjects organisieren sich selbst in Objektbäumen. Wenn Sie ein QObject mit einem anderen Objekt als Elternteil erstellen, wird es der children()-Liste des Elternteils hinzugefügt und gelöscht, wenn das Elternteil gelöscht wird. Es hat sich herausgestellt, dass dieser Ansatz sehr gut zu den Bedürfnissen von GUI-Objekten passt. Zum Beispiel ist ein QShortcut (Tastaturkürzel) ein Kind des entsprechenden Fensters, und wenn der Benutzer das Fenster schließt, wird auch das Kürzel gelöscht.
QQuickItemDas visuelle Basiselement des Moduls Qt Quick erbt von QObject, hat aber ein anderes Konzept des visuellen Elternteils als das des ElternteilsQObject . Der visuelle Parent eines Elements muss nicht unbedingt derselbe sein wie sein Object Parent. Siehe Konzepte - Visual Parent in Qt Quick für weitere Details.
QWidgetDie Klasse Child, die grundlegende Klasse des Moduls Qt Widgets, erweitert die Eltern-Kind-Beziehung. Ein untergeordnetes Objekt wird normalerweise auch zu einem untergeordneten Widget, d. h. es wird im Koordinatensystem des übergeordneten Objekts angezeigt und grafisch durch die Grenzen des übergeordneten Objekts beschnitten. Wenn die Anwendung beispielsweise ein Nachrichtenfeld löscht, nachdem es geschlossen wurde, werden auch die Schaltflächen und die Beschriftung des Nachrichtenfeldes gelöscht, genau wie wir es wollen, da die Schaltflächen und die Beschriftung Kinder des Nachrichtenfeldes sind.
Sie können auch selbst untergeordnete Objekte löschen, die sich dann von ihren übergeordneten Objekten lösen. Wenn der Benutzer z. B. eine Symbolleiste entfernt, kann dies dazu führen, dass die Anwendung eines ihrer QToolBar Objekte löscht. In diesem Fall würde das übergeordnete Objekt der Symbolleiste QMainWindow die Änderung erkennen und den Bildschirmbereich entsprechend neu konfigurieren.
Die Debugging-Funktionen QObject::dumpObjectTree() und QObject::dumpObjectInfo() sind oft nützlich, wenn eine Anwendung seltsam aussieht oder sich seltsam verhält.
Aufbau-/Zerstörungsreihenfolge von QObjects
Wenn QObjects auf dem Heap erstellt wird (d.h. mit new), kann ein Baum aus ihnen in beliebiger Reihenfolge aufgebaut werden, und später können die Objekte im Baum in beliebiger Reihenfolge zerstört werden. Wenn ein beliebiges QObject im Baum gelöscht wird, entfernt der Destruktor automatisch das Objekt von seinem Elternteil, wenn das Objekt einen Elternteil hat. Wenn das Objekt Kinder hat, löscht der Destruktor automatisch jedes Kind. Kein QObject wird zweimal gelöscht, unabhängig von der Reihenfolge der Zerstörung.
Wenn QObjects auf dem Stapel erstellt wird, gilt das gleiche Verhalten. Normalerweise stellt die Reihenfolge der Zerstörung noch kein Problem dar. Betrachten Sie den folgenden Ausschnitt:
int main() { QWidget window; QPushButton quit("Quit", &window); ... }
Das Elternteil window
und das Kind quit
sind beide QObjects, weil QPushButton von QWidget und QWidget von QObject erbt. Dieser Code ist korrekt: Der Destruktor von quit
wird nicht zweimal aufgerufen, weil der C++-Sprachstandard (ISO/IEC 14882:2003) festlegt, dass Destruktoren lokaler Objekte in umgekehrter Reihenfolge ihrer Konstruktoren aufgerufen werden. Daher wird der Destruktor des untergeordneten Objekts quit
zuerst aufgerufen, und es entfernt sich selbst von seinem übergeordneten Objekt window
, bevor der Destruktor von window
aufgerufen wird.
Aber was passiert, wenn wir die Reihenfolge der Konstruktion vertauschen, wie in diesem zweiten Schnipsel gezeigt wird?
int main() { QPushButton quit("Quit"); QWidget window; quit.setParent(&window); ... }
In diesem Fall verursacht die Reihenfolge der Zerstörung ein Problem. Der Destruktor des Elternteils wird zuerst aufgerufen, weil er zuletzt erstellt wurde. Danach wird der Destruktor des untergeordneten Elements quit
aufgerufen, was nicht korrekt ist, da quit
eine lokale Variable ist. Wenn quit
anschließend den Gültigkeitsbereich verlässt, wird sein Destruktor erneut aufgerufen, dieses Mal korrekt, aber der Schaden ist bereits angerichtet worden.
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.