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 ...
随机推荐
- 第一篇 -- Go环境的搭建以及Hello World程序编写
VS Code的下载和安装 1. 下载链接(本人下载版本VSCodeUserSetup-x64-1.57.0.exe) https://code.visualstudio.com/download 友 ...
- C实现奇偶校验
奇偶校验原理(来自百度百科):奇偶校验(Parity Check)是一种校验代码传输正确性的方法.根据被传输的一组二进制代码的数位中"1"的个数是奇数或偶数来进行校验.采用奇数的称 ...
- jvm源码解读--18 Java的start()方法解读 以及 wait 和notify流程图
drawwed by 张艳涛 and get info from openjdk8 还有一个图
- jvm源码解读--13 gc_root中的栈中oop的mark 和copy 过程分析
粘贴源码 package com.test; import java.util.Random; public class Test { static int number=12; private in ...
- 除了Swagger UI,你还能选择 IGeekFan.AspNetCore.RapiDoc
IGeekFan.AspNetCore.RapiDoc 看到博客园上的这个文章,说了下Knife4J,评论里有人推荐RapiDoc,放了几个图,看了下,还不错. 心里 便有个想法,借着上次研究 Kni ...
- Mybatis学习笔记-日志
日志工厂 如果一个数据库操作出现异常,在排错时,则需要日志 SLF4J Apache Commons Logging(COMMONS_LOGGING) LOG4J LOG4J2 JDK logging ...
- alpakka-kafka(6)-kafka应用案例,用户接口
了解了kafka原理之后,对kafka的的应用场景有了一些想法.在下面的一系列讨论中把最近一个项目中关于kafka的应用介绍一下. 先介绍一下使用kafka的起因:任何进销存系统,销售开单部分都应该算 ...
- netty系列之:自动重连
目录 简介 使用netty建立连接 自动重连接的原理 模拟自动重连 总结 简介 我们在使用客户端和服务器端连接的过程中,可能会因为各种问题导致客户端和服务器的连接发生中断,遇到这种情况,一般情况下我们 ...
- 这个 Redis 连接池的新监控方式针不戳~我再加一点佐料
Lettuce 是一个 Redis 连接池,和 Jedis 不一样的是,Lettuce 是主要基于 Netty 以及 ProjectReactor 实现的异步连接池.由于基于 ProjectReact ...
- 中高级Android大厂面试秘籍,为你保驾护航金三银四,直通大厂(上)
前言 当下,正面临着近几年来的最严重的互联网寒冬,听得最多的一句话便是:相见于江湖~.缩减HC.裁员不绝于耳,大家都是人心惶惶,年前如此,年后想必肯定又是一场更为惨烈的江湖厮杀.但博主始终相信,寒冬之 ...