Qt 如何使用反射?
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 如何使用反射?的更多相关文章
- Qt and C++ Reflection,利用Qt简化C++的反射实现
如何在C++中实现反射机制,应该算是C++开发中经常遇到的问题之一.C++程序没有完整的元数据,也就无法实现原生的反射机制.从性能的角度讲,这样的设计不难理解,毕竟在运行时储存这些元数据需要额外的开销 ...
- Qt 反射
简介 本文主要讲解Qt是如何实现反射,以及一点点反射使用的小心得. 文章概览 Qt反射内幕小窥 详细内容 反射前期准备 得到注册的类成员变量 得到注册的类成员函数 访问类成员属性(get,set) 调 ...
- Qt信号槽连接在有默认形参下的情况思考
写下这个给自己备忘,比如函数 ) 你在调用端如论是test(3)或者test(),都可以正确调用到这个函数. 但是,如果放到Qt中的信号槽的话,这个还是值得讲一讲的,不然的话,可能会引起相应的误会. ...
- Qt核心剖析: moc
前面我们说过,Qt 不是使用的“标准的” C++ 语言,而是对其进行了一定程度的“扩展”.这里我们从Qt新增加的关键字就可以看出来:signals.slots 或者 emit.所以有人会觉得 Qt 的 ...
- Qt编写控件属性设计器1-加载插件
一.前言 加载插件是整个属性设计器的第一步要打通的功能,插件中的控件都加载不了,后面就别搞别玩下去了没法玩的,要从一个动态库中加载出来控件,肯定需要用到反射机制,以前做.NET开发的时候就觉得反射这个 ...
- 《InsideUE4》UObject(二)类型系统概述
曾子曰:吾日三省吾身--为人谋而不忠乎?与朋友交而不信乎?传不习乎? 引言 上一篇我们谈到了在游戏引擎,或者在程序和高级编程语言中,设计一个统一对象模型得到的好处,和要付出的代价,以及在UE里是怎么对 ...
- qmake和moc的功能(★firecat推荐★)
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://devbean.blog.51cto.com/448512/355100 前面我们 ...
- QObject 源代码阅读
我们进入 qt/src 文件夹.你可能对这里的目录名时曾相识,因为几乎这里的所有文件夹名都对应着 Qt 的模块的名字:gui,network,multimedia等等.我们从最核心的 QtCore 开 ...
- Qt根据类名创建对象(元对象反射)
在java语言中,可以使用getObject(String)函数,从类名直接构建新的对象. 而在C++中是没有这种机制的,Qt虽然提供了元对象机制,但只可以获取对象的类名,不能反向构建. 这个问题我在 ...
随机推荐
- 【错误】Publishing to Tomcat'has encountered a problem
tomcat 启动工程时候出现 Publishing to Tomcat'has encountered a problem错误 解决方案 之后重启tomcat 就可以正常启动了
- HDU-3810 超大容量01背包
题意:有n堆野兽,每堆野兽屠杀完完需要花费ti时间,可以增加金钱gi,敌法师有瞬移技能,可以从某堆野兽移到另一堆野兽,题目有给定从哪堆可以移到哪堆.最后问在满足打的金钱多余m的情况下的最少时间.数据范 ...
- cmd获取管理员权限等
鼠标点点点的略过 可输入命令 runas /user:Administrator cmd 或 runas /noprofile /user:Administrator cmd Administrato ...
- 传统IO拷贝与零拷贝技术比较
1. 传统IO 由上面图知,传统io需要经过4次copy, 3次状态切换 第一次: 从硬盘 经过 DMA 拷贝 到 kernel buffer (内核buferr) 第二次: 从kernel buff ...
- CSS中的背景用法详解
background 属性是CSS中用于设置元素背景的属性,最简单的background属 性名,是针对背景若干设定的合并简写,最早的CSS只能使用单一背景图片,而在现在却可以设置多个背景图片.而不用 ...
- php strpos()函数 语法
php strpos()函数 语法 作用:寻找字符串中某字符最先出现的位置.大理石平台怎么选择 语法:strpos(string,find,start) 参数: 参数 描述 string 必需 ...
- 20180705-Java对象和类
Java对象和类 Java作为一种面向对象语言.支持以下基本概念: 多态继承封装抽象类对象实例方法消息解析 本节我们重点研究对象和类的概念. 对象:对象是类的一个实例,有状态和行为.例如,一条狗是一个 ...
- [CSP-S模拟测试]:折纸(模拟)
题目描述 小$s$很喜欢折纸.有一天,他得到了一条很长的纸带,他把它从左向右均匀划分为$N$个单位长度,并且在每份的边界处分别标上数字$0\sim n$.然后小$s$开始无聊的折纸,每次他都会选择一个 ...
- xiugai完了
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Conten ...
- 常用的Android关键词定位方法
1字符串,特征字 根据程序运行中出现的特征字词进行搜索,从而获取定位到程序的相关位置之中.以前用 得比较多,不过现在一般难以找到想要的关键词.有时候需要对特征字进行拆分来进行搜索.才 能获得一点提示. ...