【Qt之QVariant】使用

news2024/11/24 12:26:02

介绍

QVariant类类似于最常见的Qt数据类型的联合。由于C++禁止联合类型包括具有非默认构造函数析构函数的类型,大多数有趣的Qt类不能在联合中使用。如果没有QVariant,则QObject::property()和数据库操作等将会受到影响。

QVariant对象同时持有一个单一类型(T)的单一值(一些类型是多值的,例如字符串列表)。您可以通过convert()将其转换为不同的类型T,使用其中一个toT()函数(例如toSize())获取其值,并使用canConvert()检查该类型是否可以转换为特定类型。

toT()(例如toInt()toString())命名的方法是const的。如果您请求存储的类型,则它们返回存储对象的副本。如果要求使用存储的类型生成的类型,则toT()会复制和转换并保留对象本身不变。如果要求一种无法从存储的类型生成的类型,则结果取决于该类型;有关详细信息,请参见函数文档。

以下是一些示例代码,演示了QVariant的用法:

QDataStream out(...);
QVariant v(123); // variant现在包含一个int
int x = v.toInt(); // x=123
out << v; // 在out中写入类型标记和一个int
v = QVariant("hello");// variant现在包含一个QByteArray
v = QVariant(tr("hello")); // variant现在包含一个QString
int y = v.toInt(); // y=0,因为v不能转换为int
QString s = v.toString(); // s=tr("hello")  (参见QObject::tr())
out << v; // 在out中写入类型标记和一个QString
...
QDataStream in(...); //(打开先前编写的流)
in >> v; //读取int变量
int z = v.toInt(); // z=123
qDebug("Type is %s",v.typeName()); // 打印“Type is int”
v = v.toInt()+100; // variant现在拥有值223
v = QVariant(QStringList());

您甚至可以将QList<QVariant>QMap<QString,QVariant>类型的值存储在variant中,因此您可以轻松构建任意类型的任意复杂度的数据结构。这非常强大和灵活,但可能比在标准数据结构中存储特定类型的方式低效。

QVariant还支持空值的概念,在该概念下,您可以拥有未设置值的定义类型。但是,请注意,只有在设置了值时,QVariant类型才能进行强制转换。

  QVariant x, y(QString()), z(QString(""));
  x.convert(QVariant::Int);
  // x.isNull() == true
  // y.isNull() == true, z.isNull() == false

QVariant可以扩展以支持Type枚举中未提到的其他类型。

关于GUI类型的说明

由于QVariantQt Core模块的一部分,因此它无法向Qt GUI中定义的数据类型(如QColorQImageQPixmap)提供转换函数。换句话说,没有toColor()函数。相反,您可以使用QVariant::value()qvariant_cast()模板函数。例如:

QVariant variant;
...
QColor color = variant.value<QColor>();

所有由QVariant支持的数据类型,包括与GUI相关的类型,都支持反向转换(例如,从QColorQVariant),这是自动的。

QColor color = palette().background().color();
QVariant variant = color;

连续使用canConvert()convert()

当连续使用canConvert()convert()时,canConvert()可能会返回true,但convert()会返回false。这通常是因为canConvert()仅报告了QVariant在给定适当数据的情况下转换类型的一般能力;仍然可能提供实际上无法转换的数据。

例如,当在包含字符串的variant上调用canConvert(Int)时,它将返回true,因为原则上,QVariant能够将数字字符串转换为整数。然而,如果字符串包含非数字字符,则无法将其转换为整数,任何尝试将其转换将失败。因此,两个函数都返回true对于成功的转换来说是很重要的。

