导言:
最近在深入理解一个项目的Demo时,有一个难点困惑了整整一个上午,就是关于QMetaMethod类的使用。查看了官方的手册,懵懵懂懂。搜罗了网上的相关介绍,总算是有些明白了。接着,我就来分享下我的总结吧!
介绍:
QMetaMethod类是用来获取成员方法的元信息的一个类。
通过该类,我们可以获取到一个成员方法的类型,比如它是信号、槽、方法、构造函数;
也可以获得方法的完整签名,以及方法所接受的参数类型和参数名字;
当然也可以获取方法的返回值类型;
还可以使用access()方法获取成员函数的访问权限。
当然,最重要的还是invoke()方法,使用该方法我们可以在任意的QObject对象上调用成员函数。
而要得到一个QMetaMethod类的实例,有如下方法:
- 对于信号,可以使用该类的静态方法fromSignal()来获得相对于该信号的QMetaMethod对象;
- 对于普通成员函数和槽函数,可以使用类的QMetaObject对象来间接获取。分别举例如下:
方法一
QMetaMethod destroyedSignal = QMetaMethod::fromSignal(&QObject::destroyed);
方法二
QString retVal;
QByteArray normalizedSignature = QMetaObject::normalizedSignature(“compute(QString, int, double)”);
int methodIndex = obj->metaObject()->indexOfMethod(normalizedSignature);
QMetaMethod method = obj->metaObject()->method(methodIndex);
method.invoke(obj,
Qt::DirectConnection,
Q_RETURN_ARG(QString, retVal),
Q_ARG(QString, “sqrt”),
Q_ARG(int, 42),
Q_ARG(double, 9.7));
其中,要使用QMetaObject::normalizedSignature()来规范化函数签名,确保方法签名是invoke()所期望的。
看到这里的时候,大家还是会很困惑,如何理解invoke()方法,使用该方法我们可以在任意的QObject对象上调用成员函数。
现在我来举一个例子:
在上一篇我的博文《Qt 控制台 使用connect连接信号和槽》中,已经提到了信号和槽的使用,
这里我们在main()中补充如下代码:
QByteArray normalizedSignature = QMetaObject::normalizedSignature("cirleSolve(int)");
int methodIndex = obj.metaObject()->indexOfMethod(normalizedSignature);
QMetaMethod metaMethod = obj.metaObject()->method(methodIndex);
qDebug() << "Access: " << metaMethod.access();
qDebug() << "Valid: " << metaMethod.isValid();
qDebug() << "Index: " << metaMethod.methodIndex();
qDebug() << "Signature: " << metaMethod.methodSignature();
qDebug() << "Type: " << metaMethod.methodType();
qDebug() << "Name: " << metaMethod.name();
qDebug() << "Parameter names: " << metaMethod.parameterNames();
qDebug() << "Parameter types: " << metaMethod.parameterTypes();
qDebug() << "Return type: " << metaMethod.returnType();
qDebug() << "Type name: " << metaMethod.typeName();
//int result = 0;
bool bCall = metaMethod.invoke(&obj, Qt:: AutoConnection,Q_ARG(int, 42));
if(bCall)
{
qDebug() << "the area of obj " << obj.getArea();
}
输出:
可以看到,QMetaObject对象obj 获取到了槽函数的相关信息,并且通过invoke ()函数实现了对 槽函数circleSolve(int)的调用,将“”42”的值传入,并进行计算。
更多关于QMetaObject对象的介绍,可以参考官方的help手册。