Qt 如何使用反射?

c++ 反射 标准库暂时还没有,那我们来看看如何使用 qt 来进行反射.

反射类的案例

1. 通过注册的类型需找 id 进行实例化该类

myclass.h

#include <QtCore>

class MyClass
{
public:
MyClass() {}
QString name(){
return "cheungxiongwei";
}
};
//声明元对象类型
Q_DECLARE_METATYPE(MyClass)

main.cpp

#include <QCoreApplication>
#include "myclass.h" int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv); // 注册自定义的类
qRegisterMetaType<MyClass>("MyClass"); // 通过静态函数获取注册类的 id,id 不为 0 时,则获取成功.大部分基础类型都可以获取到 id,如 QString QByteArray
int id = QMetaType::type("MyClass");
if(id != 0){
// 根据 id 创建该类型
void *myClass = QMetaType::create(id);
// 转换指针
MyClass *my = static_cast<MyClass*>(myClass);
// 调用函数
qDebug() << my->name(); // 这里可以添加一些自己自己的处理函数 // 释放内存
QMetaType::destroy(id, myClass);
myClass = nullptr;
} return a.exec();
}

2. 通过调用静态成员变量 MyClass::staticMetaObject 获取元对象信息,比较类名称来确定 QMetaObject

myclass.h

class MyClass1 : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE MyClass1() {}
virtual ~MyClass1() {}
// 添加宏 Q_INVOKABLE 可以使用 invokeMethod 调用该函数
Q_INVOKABLE QString name(QString name){
return name.append("xiongwei");
} QString name_(){
return "cheungxiongwei";
}
}; class MyClass2 : public QObject
{
Q_OBJECT
public:
MyClass2() {}
virtual ~MyClass2() {}
}; inline QMetaObject GetMetaObjectByClassName(QString className)
{
QMetaObject metaObject;
if(className.compare("MyClass1") == 0){
metaObject = MyClass1::staticMetaObject;
}else if (className.compare("MyClass2") == 0){
metaObject = MyClass2::staticMetaObject;
} // and so on, you get the idea ... return metaObject;
} inline QMetaObject GetMetaObjectByClassName(QString className)
{
QMetaObject metaObject;
if(className.compare("MyClass1") == 0){
metaObject = LayoutCameraGrab::staticMetaObject;
}else if (className.compare("MyClass2") == 0){
metaObject = LayoutImageRead::staticMetaObject;
} // and so on, you get the idea ... return metaObject;
} inline void printMetaObject(const QMetaObject *metaObject)
{
qDebug() << "Class:" << metaObject->className();
for(int i = 0;i < metaObject->classInfoCount();++i){
qDebug() << "ClassInfo:" << metaObject->classInfo(i).name() << metaObject->classInfo(i).value();
} for(int i = 0;i < metaObject->constructorCount();++i){
qDebug() << "Constructor:" << metaObject->constructor(i).name() << metaObject->constructor(i).parameterNames();
} for(int i = 0;i < metaObject->enumeratorCount();++i){
qDebug() << "Enum:" << metaObject->enumerator(i).name();
} for(int i = 0;i < metaObject->methodCount();++i){
qDebug() << "Method:" << metaObject->method(i).name() << metaObject->method(i).parameterNames() << metaObject->method(i).tag();
} for(int i = 0;i < metaObject->propertyCount();++i){
qDebug() << "Proper:" << metaObject->property(i).name();
}
}

main.cpp

Note that only constructors that are declared with the Q_INVOKABLE modifier are made available through the meta-object system.

上面一句话说的是只有在构造函数前面添加 Q_INVOKABLE 宏后才可以 QMetaObject 的函数 newInstance 创建该实例.

#include <QCoreApplication>
#include "myclass.h" int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv); // 通过类名称获取元对象类型
QMetaObject metaObject = GetMetaObjectByClassName("MyClass1"); // 实例化该类
QObject *object = metaObject.newInstance();
if(object){
QString ret;
// 调用 name 带参数函数
// 如果未加 Q_INVOKABLE 宏,则输出 QMetaObject::invokeMethod: No such method MyClass1::name<QString>
metaObject.invokeMethod(
object,
"name",
Qt::DirectConnection,
Q_RETURN_ARG(QString,ret),
Q_ARG(QString,"cheung"));
// 打印返回值
qDebug() << ret; // 转换指针类型调用未加 Q_INVOKABLE 宏的函数.
MyClass1 *myclass = static_cast<MyClass1*>(object);
Debug() << myclass->name_();
} qDebug() << object; return a.exec();
}

