当前位置:嗨网首页>书籍在线阅读

04-元对象系统

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

3.1.2 元对象系统

Qt的元对象系统(Meta-Object System)提供了对象之间通信的信号与槽机制、运行时类型信息和动态属性系统。

元对象系统由以下三个基础组成。

  • QObject类是所有使用元对象系统的类的基类。
  • 在一个类的private部分声明Q_OBJECT宏,使得类可以使用元对象的特性,如动态属性、信号与槽。
  • MOC(元对象编译器)为每个QObject的子类提供必要的代码来实现元对象系统的特性。

构建项目时,MOC工具读取C++源文件,当它发现类的定义里有Q_OBJECT宏时,它就会为这个类生成另外一个包含有元对象支持代码的C++源文件,这个生成的源文件连同类的实现文件一起被编译和连接。

除了信号与槽机制外,元对象还提供如下一些功能。

  • QObject::metaObject()函数返回类关联的元对象,元对象类QMetaObject包含了访问元对象的一些接口函数,例如QMetaObject::className()函数可在运行时返回类的名称字符串。
QObject *obj = new QPushButton;
obj->metaObject()->className();    // 返回 "QPushButton"
  • QMetaObject::newInstance()函数创建类的一个新的实例。
  • QObject::inherits(const char *className)函数判断一个对象实例是否是名称为className的类或QObject的子类的实例。例如:
QTimer *timer = new QTimer;        // QTimer 是QObject的子类
timer->inherits("QTimer");         // 返回 true
timer->inherits("QObject");        // 返回 true
timer->inherits("QAbstractButton");//返回 false,不是QAbstractButton的子类
  • QObject::tr()和QObject::trUtf8()函数可翻译字符串,用于多语言界面设计,在第16章会专门介绍多语言界面设计。
  • QObject::setProperty()和QObject::property()函数用于通过属性名称动态设置和获取属性值。

对于QObject及其子类,还可以使用qobject_cast()函数进行动态投射(dynamic cast)。例如,假设QMyWidget是QWidget的子类并且在类定义中声明了Q_OBJECT宏。创建实例使用下面的语句:

QObject *obj = new QMyWidget;

变量obj定义为QObject指针,但它实际指向QMyWidget类,所以可以正确投射为QWidget,即:

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

从QObject到QWidget的投射是成功的,因为obj实际是QMyWidget类,是QWidget的子类。也可以将其成功投射为QMyWidget,即:

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

投射为QMyWidget是成功的,因为qobject_cast()并不区分Qt内建的类型和用户自定义类型。

但是,若要将obj投射为QLabel则是失败的,即:

QLabel *label = qobject_cast<QLabel *>(obj);

这样投射是失败的,返回指针label为NULL,因为QMyWidget不是QLabel的子类。

使用动态投射,使得程序可以在运行时对不同的对象做不同的处理。