成员函数

  1. QVariant:: QVariant() 构造一个无效的变量。
  2. QVariant:: QVariant(Type type) 构造一个空的类型为type的变量。
  3. QVariant:: QVariant(const QRegularExpression &re) 构造一个新的变量,带有正则表达式值re。该函数在Qt 5.0中引入。
  4. QVariant:: QVariant(const QUrl &val) 构造一个新的变量,值为val的url。
  5. QVariant:: QVariant(const QEasingCurve &val) 构造一个新的带有easing curve值val的变量。该函数在Qt 4.7中引入。
  6. QVariant:: QVariant(const QUuid &val) 构造一个值为uuid值val的新变量。该函数在Qt 5.0中引入。
  7. QVariant:: QVariant(const QModelIndex &val) 构造一个新的带有QModelIndex值val的变量。该函数在Qt 5.0中引入。
  8. QVariant:: QVariant(const QPersistentModelIndex &val) 构造一个新的带有QPersistentModelIndex值val的变量。该函数在Qt 5.5中引入。
  9. QVariant:: QVariant(const QJsonValue &val) 构造一个新的带有json值val的变量。该函数在Qt 5.0中引入。
  10. QVariant:: QVariant(const QJsonObject &val) 构造一个新的带有json对象值val的变量。该函数在Qt 5.0中引入。
  11. QVariant:: QVariant(const QJsonArray &val) 构造一个新的带有json数组值val的变量。该函数在Qt 5.0中引入。
  12. QVariant:: QVariant(const QJsonDocument &val) 构造一个新的带有json文档值val的变量。该函数在Qt 5.0中引入。
  13. QVariant:: QVariant(QVariant &&other) 移动构造一个QVariant实例,使其指向other指向的同一对象。该函数在Qt 5.2中引入。
  14. QVariant:: QVariant(int typeId, const void *copy) 构造类型为typeId的变量,并且如果copy不为0则初始化为copy。注意,您必须传递要存储的变量的地址。通常情况下,您不需要使用此构造函数,而是使用. QVariant:: fromValue() 来从由QMetaType::VoidStar和QMetaType::QObjectStar表示的指针类型构造变量。另请参见. QVariant:: fromValue() 和QMetaType::Type。
  15. QVariant:: QVariant(const QVariant &p) 构造一个变量的副本,该变量作为此构造函数的参数传递。
  16. QVariant:: QVariant(QDataStream &s) 从数据流s中读取变量。
  17. QVariant:: QVariant(int val) 构造一个带有整数值val的新变量。
  18. QVariant:: QVariant(uint val) 构造一个带有无符号整数值val的新变量。
  19. QVariant:: QVariant(qlonglong val) 构造一个带有长整型值val的新变量。
  20. QVariant:: QVariant(qulonglong val) 构造一个带有无符号长整型值val的新变量。
  21. QVariant:: QVariant(bool val) 构造一个带有布尔值val的新变量。
  22. QVariant:: QVariant(double val) 构造一个带有浮点值val的新变量。
  23. QVariant:: QVariant(float val) 构造一个带有浮点值val的新变量。该函数在Qt 4.6中引入。
  24. QVariant:: QVariant(const char *val) 构造一个带有val字符串值的新变量。该变量会将val创建为一个QString的深拷贝,并假定输入val的编码为UTF-8。请注意,val被转换为QString以便存储在变量中,. QVariant:: userType() 将为该变量返回QMetaType::QString。可以通过在编译应用程序时定义QT_NO_CAST_FROM_ASCII来禁用该操作符。
  25. QVariant:: QVariant(const QByteArray &val) 构造具有bytearray值val的新变量。
  26. QVariant:: QVariant(const QBitArray &val) 构造具有bitarray值val的新变量。
  27. QVariant:: QVariant(const QString &val) 构造一个具有字符串值val的新变量。
  28. QVariant:: QVariant(QLatin1String val) 构造一个具有字符串值val的新变量。
  29. QVariant:: QVariant(const QStringList &val) 构造一个具有字符串列表值val的新变量。
  30. QVariant:: QVariant(QChar c) 构造一个具有char值c的新变量。
  31. QVariant:: QVariant(const QDate &val) 构造一个具有日期值val的新变量。
  32. QVariant:: QVariant(const QTime &val) 构造一个具有时间值val的新变量。
  33. QVariant:: QVariant(const QDateTime &val) 构造一个具有日期/时间值val的新变量。
  34. QVariant:: QVariant(const QList<QVariant> &val) 构造一个具有列表值val的新变量。
  35. QVariant:: QVariant(const QMap<QString, QVariant> &val) 构造一个具有QVariant映射val的新变量。
  36. QVariant:: QVariant(const QHash<QString, QVariant> &val) 构造一个具有QVariant哈希val的新变量。
  37. QVariant:: QVariant(const QSize &val) 构造一个具有值为val的大小值的新变量。
  38. QVariant:: QVariant(const QSizeF &val) 构造一个具有值为val的大小值的新变量。
  39. QVariant:: QVariant(const QPoint &val) 构造一个具有代表点值val的新变量。
  40. QVariant:: QVariant(const QPointF &val) 构造一个具有代表点值val的新变量。
  41. QVariant:: QVariant(const QLine &val) 构造一个具有表示线值val的新变量。
  42. QVariant:: QVariant(const QLineF &val) 构造一个具有表示线值val的新变量。
  43. QVariant:: QVariant(const QRect &val) 构造一个具有表示矩形值val的新变量。
  44. QVariant:: QVariant(const QRectF &val) 构造一个具有表示矩形值val的新变量。
  45. QVariant:: QVariant(const QLocale &l) 构造一个具有本地值l的新变量。
  46. QVariant:: QVariant(const QRegExp &regExp) 构造一个新的正则表达式值regExp的变量。
  47. QVariant:: ~QVariant() 销毁QVariant和所包含的对象。
    请注意,重新实现清除的子类应重新实现析构函数以调用clear() 。这个析构函数调用clear() ,但因为它是析构函数,所以调用的是QVariant:: clear() ,而不是子类的clear()
  48. bool QVariant::canConvert(int targetTypeId) const:如果变量的类型可以转换为请求的类型targetTypeId,则返回true。在调用toInt()toBool()等方法时,会自动进行此类转换。 以下转换会自动完成:
    bool QVariant::canConvert(int targetTypeId) const
    如果变量的类型可以转换为请求的类型targetTypeId,则返回true。在调用toInt()、toBool()等方法时,会自动进行此类转换。
    以下转换会自动完成:
    在这里插入图片描述

