Qt5之反射机制(内省)
Qt的元对象系统除了提供信号/槽机制的特性之外,它还提供了以下特性:
QObject::metaObject() |
返回关联的元对象 |
QMetaObject::className() |
在运行时状态下返回类名 |
QObject::inherits() |
判断类的继承关系 |
QObject::tr(),QObject::trUtf8() |
提供国际化,翻译字符串 |
QObject::setProperty(),QObject::property() |
通过名称来动态设置和获取属性 |
QMetaObject::newInstance() |
创建新实例 |
通过QObject::metaObject()方法, 所有继承于QObject的类可以 返回元对象系统为其生成的metaObject对象。QMetaObject提供的一些重要信息:
QMetaClassInfo |
通过宏Q_CLASSINFO的支持,提供类的附加信息 |
QMetaEnum |
Qt特色的枚举对象,支持key和 value之间的互转 |
QMetaMethod |
提供类成员函数的元数据 |
QMetaProperty |
提供类成员属性的元数据 |
Qt反射前期准备
1、首先得继承于Q_Object,同时需要在class中加入Q_OBJECT。
2、注册类成员变量需要使用Q_PROPERTY
Q_PROPERTY( type member READ get WRITE set) 其中READ,WRITE是关键字
Type表示成员的类型(不支持自定义类型,对Qt很多基本类型都支持);
Member代表你给该成员另外起的名字,可以和变量名不同;get,set就是自己在C++函数里面定义的基本的访问函数名,不需要写参数。
3、注册类成员函数
如果你希望这个函数能够被反射,那么很简单,只需要在类的函数声明前加入Q_INVOKABLE关键字。
下面是一个例子:
//声明一个继承于QObject的类
class ReflectionObject : public QObject {
Q_OBJECT Q_PROPERTY(int Id READ Id WRITE setId) Q_PROPERTY(QString Name READ Name WRITE setName) Q_PROPERTY(QString Address READ Address WRITE setAddress) Q_PROPERTY(PriorityType Priority READ Priority WRITE setPriority) Q_ENUMS(PriorityType) public: enum PriorityType {High,Low,VeryHigh,VeryLow}; Q_INVOKABLE int Id() {return m_Id; } Q_INVOKABLE QString Name() { return m_Name; } Q_INVOKABLE QString Address() { return m_Address; } Q_INVOKABLE PriorityType Priority() const {return m_Priority; } Q_INVOKABLE void setId(const int & id) {m_Id = id; } Q_INVOKABLE void setName(const QString & name) {m_Name = name; } Q_INVOKABLE void setAddress(const QString & address) {m_Address = address; } Q_INVOKABLE void setPriority(PriorityType priority) {m_Priority = priority; } private:
int m_Id; QString m_Name; QString m_Address; PriorityType m_Priority; };
遍历该类的成员函数:
ReflectionObject theObject; const QMetaObject* theMetaObject =theObject.metaObject(); int methodIndex; int methodCount = theMetaObject->methodCount(); for(methodIndex = 0; methodIndex < methodCount; ++methodIndex) { QMetaMethod oneMethod =theMetaObject->method(methodIndex); qDebug() <<"typeName: " <<oneMethod.typeName(); qDebug() <<"signature: " <<oneMethod.signature(); qDebug() <<"methodType: " <<oneMethod.methodType();; qDebug() <<"parameterNames: " <<oneMethod.parameterNames() <<"\n"; }
其中typeName代表返回类型,signature只的是函数的原貌,methodType代表函数的类型,在Qt中分为三类(槽,信号,普通函数),parameterNames代表函数参数
遍历该类的成员变量:
int propertyIndex; int propertyCount = theMetaObject->propertyCount(); for(propertyIndex = 0; propertyIndex < propertyCount; ++propertyIndex) { QMetaProperty oneProperty =theMetaObject->property(propertyIndex); qDebug() <<"name: " << oneProperty.name(); qDebug() <<"type: " <<oneProperty.type() <<"\n"; }
遍历该类的枚举集合:
int enumeratorIndex; int enumeratorCount = theMetaObject->enumeratorCount(); for(enumeratorIndex = 0; enumeratorIndex < enumeratorCount; ++enumeratorIndex) { QMetaEnum oneEnumerator =theMetaObject->enumerator(enumeratorIndex); int enumIndex; int enumCount = oneEnumerator.keyCount(); for(enumIndex = 0;enumIndex < enumCount; ++enumIndex) { qDebug() <<oneEnumerator.key(enumIndex) <<" ==> " <<oneEnumerator.value(enumIndex); } }
这里我们看到QMetaEnum存在key、value配对出现,这必然可以互转,而QMetaEnum确实提供了方式:valueToKey()、keyToValue()。
反射的应用
反射反射,就我目前的认知水平来看,通过使用字符串,来实现函数的通用化调用,例如你可以利用反射把很多函数放置到数组中,实现一次遍历,全部调用。
目前见到的大多是利用反射来操作数据库,例如hibernate,其实可以利用Qt的反射,快速实现所谓的hibernate。
至此,Qt自带的反射功能已经罗列完整。但是Qt自身并没有提供类反射机制,就是像Java那样通过getObject(String)函数,从类型直接构建新的对象。实现类反射机制请阅读下一篇博客。
http://www.cnblogs.com/RainyBear/p/5251482.html
参考资料:http://blog.csdn.net/playstudy/article/details/7861329;
Qt5之反射机制(内省)的更多相关文章
- day27(反射之内省机制)
内省 内省:底层是使用反射机制实现的,是对于反射的进一步封装. 反射:通过类名来获取类中的所有属性和方法及类中的所有隐藏的方法. 内省:通过一个标准类(javabean类)来获取bean中的字段.ge ...
- Java系列笔记(2) - Java RTTI和反射机制
目录 前言 传统的RTTI 反射 反射的实现方式 反射的性能 反射与设计模式 前言 并不是所有的Class都能在编译时明确,因此在某些情况下需要在运行时再发现和确定类型信息(比如:基于构建编程,),这 ...
- Java反射机制深入研究
ava 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”. 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? ...
- 11.Java反射机制 哦对了,前面的序号来自随笔关于编程之路的思索第一篇
基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象的方法的功能来自于J ...
- 转!!java反射机制
Java 反射机制 基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象 ...
- java 反射机制01
// */ // ]]> java反射机制01 Table of Contents 1 反射机制 2 反射成员 2.1 java.lang.Class 2.2 Constructor 2.3 ...
- Java反射机制学习
Java 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”. 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?答 ...
- Java 反射和内省实现spring的IOC和DI
1.构造两个JavaBean package com.spring.model; public class People { private Car car; public Car getCar() ...
- Java 基础【18】 反射与内省
1.概念定义 Java 反射机制(Reflect)容许程序在运行时加载.探知.使用编译期间完全未知的 class,核心类 java.lang.Class. 通过把指定类中各种元素映射成 java.la ...
随机推荐
- [考试总结]noip模拟20
第五场,再挂分就没了.. 然后就没了.. 考场上一直想方法. 似乎想到了 \(T1\) 正解. 然而几个 \(k\) 的调试信息都让我迷失了自我. 然后有几句啥都没用的语句加在了上面.. 挂分... ...
- kali操作系统安装google浏览器
安装的kali操作系统版本是kali-linux-2020.2-installer-amd64.iso 参考链接:https://www.cnblogs.com/Young-wind/p/585502 ...
- Hadoop 3.1.1 - 概述 - 集群安装
Hadoop 集群安装 目标 本文描述了如何从少数节点到包含上千节点的大规模集群上安装和配置 Hadoop 集群.如果只是为了尝试,你可以先从单台机器上安装开始(参阅单节点安装). 本文并不包含诸如安 ...
- 题解 P6688 可重集
己所欲者,杀而夺之,亦同天赐 解题思路 一定不要用自动溢出的 Hash!!!!!!! 我真的是调吐了... 思路非常简单明了 : 需要我们创新一下 Hash. 首先我们的 Hash 要满足无序性.. ...
- 「Leetcode-算法_Easy461」通过「简单」题目学习位运算
Easy 461.汉明距离 因为原题目翻译效果不佳,这里是笔者自己的理解. 输入两个二进制数 x.y, 输出将 y 变为 x 所需改变的二进制位数,成为汉明距离. 注意: 0 ≤ x, y < ...
- C中的内置函数
1 //#include <stdio.h> 2 //#include <ctype.h> 3 //#include <math.h> 4 //#include & ...
- Docker部署ELK之部署elasticsearch7.6.0(1)
1. 拉取elasticsearch7.6.0镜像: sudo docker pull elasticsearch:7.6.0 2. 输入命令,构建容器: sudo docker run --name ...
- Ubuntu安装ssh,及失败解决方案
网上有很多介绍在Ubuntu下开启SSH服务的文章,但大多数介绍的方法测试后都不太理想,均不能实现远程登录到Ubuntu上,最后分析原因是都没有真正开启ssh-server服务.最终成功的方法如下: ...
- docker搭建kafka集群(高级版)
1. 环境docker, docker-compose 2.zookeeper集群 /data/zookeeper/zoo1/config/zoo.cfg # The number of millis ...
- 微信小程序开发——后端Java(一)
一.前言 最近接触了小程序的开发,后端选择Java,因为小程序的代码运行在腾讯的服务器上,而我们自己编写的Java代码运行在我们自己部署的服务器上,所以一开始不是很明白小程序如何与后台进行通信的,然后 ...