QMetaObject分析

Q_OBJECT宏在QObject子类中启用信号槽功能,而QMetaObject提供了对元对象系统的访问,包括属性和函数等信息。本文将探讨QMetaObject的属性和相关函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • Q_OBJECT 宏
    在QObject子类中,包含Q_OBJECT宏可以使用Qt的信号槽特性。
class showObject : public QObject
{
    Q_OBJECT
    ....
}
宏展开后会出现:
    const QMetaObject showObject::staticMetaObject; // 每一个QObject派生的子类都包含有一个静态的QMetaObject对象
private:    
    Q_DECL_HIDDEN_STATIC_METACALL 
    static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **);
  • QMetaObject 属性
struct { // private data
        const QMetaObject *superdata;
        const QByteArrayData *stringdata;
        const uint *data;
        typedef void (*StaticMetacallFunction)(QObject *, QMetaObject::Call, int, void **);
        StaticMetacallFunction static_metacall; // (核心)指向子类函数showObject::qt_static_metacall
        const QMetaObject **relatedMetaObjects;
        void *extradata; //reserved for future use
    } d;
  • QMetaObject 函数
/*
    \since 4.5
    Constructs a new instance of this class. You can pass up to ten arguments
    (\a val0, \a val1, \a val2, \a val3, \a val4, \a val5, \a val6, \a val7,
    \a val8, and \a val9) to the constructor. Returns the new object, or 0 if
    no suitable constructor is available.

    Note that only constructors that are declared with the Q_INVOKABLE
    modifier are made available through the meta-object system.

    \sa Q_ARG(), constructor()
*/
QObject *QMetaObject::newInstance(QGenericArgument val0,
                                  QGenericArgument val1,
                                  QGenericArgument val2,
                                  QGenericArgument val3,
                                  QGenericArgument val4,
                                  QGenericArgument val5,
                                  QGenericArgument val6,
                                  QGenericArgument val7,
                                  QGenericArgument val8,
                                  QGenericArgument val9) const
此方法在showObject 子类的构造函数使用/* Q_INVOKABLE */宏修饰的时候有效
public:
    Q_INVOKABLE explicit showObject(QObject *parent = 0);

使用:
    const QMetaObject *meta = &showObject::staticMetaObject;
    QObject *o = meta->newInstance();
    delete o;
原理:
    QMetaObject::newInstance
    {
        .....
        QObject *returnValue = 0; 
        // returnValue 传入param
        void *param[] = {&returnValue, val0.data(),... val9.data()};
        // 关键在这里
        QMetaObject::static_metacall(CreateInstance, idx, param)
        return returnValue;
    }

    int QMetaObject::static_metacall(Call cl, int idx, void **argv) const
    {
        // 这里又调用
        d.static_metacall(0, cl, idx, argv);// 指向 showObject::qt_static_metacall
    }

    // 最终实现之地,终于找到了
    showObject::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
    {
        if (_c == QMetaObject::CreateInstance) {
        switch (_id) {
        // 终于找到 new 了,从此多了一种动态创建showObject的方法,就是使用 QMetaObject::newInstance
        case 0: { showObject *_r = new showObject((*reinterpret_cast< QObject*(*)>(_a[1])));
            if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;
        case 1: { showObject *_r = new showObject();
            if (_a[0]) *reinterpret_cast<QObject**>(_a[0]) = _r; } break;
        }
    }
    }

// 未完待续。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值