元对象系统

Qt 的元对象系统提供了用于对象间通信的信号与槽机制、运行时类型信息以及动态属性系统。

元对象系统基于以下三个方面:

  1. QObject 类为能够利用元对象系统的对象提供了一个基类。
  2. Q_OBJECT 宏用于启用元对象功能,例如动态属性、信号和槽。
  3. Meta-Object Compiler (moc) 为每个 `QObject ` 子类提供了实现元对象功能所需的代码。

moc 工具会读取一个C++源文件。如果发现一个或多个包含Q_OBJECT 宏的类声明,它会生成另一个C++源文件,其中包含这些类各自的元对象代码。该生成的源文件要么通过#include 命令被包含到类的源文件中,要么(更常见的情况)被编译并链接到类的实现中。

除了为对象之间的通信提供信号和槽机制(引入该系统的主要原因)外,元对象代码还提供了以下附加功能:

还可以使用qobject_cast() 对QObject 类进行动态类型转换。qobject_cast() 函数的行为与标准 C++ 的dynamic_cast() 类似,其优点是无需 RTTI 支持,并且可以在动态库边界之间工作。 该函数尝试将参数强制转换为尖括号中指定的指针类型,若对象类型正确(在运行时确定),则返回非零指针;若对象类型不兼容,则返回nullptr 。

例如,假设MyWidget 继承自QWidget ,并使用Q_OBJECT 宏进行声明:

    QObject *obj = new MyWidget;

类型为QObject * 的obj 变量实际上指向一个MyWidget 对象,因此我们可以对其进行适当的强制转换:

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

将QObject 强制转换为QWidget 是成功的,因为该对象实际上是一个MyWidget ,它是QWidget 的子类。由于我们知道obj 是一个MyWidget ,因此也可以将其强制转换为MyWidget * :

    MyWidget *myWidget = qobject_cast<MyWidget *>(obj);

将该对象强制转换为MyWidget 是成功的,因为qobject_cast() 不会区分Qt内置类型和自定义类型。

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

另一方面,QLabel 的类型转换会失败。此时,指针会被设置为nullptr 。这使得系统能够根据类型,在运行时对不同类型的对象进行差异化处理:

    if (QLabel *label = qobject_cast<QLabel *>(obj)) {
        label->setText(tr("Ping"));
    } else if (QPushButton *button = qobject_cast<QPushButton *>(obj)) {
        button->setText(tr("Pong!"));
    }

虽然可以在不使用Q_OBJECT 宏且没有元对象代码的情况下将QObject 用作基类,但如果未使用Q_OBJECT 宏,则既无法使用信号与槽,也无法使用本文中描述的其他功能。 从元对象系统的角度来看,一个没有元代码的QObject 子类等同于其具有元对象代码的最近祖先。这意味着,例如,QMetaObject::className() 不会返回您类的实际名称,而是返回该祖先的类名。

因此,我们强烈建议所有QObject 的子类都使用Q_OBJECT 宏,无论它们是否实际使用信号、槽和属性。

另请参阅 QMetaObject 、Qt 的属性系统以及信号与槽。

© 2026 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.