如果QVariant包含指向QObject派生类型的指针,则如果可以进行与targetTypeId所描述的类型相对应的qobject_cast,则此函数也将返回true。请注意,这仅适用于使用Q_OBJECT宏的QObject子类。

如果QVariant包含一个顺序容器,则如果targetTypeId为QVariantList,则该函数也将返回true。可以在不将其提取为(复制的)QVariantList的情况下迭代容器的内容。

QList<int> intList = {7, 11, 42};

  QVariant variant = QVariant::fromValue(intList);
  if (variant.canConvert<QVariantList>()) {
      QSequentialIterable iterable = variant.value<QSequentialIterable>();
      // Can use foreach:
      foreach (const QVariant &v, iterable) {
          qDebug() << v;
      }
      // Can use C++11 range-for:
      for (const QVariant &v : iterable) {
          qDebug() << v;
      }
      // Can use iterators:
      QSequentialIterable::const_iterator it = iterable.begin();
      const QSequentialIterable::const_iterator end = iterable.end();
      for ( ; it != end; ++it) {
          qDebug() << *it;
      }
  }

结果:
在这里插入图片描述
这需要容器的value_type本身是一个元类型。类似地,如果QVariant包含一个顺序容器,则如果targetTypeId为QVariantHash或QVariantMap,则该函数也将返回true。可以在不将其提取为(复制的)QVariantHash或QVariantMap的情况下迭代容器的内容:

  QHash<int, QString> mapping;
  mapping.insert(7, "Seven");
  mapping.insert(11, "Eleven");
  mapping.insert(42, "Forty-two");

  QVariant variant = QVariant::fromValue(mapping);
  if (variant.canConvert<QVariantHash>()) {
      QAssociativeIterable iterable = variant.value<QAssociativeIterable>();
      // Can use foreach over the values:
      foreach (const QVariant &v, iterable) {
          qDebug() << v;
      }
      // Can use C++11 range-for over the values:
      for (const QVariant &v : iterable) {
          qDebug() << v;
      }
      // Can use iterators:
      QAssociativeIterable::const_iterator it = iterable.begin();
      const QAssociativeIterable::const_iterator end = iterable.end();
      for ( ; it != end; ++it) {
          qDebug() << *it; // The current value
          qDebug() << it.key();
          qDebug() << it.value();
      }
  }

