在上一篇中,我们将的是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
版权声明:本文为博主原创文章,转载请附上博文链接!

最新文章

  1. poj 2195 Going Home
  2. Spring4学习笔记1-HelloWorld与IOC和DI概述
  3. easyUI 后台经典框架DEMO下载
  4. centos nc命令安装
  5. CentOS 搭建LNMP服务器和LAMP服务器
  6. windows同时安装两个jdk
  7. WM_PAINT消息小结
  8. &lt;!DOCTYPE&gt; 声明 引发的错误
  9. RabbitMQ入门-高效的Work模式
  10. 关于 JS 拖拽功能的冲突问题及解决方法
  11. Oracle 大数据集成实施
  12. c# API接收Base64转图片
  13. HiveQl 基本查询
  14. vector的 []
  15. NoSQL简单介绍
  16. select2 清除选中项解决办法
  17. Java线程池深入理解
  18. Linux内核启动流程与模块机制
  19. go语言中container容器数据结构heap、list、ring
  20. 2015 湘潭大学程序设计比赛(Internet)H题-括号匹配

热门文章

  1. ES里设置索引中倒排列表仅仅存文档ID——采用docs存储后可以降低pos文件和cfs文件大小
  2. LeetCode 第 153 场周赛
  3. Alpha项目冲刺! Day6-产出
  4. KA,连接池居然这么简单? 原创: 58沈剑 架构师之路 3月20日
  5. Centos7.4服务器安装Laravel5.7详细讲解(2018-10-27)
  6. oracle库两个表关联查询时用 count 报错【我】
  7. delete 删除指针
  8. osg create shape
  9. Qt pri文件
  10. 编译安装python3事出错: