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:

  1. Die Klasse QObject bietet eine Basisklasse für Objekte, die das Meta-Objektsystem nutzen können.
  2. Das Q_OBJECT Makro wird verwendet, um Meta-Objekt-Funktionen, wie dynamische Eigenschaften, Signale und Slots, zu aktivieren.
  3. 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:

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:

    QWidget *widget = qobject_cast<QWidget *>(obj);

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.

    QLabel *label = qobject_cast<QLabel *>(obj);
    // label is 0

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.