QMetaObject分析

来源:互联网 发布:千牛 卖家 for mac 编辑:程序博客网 时间:2024/06/06 12:32
  • 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;        }    }    }

// 未完待续。。。

0 0