结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1185696.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

View 自定义 - 路径 Path

参考文章 一、概念 用于描述顺序 & 区域&#xff0c;单使用无法产生效果。 图形绘制的本质是先画点再将点连接起来&#xff0c;所以点与点之间是存在一个先后顺序的。图形的方向影响的是&#xff1a;添加图形时确定闭合顺序(各个点的记录顺序)、图形的渲染结果(是判断图形…

ArcGIS进阶:水源涵养功能分级评价操作

首先抛出水源涵养重要性评价的公式&#xff1a;水源涵养量降雨量-蒸散发量-地表径流量&#xff0c;其中地表径流量降雨量*平均地表径流系数 声明&#xff1a;以下数据来源于来自于牛强老师书籍&#xff08;城乡规划GIS技术&#xff09;。 以下给出重要性评价阈值表&#xff1…

『MySQL快速上手』-⑥-表的约束

文章目录 1.空属性2.默认值3.列描述4.zerofill5.主键6.自增长7.唯一键8.外键9.综合案例 真正约束字段的是数据类型&#xff0c;但是数据类型约束很单一&#xff0c;需要有一些额外的约束&#xff0c;更好的保证数据的合法性&#xff0c;从业务逻辑角度保证数据的正确性。 1.空…

高校为什么需要企业数据库?

随着信息化数字化的发展&#xff0c;企业数据库已经成为高校不可或缺的一部分。企业数据库一般整合了多维度企业数据信息。比如&#xff0c;艾思依托丰富的数据沉淀和领先的模型算法&#xff0c;打造“1N”产业大数据平台&#xff0c;包含“1个企业数据中心”一一涵盖全国2.4亿…

计算机提示找不到concrt140.dll怎么办,分享4个有效的修复方法

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示或者系统崩溃的情况。其中&#xff0c;concrt140.dll是一个常见的错误提示&#xff0c;这个错误通常会导致某些应用程序无法正常运行。为了解决这个问题&#xff0c;我们需要采取一些修复措施。本文将介绍4个修复conc…

基于显著性的无人机多光谱图像语义杂草检测与分类

Saliency-Based Semantic Weeds Detection and Classification Using UAV Multispectral Imaging(2023&#xff09; 摘要1、介绍2、相关工作2.1 监督学习2.2 半监督学习2.3 无监督学习 3、方法3.1 贡献3.2 PC/BC-DIM NEURAL NETWORK&#xff08;预测编码/有偏竞争-分裂输入调制…

20个Python实用小技巧!来自十年老程序员的推荐~

文章目录 1.用itertools排列2.单行条件表达式3. 反转字符串4. 使用 Assert 处理异常5. 对多个输入使用拆分6. 用 zip() 转置矩阵7. 资源上下文管理器8. 下划线作为分隔符9. 尝试 f 字符串格式10.用这个技巧交换整数11. 使用 lambda 代替函数12.多次打印无循环13. 将字符串解包为…

基于机器学习的 ICU 脑血管疾病死亡风险智能预测系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 Wechat / QQ 名片 :) 1. 项目简介 重症患者或重大手术后的患者在重症监护室&#xff08;ICU&#xff09;内通过多种生命支持系统以维持生理功能。患者在ICU 内会被频繁持续的记录生命体征和实验室测量等多种数据。由于高频…

电大搜题——搜索难题

