QT之元对象QMetaObject

元对象是什么?

其实就是用来存储类的结构信息的对象;由于其在QT中的名称为QMetaObject所以翻译过来就叫元对象。

那么类的结构信息存储在哪里的呢?

其实类的结构信息存储在一个类型为QMetaObject名为staticMetaObject的全局变量中我们可将其称作元对象。

存储的过程:

1.在Qt中元对象是在编译时由元对象编译器(Meta Object Compiler,即 moc)根据类的源文件生成的。
2.编译器在扫描源文件时,将包含了 QObject 宏的类声明识别出来
3.moc会解析该类的声明、信号、槽和属性等信息,并生成对应的元对象代码,提取类的结构信息,并将其存储在元对象的静态全局变量(staticMetaObject)中
3.生成的元对象代码会与源文件一起被编译形成最终的编译结果

比如编写类MyObject,继承QObject,并声明Q_OBJECT(必须)

#include <QObject>
class MyObject : QObject
{
    Q_OBJECT

    qint32 tempInt;
    bool tempBool;

public:
    explicit MyObject(QObject* parent = nullptr);
signals:
    void mySignal();
public slots:
    void mySlot();
};
#endif // MYOBJECT_H

编译后会生成MOC代码,其中有一个全局静态变量staticMetaObject

QT_INIT_METAOBJECT const QMetaObject MyObject::staticMetaObject = { {
    QMetaObject::SuperData::link<QObject::staticMetaObject>(),
    qt_meta_stringdata_MyObject.data,
    qt_meta_data_MyObject,
    qt_static_metacall,
    nullptr,
    nullptr
} };

这个staticMetaObject就是存储了我们需要的结构信息的元对象
我们可以通过对象的metaObject()函数来获取并访问它
例如:

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    MyObject myobj;
    qDebug() <<  myobj.metaObject()->className();

    return a.exec();
}
image.png
这个元对象中几乎存储了类的所有结构信息比如:

1.类名和父类名:元对象存储了类的名称以及其直接父类的名称。
2.属性信息:元对象中包含了类的属性的信息,包括属性名称、类型、读写访问权限等。
3.方法信息:元对象存储了类中定义的所有方法的信息,包括名称、参数类型和参数数量等。
5.信号和槽信息:元对象存储了类中定义的所有信号和槽的信息,包括信号和槽的名称、参数类型和参数数量等。
6.元对象连接信息:元对象中存储了类之间的连接信息,表示一个类的信号连接到另一个类的槽的关系。
7.其他元对象相关信息:元对象还可以存储其他相关的元对象信息,如类的静态成员信息和嵌套类型等。

如何访问这些信息
获取类的名称以及父类名称
    MyObject myobj;
    const QMetaObject* metaObject = myobj.metaObject();
    qDebug()<<"类名称:" <<  metaObject->className();
    qDebug()<<"父类名称:" <<  metaObject->superClass()->className();
获取属性需先将属性在类中进行声明
class MyObject : QObject
{
    Q_OBJECT
    Q_PROPERTY(qint32 tempInt READ getTempInt WRITE setTempInt)
private:
    qint32 tempInt;
    bool tempBool;

public:
    explicit MyObject(QObject* parent = nullptr);
    MyObject(qint32 a,bool isTrue);
    qint32 getTempInt() const;
    void setTempInt(qint32 t);
signals:
    void mySignal();
public slots:
    void mySlot();
};
获取类的属性
    int propertyCount = metaObject->propertyCount();
    qDebug()<<"属性数量:" << propertyCount;
    QObject *object = dynamic_cast<QObject*>(&myobj);
    for (int i = 0; i < propertyCount; ++i)
    {
        QMetaProperty property = metaObject->property(i);
        qDebug() << "Property name:" << property.name();
        qDebug() << "Property type:" << property.typeName();
        qDebug() << "Property value:" << property.read(object);
    }

想用名称来访问的可先根据名称获取索引,在用索引读取属性值
int index = metaObject->indexOfProperty("tempInt");

方法调用
    index =  metaObject->indexOfMethod("testSum(int,int)");
    QMetaMethod method = metaObject->method(index); // 获取方法
    if (method.methodType() == QMetaMethod::Method){
        QList<QByteArray> parameterTypes = method.parameterTypes();
        QList<QGenericArgument> arguments;
        for (const QByteArray& parameterType : parameterTypes) {
            if (parameterType == "int") {
                int value = 265; // 假设参数为 int 类型
                arguments.append(Q_ARG(int, value));
            }
            qDebug() << "parameterType =  " << parameterType;
        }
        int returnValue = 0;
        bool isCall = method.invoke(object, 
        Qt::AutoConnection,Q_RETURN_ARG(int,returnValue), arguments.value(0), arguments.value(1));
        qDebug() << "call " << isCall << " = " << returnValue;
    }else {
        qDebug() << "methodType =  " << method.methodType();
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容