【Qt之QVariant】使用

介绍

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于单片机的多层电梯控制仿真系统

**单片机设计介绍&#xff0c; 基于单片机的多层电梯控制仿真系统 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的多层电梯控制仿真系统是一个复杂的系统&#xff0c;它需要结合单片机技术、控制理论、电子技术以及人…

使用swagger-typescript-api

引言 前后端分离大致是这样的 后端&#xff1a;控制层 / 业务层 / 数据操作层前端&#xff1a;控制层 / 视图层 前后端的控制层&#xff0c;实际上就是前后端接口的对接 前后端分离&#xff0c;实现了更好地解耦合&#xff0c;但也引入了接口对接的过程&#xff0c;这个过程…

C++ STL - map 与 multimap用法和区别

目录 一、概述 二、用法 2.1、插入 2.2、拷贝与赋值 2.3、查找 2.4、删除 2.5、完整代码 三、其他成员类型 一、概述 map 与 multimap是存储key-value&#xff08;键-值 对&#xff09;类型的容器。不同之处在于&#xff1a;map只允许key与 value一一对应&#xff1b;…

asp.net core mvc之路由

一、默认路由 &#xff08;Startup.cs文件&#xff09; routes.MapRoute(name: "default",template: "{controllerHome}/{actionIndex}/{id?}" ); 默认访问可以匹配到 https://localhost:44302/home/index/1 https://localhost:44302/home/index https:…

PTL货位指引标签为仓储管理打开新思路

PTL货位指引标签是一种新型的仓储管理技术&#xff0c;它通过LED灯光指引和数字显示&#xff0c;为仓库管理带来了全新的管理思路和效率提升&#xff0c;成为现代物流仓库管理中的重要工具。 首先&#xff0c;PTL货位指引标签为仓储管理业务带来了管理新思路。传统的仓库管理中…

OFDM深入学习及MATLAB仿真

文章目录 前言一、OFDM 基本原理及概念1、OFDM 简介2、子载波3、符号4、子载波间隔与符号长度之间的关系 二、涉及的技术1、保护间隔2、交织3、信道编码4、扩频5、导频6、RF&#xff08;射频&#xff09;调制7、信道估计 三、变量间的关系四、IEEE 802.11a WLAN PHY 层标准五、…

matlab中的mapminmax函数初步理解和应用

matlab中的mapminmax函数初步认识 一、mapminmax 顾名思义&#xff1a;映射最大最小 二、语法及举例 2.1 语法1 [Y,PS] mapminmax(X) 将矩阵X映射形成矩阵Y, Y中每行中的最小值对应-1&#xff0c;最大值对应1。PS是一个包含映射信息的结构体。 举例&#xff1a; clc cle…

Jupyter Notebook 闪退

造成这个的原因非常非常多&#xff01; 比如什么环境变量没有配置&#xff0c;或者说jupyter和python版本不兼容&#xff0c;库不兼容等等。 但是我呢&#xff0c;以上都不是。 我是因为手残&#xff0c;删掉了不该删的文件&#xff1a; 这个操作就是打开"Anaconda Prom…

在react中组件间过渡动画如何实现?

一、是什么 在日常开发中&#xff0c;页面切换时的转场动画是比较基础的一个场景 当一个组件在显示与消失过程中存在过渡动画&#xff0c;可以很好的增加用户的体验 在react中实现过渡动画效果会有很多种选择&#xff0c;如react-transition-group&#xff0c;react-motion&…

Vb6 TCP Server服务端监听多个RFID读卡器客户端上传的刷卡数据

本示例使用设备介绍&#xff1a;WIFI无线4G网络RFID云读卡器远程网络开关物流网阅读器TTS语音-淘宝网 (taobao.com) Option ExplicitConst BUSY As Boolean False 定义常量 Const FREE As Boolean TrueDim ConnectState() As Boolean 定义连接状态 Dim ServerSendbuf(…

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

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

数字化广告运营,小迈科技的关键一步

数据驱动广告运营是小迈科技提升整体经营效率、构建竞争优势的重要选择。 截止目前&#xff0c;小迈科技已经完成了数据驱动的广告运营体系的搭建&#xff0c;并通过与神策数据的深入合作&#xff0c;借力神策客户旅程分析平台&#xff0c;在广告投放、运营活动等各个环节实现了…

网络安全从业者用于学习和了解可以访问的顶级黑客论坛

黑客论坛目前已经成为了网络犯罪者的数字聚集地。在这些论坛上我们可以看见最新的数据泄露事件,软件的漏洞,以及黑客教程。下面我将向大家分享目前还可以访问的顶级黑客论坛,网络安全从业者用于学习和了解。 1.XSS.is(俄罗斯黑客论坛) 推出时间:2013年,2018年9月重新推出…

Jdk 1.8 for mac 详细安装教程(含版本切换)

Jdk 1.8 for mac 详细安装教程&#xff08;含版本切换&#xff09; 官网下载链接 https://www.oracle.com/cn/java/technologies/downloads/#java8-mac 一、选择我们需要安装的jdk版本&#xff0c;这里以jdk8为例&#xff0c;下载 macOS 版本&#xff0c;M芯片下载ARM64版本…

centos7安装docker容器

卸载老版本&#xff1a; $ sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine/var/lib/docker/路径下存在镜像、数据卷、容器等&#xff0c;在卸载的时候是不会自动删除…

不同规模的企业如何借助宁盾LDAP统一用户认证实现安全和效率需求?

中小企业要解决安全和业务效率问题&#xff0c;须提前规划软件基础设施&#xff0c;其中最基础的部分是建立统一账号和统一用户身份认证体系。这个体系相当于在软件系统之间建立了一套统一的身份标准&#xff0c;基于这套标准创建的账号让员工方便、高效地访问公司内的大部分软…

【解密ChatGPT】:从过去到未来,揭示其发展与变革

&#x1f38a;专栏【ChatGPT】 &#x1f33a;每日一句&#xff1a;天行健,君子以自强不息,地势坤,君子以厚德载物 ⭐欢迎并且感谢大家指出我的问题 文章目录 一、ChatGPT的发展历程 二、ChatGPT的技术原理 三、ChatGPT的应用场景 四、ChatGPT的未来趋势 五、总结 引言:随着…

基于SSM的高校疫情防控出入信息管理系统(有报告)。Javaee项目。

演示视频&#xff1a; 基于SSM的高校疫情防控出入信息管理系统&#xff08;有报告&#xff09;。Javaee项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Sprin…

三天打鱼两天晒网

文章目录 前言一、题目描述 二、题目分析 三、解题 程序运行代码 前言 本系列为选择结构编程题&#xff0c;点滴成长&#xff0c;一起逆袭。 一、题目描述 二、题目分析 三、解题 程序运行代码 #include<stdio.h> int main(){int n;scanf("%d",&n);i…

开发常用的 3种 API 监控报告- Eolink Apikit

API 监控报告是一种监测 API 异常的工具。在 API 管理中&#xff0c;查看 API 异常监控的监控报告&#xff0c;是 Eolink Apikit 常用的功能。Eolink Apikit 的监控报告有3种&#xff1a; 单接口监控报告 流程监控报告 项目监控报告 1、单接口监控报告 单接口监控报告通常关…