深入Qt 学习 -- 反射机制(比较简单清楚)
相对于Java天生的这一特性, C++并不具备;但进入到Qt领域,这一切都变得简单自如了。
从Qt的元对象系统可知,除了提供信号/槽机制的特性之外,它还提供了以下特性:
■ QObject::metaObject() |
返回关联的元对象 |
■ QObject::className() |
在运行时状态下返回类名 |
■ QObject::inherits() |
判断类的继承关系 |
■ QObject::tr() QObject::trUtf8() |
提供国际化,翻译字符串 |
■ QObject::setProperty() QObject::property() |
通过名称来动态设置和获取属性 |
■ QObject::newInstance() |
创建实例 |
其中QObject::className()、QObject::setProperty()和QObject::property()比较吸引眼球,这正是反射机制中的基本功能。建立在Qt的元对象系统的基础上,只要拥有元对象(QMetaObject)的类就支持反射!如何拥有元对象?方法很简单:只需继承于QObject或者它的子类(多重继承的话,QObject类应该放在第一个),在头文件的结构声明中写上Q_OBJECT即可!
元对象信息
通过QObject::metaObject()方法, 所有继承于QObject的类可以 返回元对象系统为其生成的metaObject对象。看看QMetaObject提供的一些重要信息:
■ QMetaClassInfo |
通过宏Q_CLASSINFO的支持,提供类的附加信息 |
■ QMetaEnum |
Qt特色的枚举对象,支持key和 value之间的互转 |
■ QMetaMethod |
提供类成员函数的元数据 |
■ QMetaProperty |
提供类成员属性的元数据 |
根据QMetaObject提供的数据对象,完全可以编写通用的代码来支持反射特性。
例子:
声明一个类,继承于QObject
classReflectionObject : publicQObject { Q_OBJECT Q_PROPERTY(intId READ Id WRITE setId) Q_PROPERTY(QString Name READ Name WRITEsetName) Q_PROPERTY(QString Address READ Address WRITEsetAddress) Q_PROPERTY(PriorityType Level READ Priority WRITEsetPriority) Q_ENUMS(PriorityType) public: enumPriorityType { High, Low, VeryHigh,VeryLow }; Q_INVOKABLEint Id() {returnm_Id; } Q_INVOKABLEQString Name() { returnm_Name; } Q_INVOKABLEQString Address() { returnm_Address; } Q_INVOKABLEPriorityType Priority() const {returnm_Priority; } Q_INVOKABLEvoid setId(constint& id) {m_Id = id; } Q_INVOKABLEvoid setName(constQString& name) {m_Name = name; } Q_INVOKABLEvoid setAddress(constQString& address) {m_Address = address; } Q_INVOKABLEvoid setPriority(PriorityType priority) {m_Priority = priority; } private: int m_Id; QString m_Name; QString m_Address; PriorityTypem_Priority; }; |
为了能检测到类成员函数,得在函数前加上一个宏Q_INVOKABLE, 这意味着该函数在元对象系统编译该类时注册该函数,则在运行过程中能被元对象调用。
经过上述声明,在运行时即可做些操作:
/*遍历该类的成员: */
ReflectionObjecttheObject; constQMetaObject*theMetaObject =theObject.metaObject(); intmetathodIndex; intmetathodCount = theMetaObject->methodCount(); for(metathodIndex = 0; metathodIndex < metathodCount; ++metathodIndex) { QMetaMethodoneMethod =theMetaObject->method(metathodIndex); qDebug() <<"typeName: " <<oneMethod.typeName(); qDebug() <<"signature: " <<oneMethod.signature(); qDebug() <<"methodType: " <<oneMethod.methodType();; qDebug() <<"parameterNames: " <<oneMethod.parameterNames() <<"\n"; } |
/*遍历该类的属性: */
intpropertyIndex; intpropertyCount = theMetaObject->propertyCount(); for(propertyIndex = 0; propertyIndex < propertyCount; ++propertyIndex) { QMetaPropertyoneProperty =theMetaObject->property(propertyIndex); qDebug() <<"name: " << oneProperty.name(); qDebug() <<"type: " <<oneProperty.type() <<"\n"; } |
/*遍历该类的枚举集合*/
intenumeratorIndex; intenumeratorCount = theMetaObject->enumeratorCount(); for(enumeratorIndex = 0; enumeratorIndex < enumeratorCount; ++enumeratorIndex) { QMetaEnumoneEnumerator =theMetaObject->enumerator(enumeratorIndex); intenumIndex; intenumCount = oneEnumerator.keyCount(); for(enumIndex = 0;enumIndex < enumCount; ++enumIndex) { qDebug() <<oneEnumerator.key(enumIndex) <<" ==> " <<oneEnumerator.value(enumIndex); } } |
在这里我们看到QMetaEnum存在key、value配对出现,这必然可以互转,而QMetaEnum确实提供了方式:valueToKey()、keyToValue()。
通过这个测试能将ReflectionObject这个类的方法和属性完全遍历出来,完成自身的检查,也即反射。
反射在Qt应用程序中的用途
在Qt的元对象系统支持下,赋予了C++并不直接拥有的此特性。这样加大了开发应用程序的自由度,尤其在软件工程中强调高内聚低耦合的状态下。
具体的用例中, 可以通过Qt Designer这个工具来描述(尽管暂不清楚内部是否利用此方法来实现J):
对于其中的控件,放入到Designer中时,Designer事先并不知道(其实也不需要知道)放入插件的类型、方法和属性。将插件导入时,它可以检测该控件的类型、方法和属性;
这样在Designer中绘制控件时,遍历该控件的属性, 将这些属性显示在属性窗口中,便于修改;
在信号/槽对话框编辑时,遍历该控件的属性,提取信号/槽函数,放入对应的编辑区域里;
http://blog.csdn.net/playstudy/article/details/7861329
深入Qt 学习 -- 反射机制(比较简单清楚)的更多相关文章
- (转)java反射机制及简单工厂模式
第一步,定义一个接口类 package factory.face; /** * 接口,为了保证返回的对象可以统一用 Product接受 * @author Administrator */ publi ...
- java反射机制的简单介绍
参考博客: https://blog.csdn.net/mlc1218559742/article/details/52754310 先给出反射机制中常用的几个方法: Class.forName (& ...
- 045-利用反射机制,简单的实现PHP插件模式
<?php //利用反射机制,简单的实现PHP插件模式 # 假设,我们有一款开源产品,所有开发者都必须在我定制的需求之上,进行二次开发, # 而开发完成后的新模块,就是一个不一样的新插件,可以放 ...
- Java反射机制的简单学习
今天看了一下Java的反射机制,就此记录一下. 首先,我们要先了解一下什么是反射? 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力. JAV ...
- Qt类反射机制
前言 如何通过类名动态的创建对象(类反射),对于Java开发者来说一点也不陌生,当然Qt也提供了一个元对象系统(The Meta-Object System),通过这个系统我们可以动态的在运行时获 ...
- 利用Java反射机制优化简单工厂设计模式
之前项目有个需求,审批流程的时候要根据配置发送信息:发送短信.发送邮件.当时看到这个就想到要用工厂模式,为什么要用工厂模式呢?用工厂模式进行大型项目的开发,可以很好的进行项目并行开发.就是一个程序员和 ...
- C++ 反射机制的简单实现
C++并不支持反射机制,只能自己实现. 如果需要实现字字符串到函数到映射,一定要使用到函数指针. 简单实现反射机制,根据字符串来构造相应到类.主要有以下几点: (1) 可以使用map保存字符从到函数指 ...
- Java反射机制的简单应用
一直感觉java的反射机制非常强大,可是可用的地方不多.在android学习的时候.一直想实现挂断电话的功能,可是系统并没有提供开放的api接口,看了一下网上使用反射机制来实现该功能,确实非常强大,非 ...
- java学习——反射机制
/* * JAVA反射机制是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法: * 对于任意一个对象,都能够调用它的任意一个方法和属性: * 这种动态获取的信息以及动 ...
随机推荐
- Spring Boot 静态资源处理(转)
Spring Boot 静态资源处理 Spring Boot 系列 Spring Boot 入门 Spring Boot 属性配置和使用 Spring Boot 集成MyBatis Spring Bo ...
- Diskpart工具应用两则:MBR/GPT分区转换 & 基本/动态磁盘转换
将基本磁盘转换为动态磁盘可直接在操作系统的磁盘管理中完毕,如图1所看到的,这一转换过程对硬盘上的数据没有影响,可是可能会影响到系统的启动(盗版系统激活会受影响). 图1:基本磁盘转换为动态磁盘 要注意 ...
- C++学习笔记(达内视频版)
达内C++(陈宗权主讲) 第一天: 课程分为Core C++(标准C++.不依赖操作系统)和Unix C++. 1.配置bash,运行.sh文件. vi bash_profile 在"pat ...
- gdbserver远程调试嵌入式linux应用程序方法
此处所讲的是基于gdb和gdbsever的远程调试方法.环境为:PC机:win7.虚拟机:10.04.下位机:飞嵌TE2440开发板. 嵌入式linux应用程序的开发一般都是在linux里面编写好代码 ...
- POJ 1458 Common Subsequence (zoj 1733 ) LCS
POJ:http://poj.org/problem?id=1458 ZOJ:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=73 ...
- 9、基于Linux的v4l2视频架构应用编写
Linux系统中,视频设备被当作一个设备文件来看待,设备文件存放在 /dev目录下,完整路径的设备文件名为: /dev/video0 . 视频采集基本步骤流程如下: 打开视频设备,设置视频设备属性及采 ...
- 【u023】最长上升子序列(sequence)
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 非常经典的问题,拿来给大家练手了. 序列 { 1,2,...,n } 的一个子序列是指序列 { i1, ...
- 如何用Swift创建一个复杂的加载动画
现在在苹果应用商店上有超过140万的App,想让你的app事件非常具有挑战的事情.你有这样一个机会,在你的应用的数据完全加载出来之前,你可以通过一个很小的窗口来捕获用户的关注. 没有比这个更好的地方让 ...
- (十二)RabbitMQ消息队列-性能测试
原文:(十二)RabbitMQ消息队列-性能测试 硬件配置 宿主机用的联想3850X6的服务器四颗E7-4850v3的处理器,DDR4内存,两块1.25TB的pcie固态.在宿主机上使用的事esxi5 ...
- [D3] Create Labels from Non-numeric Data with Ordinal Scales in D3 v4
When your data contains discrete, non-numeric property values that you need to format or convert bef ...