【QVariant类型剖析】

news2024/11/18 4:18:42

QVariant类型剖析

  • 🌟 官方文档中给出的定义
  • 🌟 特性
  • 🌸QVariant实战应用
  • 🌸项目成果展示

在这里插入图片描述

🌟 官方文档中给出的定义

📘Because C++ forbids unions from including types that have non-default constructors or destructors, most interesting Qt classes cannot be used in unions. Without QVariant, this would be a problem for QObject::property() and for database work, etc.
📖[译文]:由于C ++禁止联合(union)中引用具有自定义构造函数或析构函数的类型,因此这个最有趣的QT类并不能在联合(union)中使用。没有QVariant类的支持,Qt的属性系统和数据库将无法进行正常工作。

📘A QVariant object holds a single value of a single type() at a time. (Some type()s are multi-valued, for example a string list.) You can find out what type, T, the variant holds, convert it to a different type using convert(), get its value using one of the toT() functions (e.g., toSize()) and check whether the type can be converted to a particular type using canConvert().
📖[译文]:QVariant对象每次只能容纳唯一类型的唯一值。(ps: 一些类型是可以包含有多个值,例如:QStringList)。你可以弄清楚T是哪种类型,通过使用convert()转换为不同的类型,通过T()显示转换获取其容纳的值,并通过canConvert()来判断是否能够转换为对应的类型。

📘The methods named toT() (e.g., toInt(), toString()) are const. If you ask for the stored type, they return a copy of the stored object. If you ask for a type that can be generated from the stored type, toT() copies and converts and leaves the object itself unchanged. If you ask for a type that cannot be generated from the stored type, the result depends on the type; see the function documentation for details
📖[译文]:toT()是一个稳定的方法(例如,toInt()、toString())。如果您要求存储的类型,他们会返回存储对象的副本。如果您要求一个可以从存储的类型生成的类型,toT()会复制和转换对象,并保持对象本身不变。如果您要求一个无法从存储的类型生成的类型,结果取决于该类型;有关详细信息,请参阅功能文档

🌟 特性

QVariant 是Qt中用于封装任意类型数据的类,它可以在不同数据类型之间进行转换和存储,是Qt中处理数据的重要工具之一。

  • ✨数据类型的封装和存储QVariant 可以封装和存储几乎所有Qt支持的数据类型,包括基本数据类型(如整数、浮点数、布尔值、枚举)、复合数据类型(如字符串、列表、映射、日期时间)、自定义数据类型(通过注册元类型实现)等。
  QDataStream out(...);
  QVariant v(123);                // The variant now contains an int
  int x = v.toInt();              // x = 123
  out << v;                       // Writes a type tag and an int to out
  v = QVariant("hello");          // The variant now contains a QByteArray
  v = QVariant(tr("hello"));      // The variant now contains a QString
  int y = v.toInt();              // y = 0 since v cannot be converted to an int
  QString s = v.toString();       // s = tr("hello")  (see QObject::tr())
  out << v;                       // Writes a type tag and a QString to out
  ...
  QDataStream in(...);            // (opening the previously written stream)
  in >> v;                        // Reads an Int variant
  int z = v.toInt();              // z = 123
  qDebug("Type is %s",            // prints "Type is int"
          v.typeName());
  v = v.toInt() + 100;            // The variant now hold the value 223
  v = QVariant(QStringList());
  • ✨类型安全的数据访问QVariant 允许您以一种类型安全的方式访问封装的数据,而不需要显式的类型转换。您可以通过 QVariant::value() 将 QVariant 转换为指定类型 T 的值。
 QVariant var = 42;
 int intValue = var.value<int>(); // 获取整数值
  • ✨动态类型识别:Variant 可以存储数据的同时记录其实际类型信息,使得在运行时能够动态地识别和转换数据类型。您可以使用 QVariant::type() 方法获取存储的数据类型。
 QVariant var = "Hello";
 qDebug() << var.type(); // 输出数据类型
  • ✨空值表示:QVariant 可以表示空值(即无效值),这在处理可能没有值的情况时非常有用。您可以使用 QVariant::isNull() 或 QVariant::isValid() 方法检查 QVariant 是否为空或有效。
 QVariant var; // 未初始化的空值
 if (var.isNull()) {
     qDebug() << "Variant is null";
 }
  • ✨通用数据存储和传递:QVariant 在Qt中广泛用于通用数据的存储和传递,例如在信号和槽参数中传递任意类型的数据,或者在模型/视图框架中存储和操作各种类型的数据。下面是在QTreeView中设置一个节点的角色数据。
 //setData()函数为节点的某一列设置一个角色数据
 //其中column是列号role是角色的值, value是QVariant 类型的数。
 void QTreeWidgetItem::setData(int column , int role , const QVariant &value)
 //它为节点的第一列角色Qt::UserRole设置了字符串数据dataStr,Qt::UserRole是枚举类型Qt::ItemDataRole个预定义的值
 item >setData(MainWindow::colitem,Qt::UserRole,QVariant(dataStr)) ;
  • ✨元类型系统的支持:QVariant 和Qt的元类型系统(Meta Type System)密切相关。通过注册自定义类型到元类型系统,您可以使 QVariant 能够处理自定义的用户数据类型。
