自定义类型与Qt元对象系统
个人发现一篇关于在Qt中使用元对象系统支持自定义类型的好博文,记录下防止丢失(如有侵权,烦请告知删除)。博文原地址:http://qtdebug.com/qtbook-misc-qvariant/
QVariant 非常重要,可以存储很多种不同的类型,例如 int, QString, QRect, QPoint 等,其构造函数有很多个,参数是很多种不同的常用类型,还内置了可以直接转换 QVaraint 到某些类型的函数,如 toInt(), toString(), toPoint(), toSize() 等,还是 QObject 动态 property 机制的关键,除了支持内置的类型外,QVariant 还被设计成可以存储我们自己定义的类型。
关键术语:
- Q_DECLARE_METATYPE
- qRegisterMetaType
- qRegisterMetaTypeStreamOperators
- operator QVariant()
自定义类型和 QVariant 互相转换
想要能够使得自定义类型的对象和 QVariant 能够互相转换,自定义类型需要在类声明的头文件中使用宏 Q_DECLARE_METATYPE() 声明一下,告知 Qt 的 Meta System:
- 使用
QVariant::fromValue(customClassObject)
把自定义类型的对象转换为 QVariant 对象 - 使用
variantObject.value<CustomClass>()
把 QVariant 对象转换为自定义类型的对象
Adding a Q_DECLARE_METATYPE() makes the type known to all template based functions, including QVariant.
下面使用自定义类 User 和 QVaraint 互转为例
1 |
// 文件名: User.h |
1 |
// 文件名: User.cpp |
1 |
// 文件名: main.cpp |
信号槽中使用自定义类型
如果 connect 的类型是 Qt::DirectConnection,也就是同一个线程中使用,那么不需要做什么,自定义类型的对象可以直接在信号槽中作为参数,但是如果 connect 的类型是 Qt::QueuedConnection,自定义类型除了使用宏 Q_DECLARE_METATYPE() 声明外,还必须调用 qRegisterMetaType 注册后才可以:
1 |
qRegisterMetaType<User>(); // 注意: qRegisterMetaType 是函数,不是宏 |
Adding a Q_DECLARE_METATYPE() makes the type known to all template based functions, including QVariant. Note that if you intend to use the type in queued signal and slot connections or in QObject’s property system, you also have to call qRegisterMetaType() since the names are resolved at runtime.
To use the type T in QVariant, using Q_DECLARE_METATYPE() is sufficient. To use the type T in queued signal and slot connections, qRegisterMetaType() must be called before the first connection is established.
Also, to use type T with the QObject::property() API, qRegisterMetaType() must be called before it is used, typically in the constructor of the class that uses T, or in the main() function.
QObject property 中使用自定义类型
*QObject::setProperty(const char name, const QVariant &value) 可以动态地存储数据,这样我们就不需要为了保存数据而定义很多变量了,使用 *QObject::property(const char name) 就能够取得存储的数据,是不是非常方便!
为了让 QObject 的 property 支持自定义类型的对象,自定义的类需要实现运算符 **QVariant()**,如下 User 的实现:
1 |
// 文件名: User.h |
1 |
// 文件名: User.cpp |
1 |
// 文件名: main.cpp |
QDataStream 序列化自定义类型的 QVariant
自定义类型的对象转换为 QVaraint 对象后,如果要使用 QDataStream 操作这个 varaint 的话,需要:
- 自定义类型实现 QDataStream& operator<<(QDataStream &stream, const CustomClass &obj)
- 自定义类型实现 QDataStream& operator>>(QDataStream &stream, CustomClass &obj)
- 使用 qRegisterMetaTypeStreamOperators 进行注册
任然以 User 为例:
1 |
// 文件名: User.h |
1 |
// 文件名: User.cpp |
1 |
// 文件名: main.cpp |
自定义类型与Qt元对象系统的更多相关文章
- Qt 元对象系统(Meta-Object System)(不管是否使用信号槽,都推荐使用)
Qt 元对象系统(Meta-Object System) Qt的元对象系统基于如下三件事情: 类:QObject,为所有需要利用原对象系统的对象提供了一个基类. 宏:Q_OBJECT,通常可以声明在类 ...
- 解析Qt元对象系统(五) Q_INVOKABLE与invokeMethod(automatic connection从Qt4.8开始的解释已经与之前不同,发送对象驻足于哪一个线程并不重要,起到决定作用的是接收者对象所驻足的线程以及发射信号(该信号与接受者连接)的线程是不是在同一个线程)good
概述查看Qt源码可知,Q_INVOKABLE是个空宏,目的在于让moc识别. 使用Q_INVOKABLE来修饰成员函数,目的在于被修饰的成员函数能够被元对象系统所唤起. Q_INVOKABLE与QMe ...
- Qt元对象系统简介
在Qt中提供了c++的扩展,提供了一种元对象系统的机制,(meta-object-system)的机制.其中包含了信号与槽的内部机制,能够访问到QObject子类的元对象信息的功能. Q_OBJECT ...
- Qt 元对象系统(Meta-Object System)
(转自:http://blog.csdn.net/aladdina/article/details/5496891) Qt的元对象系统基于如下三件事情: 类:QObject,为所有需要利用原对象系统的 ...
- 解析Qt元对象系统(四) 属性系统(确实比较方便)
官方解释 我们在Qt源码中可以看到一个QObject的子类经常会用到一些Q_开头的宏,例如QMainWindow类开始部分代码是这样的: Q_PROPERTY(QSize iconSize READ ...
- qt 元对象系统
元对象系统 Qt中的元对象系统是用来处理对象间通讯的信号/槽机制.运行时的类型信息和 动态属性系统. 它基于下列三类: QObject类: 类声明中的私有段中的Q_OBJECT宏: 元对象编译器(mo ...
- Qt笔记——元对象系统
Qt元对象系统提供了对象间的通信机制:信号和槽.以及执行类形信息和动态属性系统的支持.是标注C++的一个扩展,它使得Qt可以更好的实现GUI图形用户界面编程.Qt的元对象系统不支持C++模板.虽然模板 ...
- 深入了解Qt(二)之元对象系统(Meta-Object System)
深入了解Qt主要内容来源于Inside Qt系列,本文做了部分删改,以便于理解.在此向原作者表示感谢! 在Qt Meta Object System-元对象系统这篇文章中,从底层实现的源码剖析了元对象 ...
- Qt元对象(Meta-Object)系统与反射
反射 -在计算机科学中,反射是指计算机程序在运行时(Run time)可以访问.检测和修改它本身状态或行为的一种能力.[1]用比喻来说,反射就是程序在运行的时候能够“观察”并且修改自己的行为. 要注意 ...
- Qt对象模型之二:对象树与元对象系统
一.对象树的概念 Qt中使用对象树(object tree)来组织和管理所有的QObject类及其子类的对象.当创建一个QObject时,如果使用了其他的对象作为其父对象(parent),那么这个 Q ...
随机推荐
- Day13 字符串的常用方法
API帮助文档的使用流程 在索引的位置搜索自己要查看的类 看包 目的:是不是 Java.lang包(核心包),不需要编写导包代码(import) -------不是 java.lang包,都需要编写导 ...
- Loading Methods
Datasets datasets.list_datasets return:List all the datasets scripts available on the Hugging Face H ...
- 人脸识别:face_recognition初尝试
在学习face_recognition之前先看git上的另一个项目:face_collection .face_collection某种程度上可以看做是demo,便于我们更好的理解和使用face_re ...
- Docker部署Minio文件系统
MinIO 是在 GNU Affero 通用公共许可证 v3.0 下发布的高性能对象存储. 它是与 Amazon S3 云存储服务兼容的 API. 使用 MinIO 为机器学习.分析和应用程序数据工作 ...
- C# 三层架构 简单清晰讲解
https://www.cnblogs.com/smbk/p/5339610.html
- 【面试】TCP-IP经典
整理之前的笔记,发现网络通信通俗易懂的解释. 搞清这15个问题,那你就精通了TCP! 网络协议那么多, 为什么面试喜欢问TCP? 原因无外乎两个: TCP协议直接与进程打交道,写网络程序要用: TCP ...
- Delphi模拟win+tab按键效果
//按下左侧win键 keybd_event(VK_LWIN,0,0,0); //按下tab键 keybd_event(VK_TAB,0,0,0); //抬起左侧win键 keybd_event(VK ...
- hdu 1516 String Distance and Transform Process
Problem DescriptionString Distance is a non-negative integer that measures the distance between two ...
- B - Yet Another Palindrome Problem
B - Yet Another Palindrome Problem 思路: 给一个长为n(≤5000≤5000)的数组,问是否存在一个长度至少为3的子序列是回文的.回文的定义是把序列reverse, ...
- idea远程连接云服务器,并将本地代码部署在云端进行运算
电脑内存和显存过小,需要在云服务器进行运算我的模型,由于一直在自己的电脑上写的代码,于是之间迁移代码到云服务器,只要通过ssh链接到云端后,将python解释器使用云端的解释器就ok 从 file-- ...