一、简述

QVariant,是Qt中的一个变量类,属于Qt的底层核心之一,很多模块都是基于此类。可以支持N多的类型,具体支持多少,请看其类中定义的枚举:

enum Type {Invalid = QMetaType::UnknownType,Bool = QMetaType::Bool,Int = QMetaType::Int,UInt = QMetaType::UInt,LongLong = QMetaType::LongLong,ULongLong = QMetaType::ULongLong,Double = QMetaType::Double,Char = QMetaType::QChar,Map = QMetaType::QVariantMap,List = QMetaType::QVariantList,String = QMetaType::QString,StringList = QMetaType::QStringList,ByteArray = QMetaType::QByteArray,BitArray = QMetaType::QBitArray,Date = QMetaType::QDate,Time = QMetaType::QTime,DateTime = QMetaType::QDateTime,Url = QMetaType::QUrl,Locale = QMetaType::QLocale,Rect = QMetaType::QRect,RectF = QMetaType::QRectF,Size = QMetaType::QSize,SizeF = QMetaType::QSizeF,Line = QMetaType::QLine,LineF = QMetaType::QLineF,Point = QMetaType::QPoint,PointF = QMetaType::QPointF,RegExp = QMetaType::QRegExp,RegularExpression = QMetaType::QRegularExpression,Hash = QMetaType::QVariantHash,EasingCurve = QMetaType::QEasingCurve,Uuid = QMetaType::QUuid,
#if QT_CONFIG(itemmodel)ModelIndex = QMetaType::QModelIndex,PersistentModelIndex = QMetaType::QPersistentModelIndex,
#endifLastCoreType = QMetaType::LastCoreType,Font = QMetaType::QFont,Pixmap = QMetaType::QPixmap,Brush = QMetaType::QBrush,Color = QMetaType::QColor,Palette = QMetaType::QPalette,Image = QMetaType::QImage,Polygon = QMetaType::QPolygon,Region = QMetaType::QRegion,Bitmap = QMetaType::QBitmap,Cursor = QMetaType::QCursor,KeySequence = QMetaType::QKeySequence,Pen = QMetaType::QPen,TextLength = QMetaType::QTextLength,TextFormat = QMetaType::QTextFormat,Matrix = QMetaType::QMatrix,Transform = QMetaType::QTransform,Matrix4x4 = QMetaType::QMatrix4x4,Vector2D = QMetaType::QVector2D,Vector3D = QMetaType::QVector3D,Vector4D = QMetaType::QVector4D,Quaternion = QMetaType::QQuaternion,PolygonF = QMetaType::QPolygonF,Icon = QMetaType::QIcon,LastGuiType = QMetaType::LastGuiType,SizePolicy = QMetaType::QSizePolicy,UserType = QMetaType::User,LastType = 0xffffffff // need this so that gcc >= 3.4 allocates 32 bits for Type
};

太多了,让人瞠目结舌!

让我们来捋一捋,它除了支持int、double、bool等基本类型外,还支持QVariantMap、QVariantHash、QVariantList、QStringList等容器类型,还有一些类似QDateTime、QSize、QRect、QLine、QBitmap、QTransform、QIcon、QBrush、QColor、QFont等各种类型。

除此以外,它还支持自定义类型,真是有个博大的胸襟!!!

似乎Qt自己的类型全部都支持了,不过好像没有QObject。

所以,遇到类型问题,不要着急,试着往QVariant里面塞,看看是否已经支持了。

二、用QVariant保存任意类型与层次数据

我们下面测试中,使用QSetting操作ini配置文件,写入QVariant类型键值,并读取,来验证与写入内容是否一致。

QSettings* setting = new QSettings(qApp->applicationDirPath() + "/setting.ini", QSettings::IniFormat);

1. 保存QStringList

// 测试写入、读取QStringList
void test_QStringList(QSettings *setting)
{// 定义QStringList list;list << "zhangsan" << "lisi" << "wangxiaohua";// 写入setting->setValue("AppAttribute/QStringList", list);// 读取QStringList listResult = setting->value("AppAttribute/QStringList").toStringList();qDebug() << listResult;qDebug() << "-----------------------------------------------\n";
}

运行结果:

2. 保存结构体

// 测试写入、读取结构体对象
void test_StructObject(QSettings *setting)
{// 定义结构体QMap<QString, QVariant> person;person["name"] = "zhangsan";person["age"] = 25;person["sex"] = "man";// 写入setting->setValue("AppAttribute/Person", person);// 读取QMap<QString, QVariant> result = setting->value("AppAttribute/Person").toMap();qDebug() << result;qDebug() << "-----------------------------------------------\n";
}

运行结果:

3. 保存结构体嵌套

