QMetaMethod 獲取成員函數的元信息


在上一篇中,我們將的是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
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM