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之反射机制(内省)的更多相关文章

  1. day27(反射之内省机制)

    内省 内省:底层是使用反射机制实现的,是对于反射的进一步封装. 反射:通过类名来获取类中的所有属性和方法及类中的所有隐藏的方法. 内省:通过一个标准类(javabean类)来获取bean中的字段.ge ...

  2. Java系列笔记(2) - Java RTTI和反射机制

    目录 前言 传统的RTTI 反射 反射的实现方式 反射的性能 反射与设计模式 前言 并不是所有的Class都能在编译时明确,因此在某些情况下需要在运行时再发现和确定类型信息(比如:基于构建编程,),这 ...

  3. Java反射机制深入研究

    ava 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”.   在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? ...

  4. 11.Java反射机制 哦对了,前面的序号来自随笔关于编程之路的思索第一篇

    基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象的方法的功能来自于J ...

  5. 转!!java反射机制

    Java 反射机制 基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象 ...

  6. java 反射机制01

    // */ // ]]>   java反射机制01 Table of Contents 1 反射机制 2 反射成员 2.1 java.lang.Class 2.2 Constructor 2.3 ...

  7. Java反射机制学习

    Java 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”. 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?答 ...

  8. Java 反射和内省实现spring的IOC和DI

    1.构造两个JavaBean package com.spring.model; public class People { private Car car; public Car getCar() ...

  9. Java 基础【18】 反射与内省

    1.概念定义 Java 反射机制(Reflect)容许程序在运行时加载.探知.使用编译期间完全未知的 class,核心类 java.lang.Class. 通过把指定类中各种元素映射成 java.la ...

随机推荐

  1. 第十五篇 -- QListWidget与QToolButton(界面)

    效果图: 这还只是一个界面,并没有实现相应功能. 先看下这图的构成吧. 工具栏的就是将Action拖上去,这部分前面已经介绍过了,那就看下面这部分的构图. 1.左侧是一个工具箱(ToolBox)组件, ...

  2. 前端构建第1篇之---引入elementUI

    张艳涛 写于2021-1-19 HOW:如何引入elementui? 在项目根目录package.json引入,在重新执行npm install "dependencies": { ...

  3. Tomcat7+ 弱口令 && 后台getshell漏洞

    打开tomcat管理页面http://192.168.49.2:8080/manager/html,输入弱密码tomcat:tomcat,即可访问后台 先将jsp大马压缩为zip,再将zip后缀改名为 ...

  4. icmp介绍以及arp攻击

    目录 一.ip数据包格式 二.ICMP协议介绍 三.ARP协议介绍 四.ARP攻击原理 一.ip数据包格式 网络层的功能: 定义了基于ip协议的逻辑地址 连接不同的媒介类型 选择是数据通过网络的最佳途 ...

  5. 表格技术七十二变|手把手教你用Canvas电子表格做电子签名

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 日常生活工作学习中,大家对电子表格必定不陌生.从工作数据汇总分析到出门收据各种电子发票,这些都是由电子表格制 ...

  6. 复杂字符串转List<JSONObject>

    public static List<JSONObject> getlist(String data){ ObjectMapper mapper = new ObjectMapper(); ...

  7. spring-session-data-redis反序列化问题

    springCloud项目,采用springSession,用户模块同时引入了spring-cloud-starter-security,在其他模块request.getSession()的时候抛了以 ...

  8. golang 日志框架(zap)完整配置和使用

    目录结构: logger.go文件: package log import ( rotatelogs "github.com/lestrrat-go/file-rotatelogs" ...

  9. 关于 phpstudy环境下在MySQL中执行into outfile无法导入导出文件解决方法

    之前在做sqli-labs练习,需要用到into outfile 出现以下问题: 执行SQL语句后在指定的路径下无文件生成. 例如: 执行 select into outfile "C:\\ ...

  10. Windows10 + Chrome 触发蓝屏

    姿势一: 打开Chrome,输入路径:\\.\globalroot\device\condrv\kernelconnect 姿势二: 将代码 <iframe src="\\.\glob ...