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. pgtclsh -- PostgreSQL TCLshell 客户端

    SYNOPSIS pgtclsh [filename [argument...]] DESCRIPTION 描述 pgtclsh 是一个 Tcl shell 接口,用 PostgreSQL 数据库访问 ...

  2. MYSQL学习笔记——数据库范式及MYSQL优化整体思路

    一.数据库范式                                                                               为了建立冗余较小.结构合理的 ...

  3. java selenium常用API汇总

    (WebElement.iFrame.select.alert.浏览器窗口.事件.js)     一 WebElement相关方法 1.点击操作 WebElement button = driver. ...

  4. python数据分析第二版:pandas

    一:pandas 两种数据结构:series和dataframe series:索引(索引自动生成)和标签(人为定义)组成---返回一个对象 obj = pd.Series([1,2,3,4]) ob ...

  5. 共享OrCAD9.2pSpice9.2+multisim下载地址

    http://pan.baidu.com/s/1dDcfiH7ewb9绿色版,解压后即可用!http://pan.baidu.com/s/1kTG43WFMultisim v11绿色版.7zhttp: ...

  6. Python---基础---dict和set2

    2019-05-21 写一个程序来管理用户登陆系统的用户信息:登陆名字和密码,登陆用户账号建立后,已存在用户可以用登陆名字和密码重返系统,新用户不能用别人的用户名建立用户账号 ------------ ...

  7. nyoj 119: 士兵杀敌(三) 【RMQ模板】

    题目链接 贴个板子.. #include<bits/stdc++.h> using namespace std; int n,q; ],d1[][],d2[][]; void RMQ_in ...

  8. 028:with标签使用详解

    with标签使用详解: 1.在模板中享用使用变量,可以通过  with  语句实现: 2.with  有两种用法,具体情况如下 ( 包括注意事项 ) : index.html: <p>wi ...

  9. Jenkins镜像

    https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json

  10. python 生成多维数组

    在刷题时用到了数组,因为不提供三方库所以不能使用Numpy.想如何通过python列表模拟数组. 第一种方法 """ 生成n*m的初始值为0的矩阵 "" ...