添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 广东开放大学是一所素有口碑的知名学府&#xff0c;一直致力于为广大学员提供优质的教育资源和学习支持。随着科技的不断发展&#xff0c;电子学习成为了现代学习的主要方式之一。为了更好地满足学员的学习…

Django(一、简介,安装与使用)

文章目录 一、Django引入1.web应用程序什么是web&#xff1f;web引用程序的优点web应用程序的缺点什么是web框架 2.纯手写web框架1.web框架的本质2.HTTP协议的特性&#xff1a;3.编写基于wsgire模块搭建web框架代码封装优化代码封装 二、Django框架的学习1.Python中的主流框架2…

Kubernetes实战(四)-部署docker harbor私有仓库

1 Docker原生私有仓库Registry 1.1 原生私有仓库Registry概述 Docker的仓库主要分两类&#xff1a; 私有仓库公有仓库 共有仓库只要在官方注册用户&#xff0c;登录即可使用。但对于仓库的使用&#xff0c;企业还是会有自己的专属镜像&#xff0c;所以私有库的搭建也是很有…

基于SSM的婚恋网站的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

前端常用的开发工具有哪些?

目录 内置管理系统的通用场景 前后端代码生成器 权限管控 开放源码 运行性能 主流数据库 写在最后 目前使用的是JNPF框架。 前端采用Vue.js&#xff0c;这是一种流行的前端JavaScript框架&#xff0c;用于构建用户界面。Vue.js具有轻量级、可扩展性强和生态系统丰富等特点&…

成集云 | 企业微信考试+活动抽奖小程序系统 | 解决方案

方案介绍 企业微信考试功能是一种基于企业微信平台的在线考试系统&#xff0c;可以帮助企业进行员工培训、考核、招聘等考试场景。 活动抽奖小程序系统是一种基于互联网技术的应用程序&#xff0c;旨在为用户提供便捷、公平的抽奖体验。它可以帮助商家或平台吸引用户关注和参…

Gorm 中的钩子和回调

一个全面的指南&#xff0c;利用 GORM 中的钩子和回调的力量&#xff0c;为定制的数据库工作流程 在数据库管理领域&#xff0c;定制化是打造高效和定制化工作流程的关键。GORM&#xff0c;这个充满活力的 Go 对象关系映射库&#xff0c;为开发人员提供了钩子和回调的功能&…

机器人伺服驱动控制环

伺服驱动器​的控制环&#xff0c;包括&#xff1a;位置环、速度环、电流环这三种类型。 对于伺服的控制回路&#xff0c;内侧控制环的响应带宽一般会是外侧控制环的5到10倍。也就是说&#xff0c;电流环带宽大致是速度环的5到10倍&#xff0c;速度环带宽则约为位置环的5到10倍…

K8S知识点(七)

&#xff08;1&#xff09;实战入门-Namespace kubernets&#xff1a;系统创建的资源在这个命名空间里 &#xff0c;集群组件资源 kubrnets组件也是以pod的形式运行的 命令行方式操作 查看namespace和详情&#xff1a; 创建和查看和删除&#xff1a; 使用过配置文件操作&am…

Docker 介绍

Docker 介绍 1 介绍1.1 概述1.2 资源高效利用1.3 发展历程1.4 组件1.5 工具1.6 对环境部署和虚拟化的影响1.7 优点1.8 容器技术核心CgroupNamespaceUnionFS 2 命令信息、状态、配置info命令用于显示当前系统信息、docker容器、镜像个数、设置等信息 镜像容器资源 3 安装3.1 版本…

flashAttention是什么

flashAttention是一种attention加速计算的精确算法&#xff0c;它的核心有三点&#xff1a;tiling&#xff08;分块计算&#xff09;&#xff0c;kernel合并&#xff0c;和重计算。

03运算符综合

03 3.1.1算数运算符 3.1.2赋值运算符 3.1.3比较&#xff08;关系&#xff09;运算符 3.1.4逻辑运算符 3.1.5位运算符 3.2运算符的优先级 3.3条件表达式