HTML5   发布时间:2022-04-25  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了QT的元对象系统(Meta-Object System)大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

原文在这里点击打开链接

QT的元对象系统为对象间的通信提供信号槽机制,运行时的类型信息和动态的属性系统。

元对象系统建立在以下三个基础之上:

1、QObject 类作为基类,使其它的对象能够利用元对象系统。

2、类内部私有部分声明的 Q_OBjeCT 宏使对象能够使用元对象特性, 像动态属性和信号槽这些。

3、元对象编译提供了QOject 子对象需要的代码来实现元对象特性。

@H_496_4@moc 工具读入一个C++源文件,如果碰到有类中包含了Q_OBjeCT 宏, 它会产生另外一个C++源文件在这个C++源文件中包含了这些类的元对象代码。这个产生的C++源文件或者是通过#include 包含进原C++源文件中,更加通常的做法是,编译和链接进类的实现中。

除了为对象之间的通信提供信号和槽机制以外,元对象代码提供了以下这些特性:

QObject::metaObject() 返回类相关的元对象。

QMetaObject::className() 在运行时以字符串的形式返回类的名称,而需要使用标准C++编译器的运行时类型信息(RTTI)的支持

QObject::inherits() 这个函数用来返回类对象的类是否是QObject 继承层次树上的一个指定类的派生类。

QObject::setProperty() 和QObject::property()  用来动态获取属性名称和通过属性名称来设置属性

QMetaObject::newInstance()  用来创建一个类的实例。

同样的,可以通过 qobject_cast() 来动态的进行QObject 类型之间的转换。qobject_cast() 函数功能同C++ 标准库中的 dynamic_cast() 函数功能类似。不过其优点是不需要RTTI 的支持,能够跨动态库的边界工作。qobject_cast() 尝试转化它的参数为尖括号中的模板参数的类型,如果指针运行时实际所指对象含有尖括号中的类型的子对象,那么转换成功,返回一个非空指针,否则返回一个空指针 0。

比如,假设@H_745_35@myWidget 类继承自 QWidget,并且在QWidget 中定义有 Q_OBjeCT 宏:

QObject *obj = new MyWidget;

obj 对象是个指针,类型是QObject*,实际指向的是 MyWideget 对象,所以我们可以合适的转换成功。

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

从QObject 指针到 QWidget 指针的转化是成功的,因为实际上 obj 所指的对象是@L_726_6@myWidget 对象,MyWidget 对象内部含有 QWidget 子对象。当然知道obj 指针实际所指的对象是MyWidget ,当然也可以将obj 转换为MyWidget*


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

转换为MyWidget 指针是成功的,因为 qobject_cast() 函数的转换对于 Qt 内置的类型和用户自定义的类型没有差别。

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

上边这个转换就失败了,label 指针被置空,这就使得能够在运行时基于类型,对不同类型的对象进行不同的处理:

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

当然,也可以将QObject 对象作为基类然而不包含Q_OBjeCT 宏和元对象代码,如果Q_OBjeCT 没有被包含,上边描述的运行时类型信息,动态属性系统和信号槽机制都将变得不可用。就元对象系统的观点来看,QObejct 不包含元代码的子对象同该子对象包含元对象代码一个最近的祖先之间是等价的。这就意味着,比如说,QMetaObject::className() 函数返回的字符串名称不是该对象的,而是该对象最相近的一个祖先的。

因此,我们强烈的建议所有继承自QObejct 类的派生类去包含 Q_OBjeCT 宏,尽管派生类可能不会使用信号槽和动态属性系统。


另外自己的说明:

Qt功过动态属性系统来实现自省功能,是基于元对象系统实现的。所谓Qt中,所谓的属性实际上就是成员变量,是类的数据成员,只不作为属性,可以被类的元对象访问。QObject的子对象中的属性用Q_property() 宏来定义。

下边的代码用来打印一个类的所有属性

const QMetaObject *Metaobject = this->MetaObject();
    int count = Metaobject->propertyCount();
    for (int i=0; i<count; ++i) {
        QMetaProperty Metaproperty = Metaobject->property(i);
        qDebug() << Metaproperty.name();

属性的读写可以通过QObject :: property() 和 QObject :: setproperty() 进行,此时除了属性名称,并不需要类的其他信息。

大佬总结

以上是大佬教程为你收集整理的QT的元对象系统(Meta-Object System)全部内容,希望文章能够帮你解决QT的元对象系统(Meta-Object System)所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。