// 测试写入、读取结构体下面嵌套结构体
void test_NestedStructObject(QSettings *setting)
{// 定义嵌套结构体QMap<QString, QVariant> car;car["brand"] = "Audi";car["price"] = 20;QMap<QString, QVariant> person;person["name"] = "zhangsan";person["age"] = 25;person["sex"] = "man";person["car"] = car;// 写入setting->setValue("AppAttribute/PersonCar", person);// 读取QMap<QString, QVariant> result = setting->value("AppAttribute/PersonCar").toMap();qDebug() << result;qDebug() << "-----------------------------------------------\n";
}

运行结果:

4. 保存对象列表

// 测试写入、读取结构体对象列表
void test_StructObjectList(QSettings *setting)
{// 定义结构体列表QMap<QString, QVariant> person1;person1["name"] = "zhangsan";person1["age"] = 25;person1["sex"] = "man";QMap<QString, QVariant> person2;person2["name"] = "lisi";person2["age"] = 30;person2["sex"] = "woman";QList<QVariant> list;list << person1 << person2;// 写入setting->setValue("AppAttribute/Persons", list);// 读取QList<QVariant> result = setting->value("AppAttribute/Persons").toList();qDebug() << result;qDebug() << "-----------------------------------------------\n";
}

运行结果:

5. 保存对象树

// 测试写入、读取结构体对象树
void test_StructObjectTree(QSettings *setting)
{// 定义结构体对象树QMap<QString, QVariant> car1_0;car1_0["brand"] = "Audi";car1_0["price"] = 20;QMap<QString, QVariant> car1_1;car1_1["brand"] = "bmw";car1_1["price"] = 30;QMap<QString, QVariant> person1;person1["name"] = "zhangsan";person1["age"] = 25;person1["sex"] = "man";QList<QVariant> cars_1;cars_1 << car1_0 << car1_1;person1["cars"] = cars_1;/QMap<QString, QVariant> car2_0;car2_0["brand"] = "VOLVO";car2_0["price"] = 32;QMap<QString, QVariant> car2_1;car2_1["brand"] = "Benz";car2_1["price"] = 40;QMap<QString, QVariant> person2;person2["name"] = "lisi";person2["age"] = 31;person2["sex"] = "woman";QList<QVariant> cars_2;cars_2 << car2_0 << car2_1;person2["cars"] = cars_2;QList<QVariant> persons;persons << person1 << person2;// 写入setting->setValue("AppAttribute/PersonTree", persons);// 读取QList<QVariant> personsResult = setting->value("AppAttribute/PersonTree").toList();qDebug() << personsResult;qDebug() << "-----------------------------------------------\n";
}

运行结果:

结构越复杂,toString之后,可读性越低。

三、总结

QVariant实际上是实现了,以一种通用的类型,来有效组织任意类型,层次的数据,并实现了针对任意类型,层次数据的序列化、反序列化。

即对任意类型、层次数据可以自动转QString,对QString也可以自动转成最初的结构数据。

QVariant类似于实现了XML这样的可伸缩数据结构,而XML需要手写各种标签和组织层次。QVariant只需要你把数据按你自己的层次结构放进去就可以了,至于如何序列化,反序列化,你都不用关心。

正如,上面的测试代码,如果你觉得QVariant是一个值,那就错了,它可以是Any things。QSettings的设置键值方法:

void setValue(const QString &key, const QVariant &value);

同样道理,键值可以是一个list,也可以是一个map。所以有了QVariant,实现任意类型数据保存为配置,是多么easy的一件事情。

比如,我们有很多算法,每个算法有多个不同的属性,也就是成员变量,而算法的这些属性可以通过界面来配置,以决定每个属性的赋值,此时我们就可以将算法类名及其属性构成一个QVariant,多个算法就构成一个List,我们存储到配置文件中,然后读取出来,根据类名实例化算法,并同时将配置文件中属性初始化到算法实例中。这是不是像极了类似于spring框架中赖以生存的反射应用。通过配置文件来实例化对象和初始化属性。

一个QVariant,想到了反射,这似乎有点偏了,哈哈


若对你有帮助,欢迎点赞、收藏、评论,你的支持就是我的最大动力!!!

同时,阿超为大家准备了丰富的学习资料,欢迎关注公众号“超哥学编程”,即可领取。

本文涉及工程代码,公众号回复:38QVariantSetting,即可下载。

