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

时间: 2025-01-14 19:01:07

Qt5只反射机制(内省)的相关文章

理解Java的反射与内省及其区别

java的内省机制和反射机制什么区别 内省操作只针对JavaBean,只有符合JavaBean规则的类的成员才可以采用内省API进行操作....而反射则不同,一个类的所有成员都可以进行反射操作. 内省和反射的操作也有很大不同,内省是先得到属性描述器PropertyDecriptor后再进行各种操作,反射则是先得到类的字节码Class后再进行各种操作的. 反射(reflection)(实现可扩展性智能化) 相对而言,反射比内省更容易理解一点.用一句比较白的话来概括,反射就是让你可以通过名称来得到对

深入理解java:1.1.1.反射机制

反射 到底什么是反射(Reflection)呢? 反射有时候也被称为内省(Introspection),事实上,反射,就是一种内省的方式, Java不允许在运行时改变程序结构或类型变量的结构,但它允许在运行时去探知.加载.调用在编译期完全未知的class,可以在运行时加载该class,生成实例对象(instance object),调用method,或对field赋值. 这种类似于"看透"了class的特性被称为反射(Reflection),我们可以将反射直接理解为:可以看到自己在水中

java 反射机制(我的第一篇博客)

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”.从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言.但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时

使用反射机制调用属性和私有成员与代理模式的介绍

使用反射机制调用属性: 通过反射机制可以获得类的属性,获得到的属性同样的可以进行赋值.得值操作,调用getField方法并传递属性的名称可以获得[学Java,到凯哥学堂kaige123.com]指定的属性,调用getFields方法则可以获得全部属性,但是这种方式不能获得私有属性: 代码示例: Student类示例: 运行结果: 从运行结果可以看出只拿出了公开的属性,私有的属性拿不到. 使用反射机制调用私有成员: 1.调用私有属性 在反射机制里调用私有属性需要通过getDeclaredField

反射机制

反射机制: 反射机制是能够帮助我们把代码变得更加灵活,可扩展性更高,俗称"软编程.软写法".例如:有一个文件里面有一些值,想要把这些值赋值到一个Student类的属性中,按照以前所学到的知识点,只能是通过文件流将文件里的值读取出来,然后再通过set方法将这些值都赋给Student类的属性.但是,这种方式是将代码写死了,在这之后会有一个问题就是如果文件里的内容发生变动,或者要把这个Student类更换成Dog类的话,就要重新修改代码.程序写好了部署到服务器上运行了,总不能时不时就打开来修

java学习——反射机制

/* * JAVA反射机制是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法: * 对于任意一个对象,都能够调用它的任意一个方法和属性: * 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. * * 动态获取类中信息,就是java反射 . * 可以理解为对类的解剖. * * 要想要对字节码文件进行解剖,必须要有字节码文件对象. * 如何获取字节码文件对象呢? * */ 1. 通过Class clazz =Class.forName()找

反射机制的实现代码

很多朋友在深入的接触JAVA语言后就会发现这样两个词:反射(Reflection)和内省(Introspector),经常搞不清楚这到底是怎么回事,在什么场合下应用以及如何使用?今天把这二者放在一起介绍,因为它们二者是相辅相成的. 一.反射 相对而言,反射比内省更容易理解一点. 很多朋友在深入的接触JAVA语言后就会发现这样两个词:反射(Reflection)和内省(Introspector),经常搞不清楚这到底是怎么回事,在什么场合下应用以及如何使用?今天把这二者放在一起介绍,因为它们二者是相

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

目录 前言 传统的RTTI 反射 反射的实现方式 反射的性能 反射与设计模式 前言 并不是所有的Class都能在编译时明确,因此在某些情况下需要在运行时再发现和确定类型信息(比如:基于构建编程,),这就是RTTI(Runtime Type Information,运行时类型信息). 在java中,有两种RTTI的方式,一种是传统的,即假设在编译时已经知道了所有的类型:还有一种,是利用反射机制,在运行时再尝试确定类型信息. 本文主要讲反射方式实现的RTTI,建议在阅读本文之前,先了解类的加载机制(

java反射机制之基础

一.什么是反射机制 简单的来说,反射机制指的是程序在运行时能够获取自身的信息.在java中,只要给定类的名字, 那么就可以通过反射机制来获得类的所有信息. 二.哪里用到反射机制 有些时候,我们用过一些知识,但是并不知道它的专业术语是什么,在刚刚学jdbc时用过一行代码,Class.forName("com.mysql.jdbc.Driver.class").newInstance();但是那时候只知道那行代码是生成驱动对象实例,并不知道它的具体含义.听了反射机制这节课后,才知道,原来这