在上一篇中,我們將的是QMetaEnum類,它可以獲得一個類中由Q_ENUM宏或Q_FLAG宏聲明的枚舉類型的元信息。同樣,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()所期望的。
下面,我們以一個實例來使用一下該類:
新建一個Qt控制台程序,再新建一個QObject的子類,在該類中聲明一個槽函數。代碼如下:
#ifndef MYOBJECT_H
#define MYOBJECT_H
#include <QObject>
class MyObject : public QObject
{
Q_OBJECT
public:
explicit MyObject(QObject *parent = 0);
public slots:
int add(int a, int b);
};
#endif // MYOBJECT_H
然后,在main函數中,我們打印出add槽函數的元信息。代碼如下:
#include <QCoreApplication>
#include <QMetaMethod>
#include <QDebug>
#include "myobject.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyObject obj;
QByteArray normalizedSignature = QMetaObject::normalizedSignature("add(int, 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();
return a.exec();
}
運行結果如下:
可以結合QMetaMethod中相關的枚舉類型定義來理解上面的輸出。
enum Access { Private, Protected, Public }
enum MethodType { Method, Signal, Slot, Constructor }
即,該方法的訪問權限為public,類型是slot,其他的都很好理解了。
當然,上面說了,我們可以使用該類的invoke()函數,在已有的對象上,調用該函數。代碼如下:
int result = 0;
bool bCall = metaMethod.invoke(&obj, Q_RETURN_ARG(int, result), Q_ARG(int, 1), Q_ARG(int, 1));
if(bCall)
{
qDebug() << "1 + 1 = " << result;
}
大家可以自行測試一下結果。
---------------------
作者:求道玉
來源:CSDN
原文:https://blog.csdn.net/Amnes1a/article/details/69220916
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!