Qt元对象系统(Meta-Object System)

Qt的元对象系统提供了信号/槽机制用于内部对象通信,运行时信息,以及动态属性系统。
元对象系统基于以下三种特性:
(1)QObject类提供了对象的基类以使用元对象系统。
(2)Q_OBJECT宏包含了用于元对象的类声明的私有成员部分,如动态属性,信号和槽。
(3)元对象编译器(moc)支持每个包含实现元对象特性关系代码的QObject子类。


moc工具读取一个C++源文件。如果它发现了一个或多个类声明包含Q_OBJECT宏,它将生成一个另外的包含用于各个类的元对象代码的C++源文件。生成的这个源代码文件被包含到类的源代码中或被编译链接到类实现中。
为支持信号/槽机制以用于对象通信,元对象代码提供了以下特性:
(1)QObject::metaObject()返回类相关的元对象。
(2)QMetaObject::className()在运行时中以string类型的字符串返回类名称,不要求C++编译器提供本地的运行时信息(RTTI)支持。
(3)QObject::inherits()函数返回夜光对象是否是一个继承自QObject继承树的类的实例。
(4)QObject::tr()和QObject::trUtf8()翻译用于国际化的字符串。
(5)QObject::setProperty()和QObject::property()根据名字动态设置和获取属性。
(6)QMetaObject::newInstance()构造一个类的新示例。


在QObject类中使用qobjectt_cast()也可以实现dynamic casts(动态类型转换)。qobject_cast()函数的实现和标准C++中dynamic_cast()类似,不需要RTTI支持,而且可以跨越动态链接库工作。它试图将参数转换为用尖括号包含的指针类型,若对象类型正确,它将返回一个非零指针,否则返回0。
例如,假定MyWidget类继承自QWidget并在声明中含有Q_OBJECT宏。
    QObject *obj = new MyWidget;
这个QObject类型的obj变量实际是一个MyWidget对象,使用我们这样可以对它进行转换:
    QWidget *widget = qobject_cast<QWidget*>(obj);
因为该对象实际就是一个继承自QWidget的MyWidget类型对象,所以可以成功实现从QObject到QWidget的转换。由于我们已知obj是一个MyWidget对象,所以我们也可以将它转换为MyWidget*类型。
    MyWidget *myWidget = qobject_cast<MyWidget*>(obj);
因为qboject_cast()并不区分Qt内建的类型和自定义类型,所以上述转换为MyWidget可以实现。
    QLabel *lable = qobject_cast<QLabel *>(obj);
转换为QLabel则会失败,该指针将被置为0.这可以基于类型在运行时中处理不同类型的对象。
if(QLabel *label = qobject_cast<QLabel *>(obj)
{
l    abel->setText(tr("ping");
}
else if(QPushButton *button = qobject_cast<QPushButton *>(obj))
{
    button->setText(tr("ping");
}
虽然可以使用QObject作为基类而不使用Q_OBJECT宏和元对象代码,但是如果不使用Q_OBJECT宏,信号和槽或者是其他元对象特性将不可用。从元对象系统的描述可知,一个不包含元代码(meta code)的QObject子类将等价于它最近的包含元对象代码的祖先类。例如,QMetaObject::className()将不会返回类的实际名称,而是返回其祖先类的名称。
强烈建议所有Q_Object的子类都使用Q_OBJECT宏,不管它们是否实际使用了信号,槽和属性。
  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值