#include <QMetaType> // 包含Q_DECLARE_METATYPE宏所需的头文件
//可以通过下面这种方式声明元类型
Q_DECLARE_METATYPE("QVector<AgendaInfo>");

💫 补充说明:
在 Qt 中,Q_DECLARE_METATYPE 宏和 qRegisterMetaType 函数都是用于将自定义类型注册到 Qt 的元类型系统中,以便在信号槽、线程间通信等场景中能够正确地处理这些自定义类型的数据。虽然它们的作用相似,但在不同的情况下适合使用不同的方式。

  1. 💥Q_DECLARE_METATYPE 宏用于在编译时声明自定义类型作为元类型,以便 Qt 的元类型系统能够识别和处理该类型的数据。通常在自定义类型的声明之后,通过 Q_DECLARE_METATYPE 宏来告知 Qt 如何处理该类型。
  2. 💥qRegisterMetaType 函数用于在运行时动态注册自定义类型作为元类型。通常用于将自定义类型注册为 Qt 的信号槽系统中的参数类型,以便能够在不同线程间传递该类型的数据。
    在这里插入图片描述

🌸QVariant实战应用

  • 范例
    下面我利用QVariant来容纳一个自定义的数据类型ItemInfo,将其与QListWidget中的项(QListWidgetItem)关联起来,将其作为项的用户自定义角色的起始值(Qt::UserRole)的数据。实现主要项目功能如下:
    1. 💫通过QLineEdit(Qt提供的单行文本编辑器控件)来输入ItemInfo的成员变量的值。
 struct ItemInfo{//节点信息
     QString name;//节点名称
     QSize size;//节点大小
     QIcon icon;//节点图标
     ItemInfo(const QString &n = QString(), const QSize &s = QSize(),  const QIcon &i = QIcon())
        : name(n), size(s), icon(i)
     {}
 };
// 在结构体定义之后添加Q_DECLARE_METATYPE宏声明
Q_DECLARE_METATYPE(ItemInfo)

ItemInfo是用户自定义数据结构类型,必须通过声明元类型

  1. 💫通过QPushButton(Qt提供的普通按钮控件)来打开QFileDialog(文件选择对话框),选择Icon文件的路径,并将图片显示在QLabel中。
void widget::on_btn_Choose_clicked()
{
    // 选择节点图标文件
    QString fileName = QFileDialog::getOpenFileName(this, "Choose Icon"
                            , "D:/Repositories/PaperlessConferencePCSystem/src/Resources", "Icons (*.jpg;*.png)");

    if (!fileName.isEmpty()) {
        // 添加选择的图标文件到当前图标
        m_currentIcon.addFile(fileName);
        ui->lab_Icon->setPixmap(m_currentIcon.pixmap(50,50));
    }
}

其中getOpenFileName()函数是QFileDialog提供的静态函数,用于返回选中的文件名称。函数原型如下:

[static] QString QFileDialog::getOpenFileName(QWidget *parent = nullptr, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = nullptr, QFileDialog::Options options = Options())
  1. 💫通过QPushButton(Qt提供的普通按钮控件)来生成一个QListWidgetItem,并添加到QListView中,展示出与该Item关联的Icon、Name等信息。
void widget::on_btn_Add_clicked()
{
    // 获取用户输入的节点信息
    QString name = ui->lEdit_Name->text();
    int width = ui->lEdit_Width->text().toInt();
    int height = ui->lEdit_Height->text().toInt();

    // 创建节点信息结构体
    ItemInfo info(name, QSize(width, height), m_currentIcon);

    // 创建包含节点信息的 QListWidgetItem
    QListWidgetItem *item = new QListWidgetItem(info.icon, info.name);
    // 将 QListWidgetItem 添加到 QListWidget 中
    ui->listWidget->addItem(item);

    // 存储节点信息与 QListWidgetItem 的关联,可使用 QListWidgetItem 的 data() 方法存储
    QVariant variant;
    variant.setValue(info);
    item->setData(Qt::UserRole, variant); // 将节点信息存储到 QListWidgetItem 的 data 中
}
  1. 💫通过点击QListWidgetItem,通过QLabel显示出该Item关联的QSize信息。
void widget::on_listWidget_itemClicked(QListWidgetItem *item)
{
    // 获取点击的 QListWidgetItem 中存储的节点信息
    QVariant variant = item->data(Qt::UserRole);
    if (variant.canConvert<ItemInfo>()) {
        ItemInfo info = variant.value<ItemInfo>();

        // 显示节点的 QSize 信息
        QString sizeInfo = QString("Size: %1 x %2").arg(info.size.width()).arg(info.size.height());
        ui->lab_Status->setText("Item Size"+ sizeInfo);

        ui->lab_Icon->setPixmap(info.icon.pixmap(50,50));
    }
}

🌸项目成果展示

暂时支持图片展示效果,但我会将源码上传到GitHub[获取源码GitHub]。
进入软件

在这里插入图片描述
填上ItemInfo的信息,并点击AddItem
在这里插入图片描述
点击左侧中存在的Item
在这里插入图片描述
再添加一个item
在这里插入图片描述

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

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

相关文章

【C++算法】队列相关经典算法题

1. N叉树的层序遍历 首先我们遇到这个题目&#xff0c;没有任何思路&#xff0c;我们就可以来模拟一下层序的流程&#xff0c;首先我们肯定是访问根节点1&#xff0c;访问之后呢就是访问下一层的最左节点3&#xff0c;此时第一层的节点1已经访问过了就可以不要了&#xff0c;然…

笨方法自学python(二)-注释

注释和#号 程序里的注释是很重要的。它们可以用自然语言告诉你某段代码的功能是什么。在你想要临时移除一段代码时&#xff0c;你还可以用注解的方式将这段代码临时禁用。 # A comment, this is so you can read your program later. # Anything after the # is ignored by py…

消费增值:绿色积分引领电商潮流

消费增值的玩法确实为电商平台提供了一种新颖的用户激励机制&#xff0c;通过积分返利和增值机制&#xff0c;吸引消费者持续参与并提升用户粘性。以下是对您提供的信息的进一步解析和扩展&#xff1a; 消费增值玩法解析 商城消费返利&#xff1a; 每笔消费订单&#xff0c;商…

Celery Redis 集群版连接和PyCharm启动配置

目录 使用Redis cluster版作为broker原因 PyCharm配置 使用Redis cluster版作为broker 在celery5及其之前版本&#xff0c;需要配置如下才可行 celery_app.conf.update( broker_transport_options{“global_keyprefix”: “{celery}:”}, ) 原因 https://github.com/celery/…

深度学习:基于人工神经网络ANN的降雨预测

前言 系列专栏:【深度学习&#xff1a;算法项目实战】✨︎ 本专栏涉及创建深度学习模型、处理非结构化数据以及指导复杂的模型&#xff0c;如卷积神经网络(CNN)、递归神经网络 (RNN)&#xff0c;包括长短期记忆 (LSTM) 、门控循环单元 (GRU)、自动编码器 (AE)、受限玻尔兹曼机(…

alist网盘自动同步

alist网盘自动同步 alist可以设置目录定时转存到各个网盘&#xff0c;做到夸网盘&#xff0c;多备份的效果可以将自己挂载的alist 下的各个目录相互间进行同步&#xff0c;原理是采用alist原始api调用执行&#xff0c;同步原理是匹配文件名称是否相同&#xff0c;相同会跳过同…

excel表格里,可以把百分号放在数字前面吗?

在有些版本里是可以的&#xff0c;这样做&#xff1a; 选中数据&#xff0c;鼠标右键&#xff0c;点击设置单元格格式&#xff0c;切换到自定义&#xff0c;在右侧栏输入%0&#xff0c;点击确定就可以了。 这样设置的好处是&#xff0c;它仍旧是数值&#xff0c;并且数值大小没…

grid的常见使用场景

场景1&#xff1a;固定几列显示&#xff0c;显示不下会自动换行 <div id"container"><div class"item item-1">1</div><div class"item item-2">2</div><div class"item item-3">3</div>&l…

vue 孙组件调用父组件的方法

通过组件内的 传递方法名称&#xff0c;可以实现孙组件调用父组件。 代码如下&#xff1a; index.html <!DOCTYPE html> <html> <head><meta charset"utf-8"><script src"/framework/vue-2.7.16.min.js"></script>…

C++奇迹之旅:string类对象的修改操作

文章目录 &#x1f4dd;string类的常用接口&#x1f320; string类对象的修改操作&#x1f309;push_back&#x1f309;append&#x1f309;operator&#x1f309;insert&#x1f309;erase&#x1f309;replace&#x1f309; find&#x1f309; c_str &#x1f320;测试string…

如何到《新英格兰医学杂志》 NEJM查找下载文献

《新英格兰医学杂志》NEJM是世界上阅读、引用最广泛、影响力最大的综合性医学期刊之一。NEJM集团出版的期刊还包括NEJM Journal Watch、NEJM Catalyst及NEJM Evidence。NEJM是一份全科医学周刊&#xff0c;出版对生物医学科学与临床实践具有重要意义的一系列主题方面的医学研究…

服务器远程桌面局域网连接不上的解决方法

在企业网络环境中&#xff0c;服务器远程桌面局域网连接不上是一个常见且棘手的问题。这种问题可能导致工作效率下降&#xff0c;甚至影响业务运营。因此&#xff0c;我们需要采取专业的方法来解决这一问题。 服务器远程桌面局域网连接不上的解决方法&#xff1a; 1、确保服务器…

【北京迅为】《iTOP-3588从零搭建ubuntu环境手册》-第7章 安装VMwareTools

RK3588是一款低功耗、高性能的处理器&#xff0c;适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用&#xff0c;RK3588支持8K视频编解码&#xff0c;内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP&…

[单机]完美国际_V155_GM工具_VM虚拟机

[端游] 完美国际单机版V155一键端PC电脑网络游戏完美世界幻海凌云家园 本教程仅限学习使用&#xff0c;禁止商用&#xff0c;一切后果与本人无关&#xff0c;此声明具有法律效应&#xff01;&#xff01;&#xff01;&#xff01; 教程是本人亲自搭建成功的&#xff0c;绝对是…

2023版brupsuite专业破解安装

安装教程&#xff0c;分两部分&#xff1a; 1、安装java环境、参考链接JAVA安装配置----最详细的教程&#xff08;测试木头人&#xff09;_java安装教程详细-CSDN博客 2、安装2023.4版本brupsuite&#xff1a;参考链接 2023最新版—Brup_Suite安装配置----最详细的教程&…

云启未来:“云计算与网络运维精英交流群”与“独家资料”等你来探索“

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 公众号&#xff1a;网络豆云计算学堂 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a; 网络豆的主页​​​​​ &#x1f680; 云计算与运维精英交流群诚邀您的加入…

基于双经度模型的鱼眼图像畸变校正

文章目录 1. 简介2. 基本原理基本思路从目标图到半球面模型的投影从半球面模型到鱼眼图像的投影正交投影等距投影 3.实际效果示例论文中的原图去畸变 4. 有意思的玩法5. 对生成的鱼眼图去畸变 1. 简介 算法来自论文《基于双经度模型的鱼眼图像畸变矫正方法》 2. 基本原理 基本…

【复利思维 + 项目成功方程式】用1年,超越别人38年!

复利思维—每天进步1%。 一年后会比现在的自己优秀38倍。在做任何事情时都要考虑&#xff0c;这件事是否能随着时间不断积累扩大&#xff0c;不能积累价值的事情要及时调整和止损。 在这个过程中&#xff0c;千万不要陷入心理暗示的陷阱&#xff0c;尤其是越想得到的&#xf…

ElasticSearch集群环境

ElasticSearch集群环境 1、Linux单机 下载地址&#xff1a;LINUX X86_64 (elastic.co) 下载之后进行解压 tar -zxf elasticsearch-7.8.0-linux-x86_64.tar.gz 名字太长了改个名字改成es mv elasticsearch-7.8.0 es因为安全问题&#xff0c;Elasticsearch 不允许 root 用户…

一文读懂NVIDIA AI全景:从芯片到应用,全面解析未来科技

英伟达 NVIDIA AI 全景解析 NVIDIA 概述 公司概况 NVIDIA作为全球顶尖科技公司&#xff0c;早期深耕图形处理器设计制造&#xff0c;现已跃升为人工智能领域的领军者&#xff0c;产品和服务覆盖AI应用的全方位&#xff0c;引领科技潮流。 NVIDIA&#xff0c;1993年创立于美国…