您的位置:首页 > 移动开发 > Objective-C

QMetaObject分析

2015-06-02 19:06 585 查看
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;
}
}
}


// 未完待续。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: