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
版权声明:本文为博主原创文章,转载请附上博文链接!
QMetaMethod 获取成员函数的元信息的更多相关文章
- Python基础之给函数增加元信息
1. 参数注解 当写好一个函数以后,想为这个函数的参数添加一些额外的信息,这样的话,其他的使用者就可以清楚的知道这个函数应该怎么使用,这个时候可以使用函数参数注解. 函数参数注解能提示程序员应该怎样正 ...
- 通过DatabaseMetaData数据库元信息类,获取特定数据库的元信息
数据库版本:mysql8.0.18 ide:idea 2019.3 可以看到代码中连接的数据库为course_select,是一个学生的选课系统的数据库 然后通过DatabaseMetaData的ge ...
- Java反射理解(四)-- 获取成员变量构造函数信息
Java反射理解(四)-- 获取成员变量构造函数信息 步骤 获取成员变量信息: obj.getClass() 获取类类型对象 成员变量也是对象,java.lang.reflect.Field 类中封装 ...
- 从汇编看c++成员函数指针(三)
前面的从汇编看c++中成员函数指针(一)和从汇编看c++成员函数指针(二)讨论的要么是单一类,要么是普通的多重继承,没有讨论虚拟继承,下面就来看一看,当引入虚拟继承之后,成员函数指针会有什么变化. 下 ...
- C++ 指向类成员函数指针的用法(转自维基百科)
类成员函数指针 类成员函数指针(member function pointer),是C++语言的一类指针数据类型,用于存储一个指定类具有给定的形参列表与返回值类型的成员函数的访问信息. 目录 1 语法 ...
- QMetaEnum获取枚举元信息
QMetaEnum 类提供了一个枚举的元数据.我们可以使用该类的静态模板函数,fromType<enumerator>来获得关于某个枚举的QMetaEnum对象,然后就可以调用该类的成员函 ...
- java反射获取类的成员函数,成员变量,构造函数
package com.imooc.reflect;import javax.sound.midi.Soundbank;import java.lang.reflect.Constructor;imp ...
- 实现php获取mp3文件元信息如播放时间歌曲作者等
最近收集到一个php获取mp3文件元信息的类,感觉比较方便.现在分享给大家! 下面是使用方式和测试方式: <?php include_once 'mp3file.class.php'; func ...
- 微信企业号-根据code获取成员信息(过期code)
二次请求获取成员信息时,会报如下错误: { "errcode": "40029", "errmsg": "invalid code ...
随机推荐
- 【零基础】神经网络优化之L1、L2
一.序言 前面的文章中,我们逐步从单神经元.浅层网络到深层网络,并且大概搞懂了“向前传播”和“反向传播”的原理,比较而言深层网络做“手写数字”识别已经游刃有余了,但神经网络还存在很多问题,比如最常见的 ...
- ML_Review_LDA(Ch5)
Note sth about LDA(Linear Discriminant Analysis) 这篇来说说LDA的复习,LDA在第二次作业的博客中也提及了,但是那是作业思考,所以决定再开一篇只说LD ...
- Alpha冲刺(2/4)
队名:福大帮 组长博客链接:https://www.cnblogs.com/mhq-mhq/p/11885037.html 作业博客 :https://edu.cnblogs.com/campus/f ...
- OpenJudge计算概论-买房子
/*================================================================= 买房子 总时间限制: 1000ms 内存限制: 65536kB ...
- 你的Node应用,对接分布式链路跟踪系统了吗?(一) 原创: 金炳 Node全栈进阶 4天前 戳蓝字「Node全栈进阶」关注我们哦
你的Node应用,对接分布式链路跟踪系统了吗?(一) 原创: 金炳 Node全栈进阶 4天前 戳蓝字「Node全栈进阶」关注我们哦
- http-proxy-middleware及express实现反向代理
$ npm install --save-dev http-proxy-middleware npm install express // 引用依赖 var express = require('ex ...
- 一台java服务器可以跑多少个线程?
一台java服务器能跑多少个线程?这个问题来自一次线上报警如下图,超过了我们的配置阈值. 京东自研UMP监控分析 打出jstack文件,通过IBM Thread and Monitor Dump ...
- bing map for wpf 怎么显示中文地图
添加一下代码: string suriFormat = "http://r2.tiles.ditu.live.com/tiles/r{quadkey}.png?g=41"; Mic ...
- 转载:Spark中文指南(入门篇)-Spark编程模型(一)
原文:https://www.cnblogs.com/miqi1992/p/5621268.html 前言 本章将对Spark做一个简单的介绍,更多教程请参考:Spark教程 本章知识点概括 Apac ...
- jQuery学习三——事件
代码如下: <!DOCTYPE html> <html> <head> <title>jquery事件</title> </head& ...