Qt 如何使用反射?的更多相关文章

  1. Qt and C++ Reflection,利用Qt简化C++的反射实现

    如何在C++中实现反射机制,应该算是C++开发中经常遇到的问题之一.C++程序没有完整的元数据,也就无法实现原生的反射机制.从性能的角度讲,这样的设计不难理解,毕竟在运行时储存这些元数据需要额外的开销 ...

  2. Qt 反射

    简介 本文主要讲解Qt是如何实现反射,以及一点点反射使用的小心得. 文章概览 Qt反射内幕小窥 详细内容 反射前期准备 得到注册的类成员变量 得到注册的类成员函数 访问类成员属性(get,set) 调 ...

  3. Qt信号槽连接在有默认形参下的情况思考

    写下这个给自己备忘,比如函数 ) 你在调用端如论是test(3)或者test(),都可以正确调用到这个函数. 但是,如果放到Qt中的信号槽的话,这个还是值得讲一讲的,不然的话,可能会引起相应的误会. ...

  4. Qt核心剖析: moc

    前面我们说过,Qt 不是使用的“标准的” C++ 语言,而是对其进行了一定程度的“扩展”.这里我们从Qt新增加的关键字就可以看出来:signals.slots 或者 emit.所以有人会觉得 Qt 的 ...

  5. Qt编写控件属性设计器1-加载插件

    一.前言 加载插件是整个属性设计器的第一步要打通的功能,插件中的控件都加载不了,后面就别搞别玩下去了没法玩的,要从一个动态库中加载出来控件,肯定需要用到反射机制,以前做.NET开发的时候就觉得反射这个 ...

  6. 《InsideUE4》UObject(二)类型系统概述

    曾子曰:吾日三省吾身--为人谋而不忠乎?与朋友交而不信乎?传不习乎? 引言 上一篇我们谈到了在游戏引擎,或者在程序和高级编程语言中,设计一个统一对象模型得到的好处,和要付出的代价,以及在UE里是怎么对 ...

  7. qmake和moc的功能(★firecat推荐★)

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://devbean.blog.51cto.com/448512/355100 前面我们 ...

  8. QObject 源代码阅读

    我们进入 qt/src 文件夹.你可能对这里的目录名时曾相识,因为几乎这里的所有文件夹名都对应着 Qt 的模块的名字:gui,network,multimedia等等.我们从最核心的 QtCore 开 ...

  9. Qt根据类名创建对象(元对象反射)

    在java语言中,可以使用getObject(String)函数,从类名直接构建新的对象. 而在C++中是没有这种机制的,Qt虽然提供了元对象机制,但只可以获取对象的类名,不能反向构建. 这个问题我在 ...

随机推荐

  1. 【错误】Publishing to Tomcat'has encountered a problem

    tomcat 启动工程时候出现 Publishing to Tomcat'has encountered a problem错误 解决方案 之后重启tomcat 就可以正常启动了

  2. HDU-3810 超大容量01背包

    题意:有n堆野兽,每堆野兽屠杀完完需要花费ti时间,可以增加金钱gi,敌法师有瞬移技能,可以从某堆野兽移到另一堆野兽,题目有给定从哪堆可以移到哪堆.最后问在满足打的金钱多余m的情况下的最少时间.数据范 ...

  3. cmd获取管理员权限等

    鼠标点点点的略过 可输入命令 runas /user:Administrator cmd 或 runas /noprofile /user:Administrator cmd Administrato ...

  4. 传统IO拷贝与零拷贝技术比较

    1. 传统IO 由上面图知,传统io需要经过4次copy, 3次状态切换 第一次: 从硬盘 经过 DMA 拷贝 到 kernel buffer (内核buferr) 第二次: 从kernel buff ...

  5. CSS中的背景用法详解

    background 属性是CSS中用于设置元素背景的属性,最简单的background属 性名,是针对背景若干设定的合并简写,最早的CSS只能使用单一背景图片,而在现在却可以设置多个背景图片.而不用 ...

  6. php strpos()函数 语法

    php strpos()函数 语法 作用:寻找字符串中某字符最先出现的位置.大理石平台怎么选择 语法:strpos(string,find,start) 参数: 参数 描述 string     必需 ...

  7. 20180705-Java对象和类

    Java对象和类 Java作为一种面向对象语言.支持以下基本概念: 多态继承封装抽象类对象实例方法消息解析 本节我们重点研究对象和类的概念. 对象:对象是类的一个实例,有状态和行为.例如,一条狗是一个 ...

  8. [CSP-S模拟测试]:折纸(模拟)

    题目描述 小$s$很喜欢折纸.有一天,他得到了一条很长的纸带,他把它从左向右均匀划分为$N$个单位长度,并且在每份的边界处分别标上数字$0\sim n$.然后小$s$开始无聊的折纸,每次他都会选择一个 ...

  9. xiugai完了

    <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Conten ...

  10. 常用的Android关键词定位方法

    1字符串,特征字 根据程序运行中出现的特征字词进行搜索,从而获取定位到程序的相关位置之中.以前用 得比较多,不过现在一般难以找到想要的关键词.有时候需要对特征字进行拆分来进行搜索.才 能获得一点提示. ...