Das Meta-Objekt-System
Das Meta-Objektsystem von Qt bietet den Signal- und Slot-Mechanismus für die Kommunikation zwischen Objekten, Laufzeit-Typinformationen und das dynamische Eigenschaftssystem.
Das Meta-Objektsystem basiert auf drei Dingen:
- Die Klasse QObject bietet eine Basisklasse für Objekte, die das Meta-Objektsystem nutzen können.
- Das Q_OBJECT Makro wird verwendet, um Meta-Objekt-Funktionen, wie dynamische Eigenschaften, Signale und Slots, zu aktivieren.
- Das Meta-Object Compiler (
moc
) versorgt jede QObject Unterklasse mit dem notwendigen Code, um Meta-Objekt-Funktionen zu implementieren.
Das Werkzeug moc
liest eine C++-Quelldatei. Wenn es eine oder mehrere Klassendeklarationen findet, die das Makro Q_OBJECT enthalten, erzeugt es eine weitere C++-Quelldatei, die den Meta-Objekt-Code für jede dieser Klassen enthält. Diese erzeugte Quelldatei wird entweder #include
'd in die Quelldatei der Klasse eingefügt oder, was üblicherweise der Fall ist, kompiliert und mit der Implementierung der Klasse verknüpft.
Neben der Bereitstellung der Signale und des Slot-Mechanismus für die Kommunikation zwischen Objekten (der Hauptgrund für die Einführung des Systems) bietet der Meta-Objekt-Code die folgenden zusätzlichen Funktionen:
- QObject::metaObject() gibt die zugehörige meta-object für die Klasse zurück.
- QMetaObject::className() gibt zur Laufzeit den Klassennamen als String zurück, ohne dass der C++-Compiler native Run-Time Type Information (RTTI) unterstützen muss.
- QObject::inheritsDie Funktion () gibt zurück, ob ein Objekt eine Instanz einer Klasse ist, die eine bestimmte Klasse innerhalb des QObject Vererbungsbaums erbt.
- QObject::tr() übersetzt Zeichenketten für die Internationalisierung.
- QObject::setProperty() und QObject::property() setzen und erhalten dynamisch Eigenschaften nach Namen.
- QMetaObject::newInstance() konstruiert eine neue Instanz der Klasse.
Es ist auch möglich, dynamische Casts mit qobject_cast() auf QObject Klassen durchzuführen. Die Funktion qobject_cast() verhält sich ähnlich wie die Standard-C++-Funktion dynamic_cast()
, mit dem Vorteil, dass sie keine RTTI-Unterstützung benötigt und über dynamische Bibliotheksgrenzen hinweg funktioniert. Sie versucht, ihr Argument auf den in spitzen Klammern angegebenen Zeigertyp zu übertragen und gibt einen Zeiger ungleich Null zurück, wenn das Objekt vom richtigen Typ ist (zur Laufzeit ermittelt), oder nullptr
, wenn der Typ des Objekts nicht kompatibel ist.
Nehmen wir zum Beispiel an, MyWidget
erbt von QWidget und wird mit dem Makro Q_OBJECT deklariert:
QObject *obj = new MyWidget;
Die Variable obj
vom Typ QObject *
bezieht sich in Wirklichkeit auf ein Objekt MyWidget
, so dass wir sie entsprechend umwandeln können:
Der Cast von QObject nach QWidget ist erfolgreich, da es sich bei dem Objekt um ein MyWidget
handelt, das eine Unterklasse von QWidget ist. Da wir wissen, dass obj
ein MyWidget
ist, können wir es auch nach MyWidget *
casten:
MyWidget *myWidget = qobject_cast<MyWidget *>(obj);
Der Cast nach MyWidget
ist erfolgreich, weil qobject_cast() keinen Unterschied zwischen eingebauten Qt-Typen und benutzerdefinierten Typen macht.
Der Cast nach QLabel schlägt dagegen fehl. Der Zeiger wird dann auf 0 gesetzt. Dies ermöglicht es, Objekte verschiedener Typen zur Laufzeit je nach Typ unterschiedlich zu behandeln:
if (QLabel *label = qobject_cast<QLabel *>(obj)) { label->setText(tr("Ping")); } else if (QPushButton *button = qobject_cast<QPushButton *>(obj)) { button->setText(tr("Pong!")); }
Es ist zwar möglich, QObject als Basisklasse ohne das Makro Q_OBJECT und ohne Meta-Objekt-Code zu verwenden, aber weder Signale und Slots noch die anderen hier beschriebenen Funktionen sind verfügbar, wenn das Makro Q_OBJECT nicht verwendet wird. Aus der Sicht des Meta-Objekt-Systems ist eine QObject Unterklasse ohne Meta-Code äquivalent zu ihrem engsten Vorfahren mit Meta-Objekt-Code. Das bedeutet zum Beispiel, dass QMetaObject::className() nicht den tatsächlichen Namen Ihrer Klasse zurückgibt, sondern den Klassennamen dieses Vorgängers.
Daher empfehlen wir dringend, dass alle Unterklassen von QObject das Makro Q_OBJECT verwenden, unabhängig davon, ob sie tatsächlich Signale, Slots und Eigenschaften verwenden oder nicht.
Siehe auch QMetaObject, Qt's Property System, und Signale und Slots.
© 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.