关键词:Qt 源码 QObject QMetaObject 元对象系统 属性 事件 信号 槽
概述
官方文档第二章内容就是元对象系统,它在介绍里描述到:
Qt的元对象系统提供了信号和槽机制(用于对象间的通信)、运行时类型信息和动态属性系统。
元对象系统基于三个要素:
QObject类为那些可以利用元对象系统的对象提供了一个基类。- 在类声明的私有部分中使用**
Q_OBJECT**宏用于启用元对象特性,比如动态属性、信号和槽。 - 元对象编译器(
moc)为每个QObject子类提供必要的代码来实现元对象特性。
moc工具读取C++源文件,如果发现一个或多个包含Q_OBJECT宏的类声明,它会生成另一个C++源文件,其中包含了这些类的每个元对象的代码。这个生成的源文件被#include进入类的源文件,更常见的是被编译并链接到类的实现中。
引入这个系统的主要原因是信号和槽机制,此外它还提供了一些额外功能:
QObject::metaObject()返回与该类相关联的元对象。QMetaObject::className()在运行时以字符串形式返回类名,而无需通过 C++ 编译器提供本地运行时类型信息(RTTI)支持。QObject::inherits()函数返回一个对象是否是在 QObject 继承树内继承了指定类的实例。QObject::tr()和QObject::trUtf8()用于国际化的字符串翻译。QObject::setProperty()和QObject::property()动态地通过名称设置和获取属性。QMetaObject::newInstance()构造该类的新实例。
上面说到的元对象系统三要素,第3点moc会在后面用单独篇章分析,下面就不再展开,第1点我们在上一篇中做了简单的分析,本篇我们看看第2点——Q_OBJECT到底怎么启用了元对象系统(然而启用非常复杂,我们先浏览个大概,所以标题叫热身)。
staticMetaObject
找到源码中出现QMetaObject的地方:
//qobject.h
class Q_CORE_EXPORT Qobject{
Q_OBJECT
//...
protected:
static const QMetaObject staticQtMetaObject;
//...
}
和QMetaObject相关的变量只有2个地方出现,既然前面说了Q_OBJECT和元对象系统相关,那我们就直接看Q_OBJECT的定义:
//qobjectdefs.h
#define Q_OBJECT \
public: \
QT_WARNING_PUSH \
Q_OBJECT_NO_OVERRIDE_WARNING \
static const QMetaObject staticMetaObject; \
virtual const QMetaObject *metaObject() const; \
virtual void *qt_metacast(const char *); \
virtual int qt_metacall(QMetaObject::Call, int, void **); \
QT_TR_FUNCTIONS \
private: \
Q_OBJECT_NO_ATTRIBUTES_WARNING \
Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
QT_WARNING_POP \
struct QPrivateSignal {}; \
QT_ANNOTATE_CLASS(qt_qobject, "")
我们关注变量static const QMetaObject staticMetaObject,这是一个QMetaObject类型的静态变量,它应该是和元对象系统相关,文档对QMetaObject的描述:
QMetaObject类包含有关Qt对象的元信息。每个在应用程序中使用的QObject子类都会创建一个QMetaObject实例,该实例存储了该QObject子类的所有元信息。此对象可通过Q

本文介绍了Qt中的元对象系统,特别是如何通过Q_OBJECT宏启用元对象特性,重点讲解了staticMetaObject的初始化过程,以及QMetaObject在信号槽机制、运行时类型信息和动态属性系统中的核心作用。
最低0.47元/天 解锁文章
328

被折叠的 条评论
为什么被折叠?