有容乃大的QVariant之使用相关推荐

  1. 海纳百川 有容乃大, 壁立千仞 无欲则刚

    可以想象,人生好比一趟旅行,一趟在海与山环绕的世界里旅行,地球上的海远比山多,这注定你开始旅行得造一艘结实的船. 我们学习的技术,就是在给自己造船的技术,这一般会占据我们人生时间中的三分之一,剩下的三 ...

  2. 痛苦的时候,不妨默读“有容乃大”

    --转载自简书用户 马石头 文/马石头 生而为人,活在这个世界上,谁都有可能遭遇意想不到事情,谁都会难免遇到一些排解不了的痛苦.有些事,可以通过我们的努力化解掉:有些事,任凭我们多么努力,也是无法避免 ...

  3. web返回的数据集格式_200G倾斜数据无插件web端预览!兼容三端,有容乃大—MapGIS M3D数据格式...

    "有容乃大"最早见之于明代兵部尚书太子太保袁可立在河南睢州自己"弗过堂"中所著的自勉联.二百年后又有清末民族英雄林则徐题于书室的八字联:"海纳百川,有 ...

  4. “容灾大数据城”梧桐引来金凤凰,千万元融资助“城市大脑”起步

    看什么看,快点蓝字关注我! 这边深圳"智博会"还未落幕,那边重庆"智博会"已经鸣锣开场.两个大会虽然定位.内容不完全相同,但同一个"智"字再 ...

  5. 有容乃大,无欲则刚,容是别人,欲是自己

    有容乃大,有欲则刚,容是别人,欲是自己,这样的天地才跑的欢畅,尤其适合机动部队,这早熟的人通常都晚熟,骄傲的人又急性子,这两样我都占了. 最恶毒的台词:最好你得破伤风死掉! 最无奈的台词:你暧昧你,你 ...

  6. 有容乃大-牛客网-编程入门(Java版)

    03有容乃大 题目描述: 确定不同整型数据类型在内存中占多大(字节),输出不同整型数据类型在内存中占多大(字节). 输入描述: 无 输出描述: 不同整型数据类型在内存中占多大(字节),具体格式详见输出 ...

  7. 有容乃大的技术世界观

    本文转载自:www.zhangxinxu.com/life/?p=811 对于刚工作不久,或者即将参与工作的技术人员,看一些关于技术人文,价值取向,以及技术世界观方面的文章要比单纯学一两个技术要重要的 ...

  8. 深圳市云海麒麟计算机系统,有容乃大 云海麒麟川大建平台解决方案

    原标题:有容乃大 云海麒麟川大建平台解决方案 近年来,高性能计算的崛起不仅仅在企业广泛应用,在学术教育领域的需求也日渐增多.云海麒麟在业内领先的技术也得到了知名学府四川大学的青睐.在云海麒麟的帮助下, ...

  9. 如何升华“海纳百川,有容乃大”——我们是高级生命

    看事物,抓本质. 地球上的生物都在围绕一个事情展开,那就是生存.如人类--价值观的不同,对生存的意义也就不同.不管是传宗接代,还是权力至上,更或者是杀戮征服,一切都是在有限生命里做自己认为有意义的事情 ...

最新文章

  1. java 继承 接口 练习,java:面向对象-抽象类、继承、接口结合练习
  2. poj-2101Honey and Milk Land
  3. STM32学习笔记——DMA控制器(向原子哥学习)
  4. C语言:L1-036 A乘以B (5分)
  5. Taro+react开发(88):taro条件渲染
  6. Python 错误和异常小结[转]
  7. 模拟ios_王者荣耀策划Donny:安卓IOS今年或实现互通!模拟战一周一更新
  8. 一步一步写算法(之基数排序)
  9. python接口自动化(十七)--Json 数据处理---一次爬坑记(详解)
  10. MySQL 备份 nb3 和 psc的区别
  11. 数据结构上机实践第五周项目1- 建立顺序栈算法库
  12. mysql insert or update_MySQL insert or update SQL 示例
  13. 什么是软件开发模式?
  14. 问题解决:wireshark之npcap无法安装、winpcap无法安装问题解决
  15. 数据挖掘实验:使用 Hadoop 实现 WordCount 应用
  16. 一加8T安装的EdXposed插件导致手机无限重启的解决办法
  17. 幸运岛链LKC:打造全新的商业和经济体系,让区块链赋能商业经济
  18. 【三种常见架构开发模式:MVC、MVP、MVVM】
  19. 如何批量重命名文件?
  20. strncpy()函数详解

热门文章

  1. 删除Github仓库中的指定的文件或文件夹
  2. kali自带的mysql初始化及密码
  3. 新版火狐 拖 功能_Firefox 28的新功能
  4. `Mask`工具使用示例
  5. NAudio音频相关开发
  6. 这家儿童运动馆的疯狂引流方案,老板赚翻了,值得各位学习
  7. jquery 点击元素以外任意地方隐藏该元素的方法
  8. 安全渗透测试笔记------------网络踩点(fierce、lbd、maltego、netifera)
  9. 手机内存不足怎么办?学会4招,让手机告别卡顿
  10. aspose依赖导入