【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 valueqDebug() << it.key();qDebug() << it.value();}}

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

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

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

相关文章

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

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;预测编码/有偏竞争-分裂输入调制…

【博弈论】混合策略纳什均衡

上一章中遇到了划线法无法找到均衡的情况&#xff0c;例如盖硬币博弈&#xff0c;盖方盖硬币&#xff0c;猜方猜正反。那是因为考虑的都是纯策略&#xff0c;就是每个策略要么选&#xff0c;要么不选。本章考虑混合策略&#xff0c;就是每个策略都有一个选择的概率。 考虑还是这…

xilinx fpga ddr mig axi

硬件 参考&#xff1a; https://zhuanlan.zhihu.com/p/97491454 https://blog.csdn.net/qq_22222449/article/details/106492469 https://zhuanlan.zhihu.com/p/26327347 https://zhuanlan.zhihu.com/p/582524766 包括野火、正点原子的资料 一片内存是 1Gbit 128MByte 16bit …

Chrome 插件开发 V3版本 跨域处理

插件构成 chrome 插件通常由以下几部分组成&#xff1a; manifest.json&#xff1a;相当于插件的 meta 信息&#xff0c;包含插件的名称、版本号、图标、脚本文件名称等&#xff0c;这个文件是每个插件都必须提供的&#xff0c;其他几部分都是可选的。 background script&…

探索经典算法:贪心、分治、动态规划等

1.贪心算法 贪心算法是一种常见的算法范式&#xff0c;通常在解决最优化问题中使用。 贪心算法是一种在每一步选择中都采取当前状态下最优决策的算法范式。其核心思想是选择每一步的最佳解决方案&#xff0c;以期望达到最终的全局最优解。这种算法特点在于只考虑局部最优解&am…

Linux Vim批量注释和自定义注释

使用 Vim 编辑 Shell 脚本&#xff0c;在进行调试时&#xff0c;需要进行多行的注释&#xff0c;每次都要先切换到输入模式&#xff0c;在行首输入注释符"#"再退回命令模式&#xff0c;非常麻烦。连续行的注释其实可以用替换命令来完成。 换句话说&#xff0c;在指定…

0.专栏概述与几句闲话

引 还记得今年大年初一开始写《数据结构和算法》专栏的时候定了个小目标&#xff1a; 不知不觉间已经过去了十个月&#xff0c;我的第一个专栏也算是圆满收官了 。 这次PO一张成都熊猫基地的团子们&#xff0c;开启设计模式这个专栏吧。 目录与概述 犹记得一位身在广州的老…

Linux实现简易shell

文章目录 &#x1f984;0. shell&#x1f42e;1. 交互及获取命令行&#x1f437;2. 解析命令行&#x1f42f;3. 执行命令行&#x1f405;3.1 普通命令&#x1f405;3.2 内建命令 &#x1f981;4. 主函数逻辑及演示 本章代码gitee仓库&#xff1a;简易shell &#x1f984;0. she…

昇腾CANN 7.0 黑科技:DVPP硬件加速训练数据预处理,友好解决Host CPU预处理瓶颈

在NPU/GPU上进行模型训练计算&#xff0c;为了充分使用计算资源&#xff0c;一般采用批量数据处理方式&#xff0c;因此一般情况下为提升整体吞吐率&#xff0c;batch值会设置的比较大&#xff0c;常见的batch数为256/512&#xff0c;这样一来&#xff0c;对数据预处理处理速度…

Harbor私有仓库

Harbor私有仓库 文章目录 Harbor私有仓库Harbor简介&#xff1a;Harbor 提供了以下主要功能和特性&#xff1a;优缺点&#xff1a;环境说明&#xff1a;部署harbor1.永久关闭防火墙和seliux&#xff0c;配置阿里云源&#xff0c;添加映射关系2.安装docker&#xff0c;开启docke…

spdk用户态块层详解

先通过回顾内核态的通用块层来详细介绍SPDK通用块层&#xff0c;包括通用块层的架构、核心数据结构、数据流方面的考量等。最后描述基于通用块层之上的两个特性&#xff1a;一是逻辑卷的支持&#xff0c;基于通用块设备的Blobstore和各种逻辑卷的特性&#xff0c;精简配置&…

linux安装jdk和weblogic易错点

1.版本问题&#xff0c;如果版本不兼容&#xff0c;安装的时候会报错&#xff0c;所有安装之前要确认好版本 jdk1.6&#xff0c;weblogic10 2.jdk安装后配置文件 JAVA_HOME ,CLASSPATH,PATH&#xff0c;配置问你的追加&#xff0c;用冒号链接 修改后需要用source 刷新下 3安装…

MCU常见通信总线串讲(四)—— SPI总线协议

&#x1f64c;秋名山码民的主页 &#x1f602;oi退役选手&#xff0c;Java、大数据、单片机、IoT均有所涉猎&#xff0c;热爱技术&#xff0c;技术无罪 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; 获取源码&#xff0c;添加WX 目录 前言一…

PyCharm 无法登陆 Codeium 的解决方法

PyCharm 登陆 Codeium PyCharm 无法登陆 Codeium 的问题描述PyCharm 使用 token 登陆 Codeium PyCharm 无法登陆 Codeium 的问题描述 使用 PyCharm 登录 Codeium 时&#xff0c;单击 Login 无反应&#xff0c;单击侧边栏的 Codeium 图标也一直显示连接失败。 PyCharm 使用 to…

【Unity细节】Json序列化时出现:An item with the same key has already been added. Key:

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 &#x1f636;‍&#x1f32b;️收录于专栏&#xff1a;unity细节和bug &#x1f636;‍&#x1f32b;️优质专栏 ⭐【…

机器学习——CBOW负采样(纯理解)

刚从前一个坑里&#xff0c;勉强爬出来&#xff0c;又掘开另一坑 看了很多文章B站up主。。。糊里糊涂 但是我发觉&#xff0c;对于不理解的东西&#xff0c;要多看不同up主写的知识分享 书读百遍&#xff0c;其意自现&#xff0c;我是不相信的&#xff0c;容易钻牛角尖 但是&am…

前端-选中DOM定位源代码

用到的工具&#xff1a;react-dev-inspector 使用流程 根据react-dev-inspector文档进行配置 安装 yarn add --dev react-dev-inspector配置&#xff1a;在根目录下配置Inspector import { createRoot } from react-dom/client import { Inspector } from react-dev-inspe…

draw.io与项目管理——如何利用流程图工具提高项目管理效率

draw.io 是一款强大的图形绘制工具&#xff0c;用于创建各种类型的图表、流程图、组织结构图、网络图和平面设计等。它提供了丰富的绘图工具和预定义的图形库&#xff0c;使用户能够轻松创建专业水平的图形作品。 draw.io具有直观的界面和简单易用的功能&#xff0c;适合各种用…

oracle_19c 安装

oracle安装部署 1、安装docker,docker-compose环境。 curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun curl -L "https://github.com/docker/compose/releases/download/1.14.0-rc2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/b…

云计算的大模型之争,亚马逊云科技落后了?

文丨智能相对论 作者丨沈浪 “OpenAI使用了Azure的智能云服务”——在过去的半年&#xff0c;这几乎成为了微软智能云最好的广告词。 正所谓“水涨船高”&#xff0c;凭借OpenAI旗下的ChatGPT在全球范围内爆发&#xff0c;微软趁势拉了一波自家的云计算业务。2023年二季度&a…