Qt自定义类型
概述
在使用Qt创建用户界面时,特别是那些具有特殊控件和特性的界面时,开发人员有时需要创建新的数据类型,以便与Qt现有的值类型集一起使用或代替它们。
QSize、QColor和QString等标准类型都可以存储在QVariant对象中,作为基于qobject的类的属性类型,并在信号槽通信中发出。
在本文中,我们将使用一个自定义类型,并描述如何将其集成到Qt的对象模型中,以便它能够以与标准Qt类型相同的方式存储。然后,我们将展示如何注册自定义类型以允许它在信号和插槽连接中使用。
创建自定义类型
在开始之前,我们需要确保创建的自定义类型满足QMetaType的所有要求。换句话说,它必须提供:
- 一个公共的默认构造函数,
- 一个公共复制构造函数,以及
- 一个公共析构函数。
下面的Message类定义包含了这些成员:
class Message
{
public:Message() = default;~Message() = default;Message(const Message &) = default;Message &operator=(const Message &) = default;Message(const QString &body, const QStringList &headers);QString body() const;QStringList headers() const;private:QString m_body;QStringList m_headers;
};
这个类还提供了一个普通使用的构造函数,以及两个用于获取私有数据的公共成员函数。
用QMetaType声明类型
Message类只需要适当的实现就可以使用。然而,Qt的类型系统将无法理解如何存储,检索和序列化这个类的实例,如果没有一些帮助。例如,我们将无法在QVariant中存储消息值。
Qt中负责自定义类型的类是QMetaType。为了让这个类知道类型,我们在定义类的头文件中调用Q_DECLARE_METATYPE()宏:
Q_DECLARE_METATYPE(Message);
这使得将消息值存储在QVariant对象中并在以后检索成为可能。有关演示这一点的代码,请参阅自定义类型示例。
Q_DECLARE_METATYPE()宏也可以将这些值用作信号的参数,但只能在直接的信号槽连接中使用。为了使自定义类型通常可用于信号和插槽机制,我们需要执行一些额外的工作。
创建和销毁自定义对象
虽然前一节中的声明使该类型可用于直接的信号槽连接,但不能用于排队的信号槽连接,例如不同线程中的对象之间的连接。这是因为元对象系统不知道如何在运行时处理自定义类型对象的创建和销毁。
要在运行时创建对象,请调用qRegisterMetaType()模板函数将其注册到元对象系统。这也使得该类型可用于排队信号槽通信,只要您在创建第一个使用该类型的连接之前调用它。
排队的自定义类型示例声明了一个注册在main.cpp文件中的块类:
int main(int argc, char *argv[])
{QApplication app(argc, argv);...qRegisterMetaType<Block>();...return app.exec();
}
此类型稍后在window.cpp文件中的信号槽连接中使用:
Window::Window(QWidget *parent): QWidget(parent), thread(new RenderThread(this))
{...connect(thread, &RenderThread::sendBlock,this, &Window::addBlock);...setWindowTitle(tr("Queued Custom Type"));
}
如果在未注册的情况下在排队连接中使用了类型,则将在控制台中打印警告;例如:
QObject::connect: Cannot queue arguments of type 'Block'
(Make sure 'Block' is registered using qRegisterMetaType().)
使类型可打印
使自定义类型可打印用于调试通常是非常有用的,如下面的代码所示:
Message message(body, headers);qDebug() << "Original:" << message;
这可以通过为该类型创建一个流操作符来实现,该操作符通常在该类型的头文件中定义:
QDebug operator<<(QDebug dbg, const Message &message);
自定义类型示例中Message类型的实现做了一些努力,使可打印的表示尽可能可读:
QDebug operator<<(QDebug dbg, const Message &message)
{const QString body = message.body();QVector<QStringRef> pieces = body.splitRef(QLatin1String("\r\n"), Qt::SkipEmptyParts);if (pieces.isEmpty())dbg.nospace() << "Message()";else if (pieces.size() == 1)dbg.nospace() << "Message(" << pieces.first() << ")";elsedbg.nospace() << "Message(" << pieces.first() << " ...)";return dbg.maybeSpace();
}
当然,发送到调试流的输出可以按照您的喜好设置为简单或复杂。请注意,该函数返回的值是QDebug对象本身,尽管这通常是通过调用QDebug的maybeSpace()成员函数获得的,该函数用空格字符填充流,使其更具可读性。
Creating Custom Qt Types | Qt Core 5.15.17
相关文章:
Qt自定义类型
概述 在使用Qt创建用户界面时,特别是那些具有特殊控件和特性的界面时,开发人员有时需要创建新的数据类型,以便与Qt现有的值类型集一起使用或代替它们。 QSize、QColor和QString等标准类型都可以存储在QVariant对象中,作为基于qo…...
UE4_材质_材质节点_DepthFade
一、DepthFade参数 DepthFade(深度消退)表达式用来隐藏半透明对象与不透明对象相交时出现的不美观接缝。 项目说明属性消退距离(Fade Distance)这是应该发生消退的全局空间距离。未连接 FadeDistance(FadeDistance&a…...
如何对GD32 MCU进行加密?
GD32 MCU有哪些加密方法呢?大家在平时项目开发的过程中,最后都可能会面临如何对出厂产品的MCU代码进行加密,避免产品流向市场被别人读取复制。 下面为大家介绍GD32 MCU所支持的几种常用的加密方法: 首先GD32 MCU本身支持防硬开盖…...
快速了解GPT-4o和GPT-4区别
GPT-4o简介 在5月14日的OpenAI举行春季发布会上,OpenAI在活动中发布了新旗舰模型“GPT-4o”!据OpenAI首席技术官穆里穆拉蒂(Muri Murati)介绍,GPT-4o在继承GPT-4强大智能的同时,进一步提升了文本、图像及语…...
周末休息日也能及时回应客户消息!微信自动回复神器太就好用啦!
无论是在忙碌时,还是在周末休息日,如果没能及时回应客户,很可能会造成客户流失。 今天,我要为大家介绍一个多微管理神器——个微管理系统,它可以帮助你实现自动回复,提高回复效率。 自动通过好友请求 在…...
力扣404周赛 T1/T2/T3 枚举/动态规划/数组/模拟
博客主页:誓则盟约系列专栏:IT竞赛 专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ 3200.三角形的最大高度【简单】 题目: 给你两个整数 red 和 b…...
Taurus 性能测试工具详解
文章目录 简介原理安装编写测试配置运行测试集成其他工具结果分析优点与缺点优点缺点 参考资料总结 简介 Taurus 是一个开源的自动化测试工具,用于简化和增强性能测试流程。与其他性能测试工具不同,Taurus 旨在通过友好的 YAML 配置文件和对多种负载测试…...
天猫商品详情API接口(店铺|标题|主图|价格|SKU属性等)
天猫商品详情API接口为开发者提供了获取天猫商品详细信息的能力,包括店铺信息、商品标题、主图、价格、SKU属性等。以下是该接口的使用过程和相关技术要点: 注册账号并创建应用 注册账号:需要在天猫开放平台注册一个开发者账号。创建应用&a…...
双向广搜——AcWing 190. 字串变换
双向广搜 定义 双向广度优先搜索(Bi-directional Breadth-First Search, Bi-BFS)是一种在图或树中寻找两点间最短路径的算法。与传统的单向广度优先搜索相比,它从起始点和目标点同时开始搜索,从而有可能显著减少搜索空间&#x…...
工商业光伏项目如何快速开发?
一、前期调研与规划 1、屋顶资源评估:详细测量屋顶面积、承重能力及朝向,利用光伏业务管理软件进行日照分析和发电量预测,确保项目可行性。 2、政策与补贴研究:深入了解当地政府对工商业光伏项目的政策支持和补贴情况࿰…...
Kafka入门-分区及压缩
一、生产者消息分区 Kafka的消息组织方式实际上是三级结构:主题-分区-消息。主题下的每条消息只会保存在某一个分区中,而不会在多个分区中被保存多份。 分区的作用就是提供负载均衡的能力,或者说对数据进行分区的主要原因,就是为…...
被⽹络罪犯利⽤的5⼤ChatGPT越狱提⽰
⾃ChatGPT发布的近18个月以来,⽹络罪犯们已经能够利⽤⽣成式AI进⾏攻击。OpenAI在其内容政策中制定了限制措施,以阻⽌⽣成恶意内容。作为回应,攻击者们创建了⾃⼰的⽣成式AI平台,如 WormGPT和FraudGPT,并且他们还分享了…...
AVR晶体管测试仪开源制作与验证
AVR晶体管测试仪开源制作与验证 📍原项目地址:https://www.mikrocontroller.net/articles/AVR_Transistortester github地址:https://github.com/Mikrocontroller-net/transistortester 🎈EasyEDA项目地址:https://osh…...
头条系统-05-延迟队列精准发布文章-概述添加任务(db和redis实现延迟任务)、取消拉取任务定时刷新(redis管道、分布式锁setNx)...
文章目录 延迟任务精准发布文章 1)文章定时发布2)延迟任务概述 2.1)什么是延迟任务2.2)技术对比 2.2.1)DelayQueue2.2.2)RabbitMQ实现延迟任务2.2.3)redis实现 3)redis实现延迟任务4)延迟任务服务实现 4.1)搭建heima-leadnews-schedule模块4.2)数据库准备4.3)安装redis4.4)项目…...
不同系统间数据交换要通过 api 不能直接数据库访问
很多大数据开发提供数据给外部系统直接给表结构,这是不好的方式。在不同系统间进行数据交换时,通过API(应用程序编程接口)而非直接访问数据库是现代系统集成的一种最佳实践。 目录 为什么要通过API进行数据交换如何通过API进行数据…...
深度探索“目录名称无效“:原因、解决方案与最佳实践
目录名称无效:现象背后的秘密 在日常使用电脑或移动设备时,我们时常会遇到“目录名称无效”的错误提示,这一提示仿佛是一道无形的屏障,阻断了我们与重要数据的联系。从本质上讲,“目录名称无效”意味着系统无法识别或…...
open3d基础使用-简单易懂
Open3D是一个开源库,主要用于快速开发处理3D数据的软件。它提供了丰富的数据结构和算法,支持点云、网格和RGB-D图像等多种3D数据的处理。以下是对Open3D基础使用的详细归纳和说明: 一、安装Open3D Open3D可以通过Python的包管理器pip进行安…...
【前端】HTML+CSS复习记录【5】
文章目录 前言一、padding、margin、border(边框边距)二、样式优先级三、var(使用 CSS 变量更改多个元素样式)四、media quary(媒体查询)系列文章目录 前言 长时间未使用HTML编程,前端知识感觉…...
三分钟看懂SMD封装与COB封装的差异
全彩LED显示屏领域中,COB封装于SMD封装是比较常见的两种封装方式,SMD封装产品主要有常规小间距以及室内、户外型产品,COB封装产品主要集中在小间距以及微间距系列产品中,今天跟随COB显示屏厂家中品瑞一起快速看懂SMD封装与COB封装…...
深入理解策略梯度算法
策略梯度(Policy Gradient)算法是强化学习中的一种重要方法,通过优化策略以获得最大回报。本文将详细介绍策略梯度算法的基本原理,推导其数学公式,并提供具体的例子来指导其实现。 策略梯度算法的基本概念 在强化学习…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
