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();
}

最新文章

  1. centos上如何安装redis?|centos傻瓜式安装redis教程
  2. Math Start!
  3. mysql与oracle的存储过程有什么区别?
  4. 图文安装Windows Template Library - WTL Version 9.0
  5. StrictMode对SharedPreferences的检查出来的IO操作
  6. QStringLiteral(源代码里有一个通过构造函数产生的从const char*到QString的隐式转换,QStringLiteral字符串可以放在代码的任何地方,编译期直接生成utf16字符串,速度很快,体积变大)
  7. 0-1背包的动态规划算法,部分背包的贪心算法和DP算法------算法导论
  8. 简单的android启动跳转页面
  9. CH#46 磁力块 分块
  10. Hash table: why size should be prime?
  11. FileNotFoundError: [Errno 2] No such file or directory的解决方法
  12. [LeetCode&amp;Python] Problem 771: Jewels and Stones
  13. Ubuntu系统常见问题解决
  14. 64位平台C/C++开发注意事项
  15. [Windows] 解决 COM Surrogate 错误提示
  16. 20145118《Java程序设计》 第9周学习总结
  17. iterator_教程中的讲解
  18. Centos7 安装 MySQL5.7
  19. 解决QT出现XXXX.dll不能加载问题
  20. cookie属性和作用

热门文章

  1. C# List&lt;object&gt; 按特定字段排序
  2. linux系统安装telnet服务
  3. 1146. Topological Order (25)
  4. spring+mybatis+log4j 输出SQL
  5. ivew 限制输入 0 到 1 的数字 包括小数, 0 ,1
  6. mysql order by 自定义
  7. 对http的研究
  8. github上拉去代码执行 npm install报错code:128
  9. 【面试题】JavaScript
  10. MySQL:MySQL日期数据类型、MySQL时间类型使用总结