Qt学习及使用_第3部分_Qt框架功能概述---QMetaObject类&运行时类型信息&属性系统

前言
        


        学以致用,通过QT框架的学习,一边实践,一边探索编程的方方面面.

        参考书:<Qt 6 C++开发指南>(以下称"本书"),继承关系沿用本书说法:父类/子类,而非传统C++使用基类/派生类

        标识说明:概念用粗体+倾斜.重点内容用(加粗黑体)---重点内容(红字)---重点内容(加粗红字),

                        本书原话内容用深蓝色标识,比较重要的内容用加粗倾斜下划线深蓝色标识

引入

        Qt框架功能是本书的核心内容,本贴展开对元对象的理解

QMetaObject类(元对象类)

        本书P49第4段:每个QObject及其子类的实例(对象)都有一个自动创建的元对象,元对象是QMetaObject类型的实例.元对象存储了类的实例所属类的各种元数据,包括类信息元数据、方法元数据、属性元数据等,所以,元对象实质上是对类的描述.

        ---解读:从以下几个方面来解读元对象和元数据:

            1>什么是元数据?这里的元数据和<深入理解计算机系统>(原书第3版)P632中的文件元数据意思相同.表示每个类对象建立时的数据.包括了类方法,类属性,类构造函数,静态数据等内容

            2>类对象元数据怎样实现的?笔者不清楚(如果C++提供了相应的接口,应该也可以访问).但可以分析得出结论---元数据实际上和文件元数据一样,由C++底层记录:每个类对象的属性和类型,方法的名称,参数和返回值,构造函数等信息,被放进了一个数据类型(假设名为MetaObject)中.

        综合本书内容,元数据的大概形式是这样的,假设有一个名叫"DemoClass"的类

class DemoClass{

    public:
        void fun1();    //方法1
        void fun2();    //方法2
        DemoClass();    //构造函数

    private:
        SomeType1 st1;  //属性1
        SomeType2 st2;  //属性2

}

        对应的元数据类型表示为:

/*C++底层对元数据的表示*/
struct MetaObject{
    vector<MetaClassInfo> mcis;
    vector<MetaMethod>    mms;
    vector<MetaEnum>      mes;
    vector<MetaProperty>  mps;
}

        举个例子:MetaMethod类型里应该有些什么内容?他表示方法的元数据.vector表示了有n个方法,对应DemoClass类,mms中有2个MetaMethod对象,试着写出MetaMethod的类型定义:

/*只看意思,不保证准确*/
struct MetaMethod{
    string return_type;        //返回值类型
    string method_name;        //函数名称
    vector<string> parameters; //参数类型名的集合
    /*是否需要形参名未知*/
}

        那么方法1的元数据---fun1()对应的元数据为

/*只看意思,不保证准确*/
/*方法1的元数据,返回值类型为空,函数名称为fun1,无参数*/
MetaMethod fun1={"void","fun1","NULL"}

        意思比较明显了:QMetaObject封装了MetaObject类型对象---基于C++底层对类信息的表示

=============================内容分割线↓===================================

       从C++底层对类信息的表示,继续思考:C++底层,或者机器层,是怎样理解类名,函数名,形参名等内容的?编译时需要用的语义分析---类名,函数名等字符串(姑且认为机器识别为char*类型),他一方面要在机器层面分配一个地址,一方面当地址内容和字符串对应上时,他知道是某个类对象或某个函数.

=============================内容分割线↑===================================

QObject和QMetaObject类型的关系

        本书没有明确说明,他们可能是继承也可能是包含,笔者倾向于他们是"包含"关系

/*伪代码且不保证准确*/
//QMetaObject定义
class QMetaObject{
    MetaObject mo;
}
//QObject定义
class QObject{
    public:
        QMetaObject qmo;
    ...
}

        注意:表3-6的所有接口函数,要先生成元对象---调用表3-5中的第一个方法metaObject();

运行时类型信息

        本书P50举了几个RTTI的例子,都包含在表3-5和表3-6的函数中,所以看一下即可.

        本书P51的强制转换,和标准C++的强制转换类似:父类指针指向子类对象的可以转换.

属性系统

格式

        本书P51讲了属性系统的格式,包括了类型、名称和值

        宏Q_PROPERTY定义了一个值类型为type,名称为name的属性,用READ,WRITE关键字分别定义属性的读取、写入函数,还有一些其他关键字用于定义属性的一些操作特征.属性值的类型可以是QVariant支持的任何类型,也可以是自定义类型.

        ---解读:这里的属性和标准C++类型的属性做个对比---对比也是一种有效的学习方法

/*伪代码*/
class Demo{
    private:
        SomeType st;
        ....
}

        Qt引入的属性系统,在普通C++属性基础上附加了操作信息,包括设置属性读写的函数,默认值,是否常量,是否发射信号,能否被子类重载,是否可以被用户编辑等等.想一想用普通C++也可以实现这些内容,Qt宏Q_PROPERTY封装了这些代码----所以读源码要把宏定义弄清楚

例子

        本书P52:下面是QWidget类定义属性的一些例子.

/*原书示例*/
Q_PROPERTY(bool focus READ hasFocus)
Q_PROPERTY(bool enable READ isEnable WRITE setEnabled)
Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor)

属性读写 

        本书介绍了两种方法,推荐第一种直观明了,第二种比较复杂.第一种方法由对象调用.

        注意:可读可写的属性通常有一个用于读取属性值的函数,函数名一般与属性名相同,还有一个用于设置属性值的函数,函数名一般是在属性前面加"set".        ---不管哪一种语言基本上都这样写.

        属性的读写,需要知道属性的数据类型.

属性元数据的使用

        QMetaObject(属性元数据)对象记录了属性有关的操作信息---和属性设置时对应.使用方法如本书P52所示:

        1.先获得组件元对象,再按照组件属性名称获得属性序号;

        2.根据序号获得QMetaObject对象,此后按照QMetaObject对象函数获得属性信息.

动态属性

        本书P53:如果属性名称不存在,就会为对象定义一个新得属性并设置属性值,这时定义得属性称为动态属性.

        ---解读:动态属性是添加的临时属性.

        动态属性的设置有一个困惑之处:属性使用什么数据类型?本书的例子都是bool型.

附加的类信息

        元对象系统还支持使用宏Q_CLASSINFO()在类中定义一些类信息,类信息有名称和值.

        ---解读:和动态属性一样,属于临时信息.

        附加类信息的访问用三条代码实现:

        1.获得对象的元对象---调用表3-5中的metaObject()

        2.获得QMetaClassInfo对象---调用表3-6中的classInfo(int index),需传入索引号

        3.调用name()返回类信息名称,调用value()返回类信息的值.

---动态属性和附加的类信息暂时没感觉有多大意义:如果设计完整,无需额外增加属性.

小结

        元数据的一些解读.

        元数据的内容和类信息相关的.感觉他的应用场景和信息安全有关.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

重庆彭枫

你的鼓励是我创作的动力,谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值