Qt中的JSON操作

2023-11-11

JSON(JavaScript Object Notation,js对象标记)是一种轻量级的数据交换格式。它基于ECMAScript的一个子集,使用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的的层次结构使得JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效的提升网络传输效率。关于JSON的更多解释,请参看JSON官网

在Qt库中,为JSON的相关操作提供了完整的类支持,包括QJsonValue,QJsonObject,QJsonArray,QJsonDocument和QJsonParseError。其中,QJsonValue类表示json格式中的一个值;QJsonObject表示一个json对象;QJsonArray顾名思义表示一个json数组;QJsonDocument主要用来读写json文档;而QJsonParseError是用来表示json解析过程中出现的错误的方便类。下面,我们就来看看这些类的详细信息。

QJsonValue

QJsonValue类封装了一个json格式中的值。该值可以是如下6中基本类型:

  • bool QJsonValue::Bool
  • double QJsonValue::Double
  • string QJsonValue::String
  • array QJsonValue::Array
  • object QJsonValue::Object
  • null QJsonValue::Null
一个QJsonValue可以表示上面任何一种数据类型。此外,QJsonValue还有一个特殊的标志用来表示未定义的值。可以使用isUndefined()函数来进行判断。而一个QJsonValue中存储的类型可以通过type()或isBool(),isString()之类的函数进行查询。同样,QJsonValue中存储的值可以通过toBool(),toString()等函数转换到具体的类型。
QJsonValue中存储的值在内部是强类型的,并且和QVariant相反,它不会尝试进行任何的隐式类型转换。这意味着将QJsonValue转换成一个不是它存储的类型,将返回一个该类型的模型构造函数返回的值。
其实,说到QJsonValue,还有另一个类要说,QJsonValueRef,该类是一个对于QJsonArray和QJsonObject来说的一个帮助类。当你获得一个QJsonValueRef类的对象后,你可以把它当做一个QJsonValue对象的应用来使用。如果你向他赋值,该值会实际作用到底层的QJsonArray或者QJsonObject对象中的元素上。而要想使用该类,可以使用一下的两个方法:
  • QJsonArray::operator[](int i)
  • QJsonObject::operator[](const QString& key)const;
下面来看一下QJsonValue的构造函数:
QJsonValue(Type type = Null)
QJsonValue(bool b)
QJsonValue(double n)
QJsonValue(int n)
QJsonValue(qint64 n)
QJsonValue(const QString &s)
QJsonValue(QLatin1String s)
QJsonValue(const char *s)
QJsonValue(const QJsonArray &a)
QJsonValue(const QJsonObject &o)
QJsonValue(const QJsonValue &other)
可以看到,该类主要是对基本类型的一个包装。
QJsonObject
QJsonObject类封装了一个json对象。一个json对象是一个键值对的列表,其中key是唯一的字符串,而值就是一个我们上面讲到的QJsonValue。一个QJsonObject的对象可以转换到QVariantMap,要可以由QVariantMap转换得到。
我们可以使用size()函数来查询一个QJsonObject中存储的键值对的个数;使用insert()和remove()来插入或从中删除键值对;还可以使用标准的C++迭代器来遍历它。
QJsonObject类是一个隐式共享类。
其构造函数如下:
QJsonObject()
QJsonObject(std::initializer_list<QPair<QString, QJsonValue> > args)
QJsonObject(const QJsonObject &other)
我们可以使用初始化列表来快速的构建一个QJsonObject对象。如下:
  QJsonObject object
  {
      {"property1", 1},
      {"property2", 2}
  };
如此之外,比较常用的就是insert()函数了:
iterator QJsonObject::insert(const QString &key, const QJsonValue &value)
一般,我们可以先定义一个空的QJsonObject对象,然后使用该函数向其中插入需要的键值对。如果新插入的key已存在,那么会进行替换。
下面,我们通过一个例子还使用该类构造如下json字符串:{"name":"lily", "age":23, "addr":{"city":"xxx", "province":"yyy"}}
代码如下:
#include <QCoreApplication>
#include <QDebug>
#include <QJsonObject>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QJsonObject obj;
    obj.insert("name", "lily");
    obj.insert("age", 23);
    QJsonObject addr;
    addr.insert("city", "guangzhou");
    addr.insert("province", "guangdong");
    obj.insert("addr", addr);
    qDebug() << obj;

    return a.exec();
}
我们先构建了一个QJsonObject对象obj,然后向其中插入姓名和年龄键值对;因为地址又是一个QJsonObject,所以我们又构建了addr对象,向其中插入城市和省份,最后,将该QJsonObject做为地址键值对的值,插入到obj中。打印结果如下:
QJsonArray
顾名思义,QJsonArray封装了一个JSON数组。一个JSON数组是一个值的列表。我们可以向这个列表中插入或删除QJsonValue。
同时,我们可以把一个QVariantList转换成一个QJsonArray。也可以使用标准C++迭代器对它进行遍历。
其构造函数如下:
QJsonArray()
QJsonArray(std::initializer_list<QJsonValue> args)
QJsonArray(const QJsonArray &other)
我们也可以像上面那样,使用一个初始化列表来构建一个QJsonArray对象:
QJsonArray array = { 1, 2.2, QString() };
在此我们只使用了单个的值,没有使用键值对。其实,这样的json对象,一般我们就称为数组。
和QJsonObject一样,我们一般也是通过它的insert()函数来生成我们需要的json数组:
void insert(int i, const QJsonValue &value)
iterator insert(iterator before, const QJsonValue &value)
下面,我们继续上面的例子,来生成一个表示人物信息的列表。代码如下:
#include <QCoreApplication>
#include <QDebug>
#include <QJsonObject>
#include <QJsonArray>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QJsonObject obj1;
    obj1.insert("name", "lily");
    obj1.insert("age", 23);
    QJsonObject addr1;
    addr1.insert("city", "guangzhou");
    addr1.insert("province", "guangdong");
    obj1.insert("addr", addr1);
    qDebug() << obj1;

    QJsonObject obj2;
    obj2.insert("name", "tom");
    obj2.insert("age", 24);
    QJsonObject addr2;
    addr2.insert("city", "shenzhen");
    addr2.insert("province", "guangdong");
    obj2.insert("addr", addr2);
    qDebug() << obj2;

    QJsonObject obj3;
    obj3.insert("name", "jerry");
    obj3.insert("age", 24);
    QJsonObject addr3;
    addr3.insert("city", "foshan");
    addr3.insert("province", "guangdong");
    obj3.insert("addr", addr3);
    qDebug() << obj3;

    QJsonArray array;
    array.push_back(obj1);
    array.push_back(obj2);
    array.push_back(obj3);
    qDebug() << array;

    return a.exec();
}

在此,我们只是简单的构建了三个人物的QJsonObject对象,然后将它们放入一个QJsonArray中。输入结果如下:

QJsonDocument
QJsonDocument类提供了读写JSON文档的方法。QJsonDocument类包装了一个完整的JSON 文档,我们可以以utf-8编码的文本格式和Qt自己的二进制格式来操作该文档。一个JSON文档可以使用QJsonDocument::fromJson()函数转换json文本字符串来得到。而toJson()可以将其转换成文本。这个解析器是非常快速和高效的,Qt也是使用它来将JSON对象转换成其二进制表示的。解析得到的文档可以使用isNull()来判断是否有效。还可以使用isArray()和isObject()函数来判断该文档所包含的是否是数据或json对象。如果是,可以使用array()或object()函数还获得其中的对象或数组。
其构造函数如下:
QJsonDocument()
QJsonDocument(const QJsonObject &object)
QJsonDocument(const QJsonArray &array)
QJsonDocument(const QJsonDocument &other)
除了构造函数外,该类还提供了两个转换函数,可以将json文档序列化为二进制对象,然后我们就可以将该对象存储到文件中,或发送到网络上。
QByteArray toBinaryData() const
QByteArray toJson(JsonFormat format = Indented) const
下面,我们就使用该类将我们上面生成的json数组写入到文件中:
代码如下:
#include <QCoreApplication>
#include <QDebug>
#include <QJsonObject>
#include <QJsonArray>
#include <QFile>
#include <QJsonDocument>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QJsonObject obj1;
    obj1.insert("name", "lily");
    obj1.insert("age", 23);
    QJsonObject addr1;
    addr1.insert("city", "guangzhou");
    addr1.insert("province", "guangdong");
    obj1.insert("addr", addr1);
    qDebug() << obj1;

    QJsonObject obj2;
    obj2.insert("name", "tom");
    obj2.insert("age", 24);
    QJsonObject addr2;
    addr2.insert("city", "shenzhen");
    addr2.insert("province", "guangdong");
    obj2.insert("addr", addr2);
    qDebug() << obj2;

    QJsonObject obj3;
    obj3.insert("name", "jerry");
    obj3.insert("age", 24);
    QJsonObject addr3;
    addr3.insert("city", "foshan");
    addr3.insert("province", "guangdong");
    obj3.insert("addr", addr3);
    qDebug() << obj3;

    QJsonArray array;
    array.push_back(obj1);
    array.push_back(obj2);
    array.push_back(obj3);
    qDebug() << array;

    QJsonDocument jsonDoc(array);
    QByteArray ba = jsonDoc.toJson();
    QFile file("result.json");
    if(!file.open(QIODevice::WriteOnly))
    {
        qDebug() << "write json file failed";
        return 0;
    }
    file.write(ba);
    file.close();

    return a.exec();
}
我们先使用QJsonArray构建出一个QJsonDocument对象,然后调用其toJson()方法,将该json文档转换成一个字节数组。注意,toJson()函数会接受一个格式化参数:
QByteArray QJsonDocument::toJson(JsonFormat format = Indented) const
其中,format主要有两种格式,一种是人们可读的格式,一种是紧凑的格式。分别描述如下表:
Constant Value Description
QJsonDocument::Indented 0 定义人们可读的输出格式,如下:
{
"Array":[
true,
999,
"string"
],
"key": "value",
"null": null
}
QJsonDocument::Compact 1 定义一个紧凑的输出格式,如下:
{"Array": [true, 999, "string"], "key": "value", "null":null}

toJson()函数默认使用Indented,一缩进的形式生成人们可读的json文件。
运行该程序后,在编译目录查看生成的json文件。结果如下:
当然,除了将json对象写入到文件中,QJsonDocument还提供了几个静态函数,将从文件中读取出的原始数据或json字符串转换成一个QJsonDocument对象。函数声明信息如下:
QJsonDocument fromBinaryData(const QByteArray &data, DataValidation validation = Validate)
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR)
QJsonDocument fromRawData(const char *data, int size, DataValidation validation = Validate)
QJsonDocument fromVariant(const QVariant &variant)
下面,我们就使用这些函数,将我们写入到文件中的json对象再读出来,并生成一个QJsonDocument对象。
代码如下:
#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QJsonDocument>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QFile file("result.json");
    if(!file.open(QIODevice::ReadOnly))
    {
        qDebug() << "read json file failed";
        return 0;
    }
    QByteArray ba = file.readAll();
    qDebug() << "读出的数据如下:";
    qDebug() << ba;
    QJsonParseError e;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(ba, &e);
    if(e.error == QJsonParseError::NoError && !jsonDoc.isNull())
    {
        qDebug() << jsonDoc;
    }

    return a.exec();
}

在此,因为我们从文件中读出的是一个json形式的字符串,所以可以使用fromJson()函数,将其转换成一个QJsonDocument对象。同时,在调用fromJson()函数时,我们还为它传入了一个QJsonParseError对象,用来接收解析json字符串的过程中,有可能发生的错误信息。
代码运行如下:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt中的JSON操作 的相关文章

随机推荐

  • IDEA在使用maven命令时,控制台出现中文乱码的解决方式

    今天在进行maven打包的时候 由于项目路径有中文名称 然后控制台出现了中文乱码 如图所示 这种情况下 本狗试过很多种方法 比如在setting gt encoding中设置字符集为UTF 8等等方法 但是都没有用 后来经过大量百度 找到了
  • Secret File ctf web php伪协议

    Secret File php伪协议 打开网页并没有太多提示 查看一下网页源码 可以看到一个新的页面 Archive room php 尝试访问一下 这是就跳出了这样一个页面 点击SECRET 出现如下页面 比较之前的网页源码并没有什么变化
  • 成功解决:RuntimeError: DataLoader worker (pid(s) XXX) exited unexpectedly

    跑着跑着出现Bug RuntimeError DataLoader worker pid s x x x x exited unexpectedly 加上 if name main
  • 【数模】基于PageRank算法的学术论文重要性排序问题(matlab实现)

    基于PageRank算法的学术论文排序问题 matlab实现 问题描述 六篇学术论文的引用关系如图 A 指向 B 表示 A 引用 B 试排出它们重要性的顺序 问题分析 就是给节点来个重要性排序 PageRank简介 PageRank 又称网
  • oracle表空间迁移transport_tablespace的使用

    问题描述 如果某个表空间有多个用户 那么我们在迁移的时候如果按用户导出导入的话 那将是一个麻烦费事的活 这个时候我们可以通过transport tablespace参数进行表空间迁移 达到一次性迁移整个表空间的目的 下面通过一个实验来讲解整
  • layui table 跨页、翻页记忆选择

    示例 table class layui table table layui 需要初始化的 form layui form layfilter layui layfilter table render
  • linux du命令

    百度百科查到 du show disk usage 查看磁盘使用情况 个人用的比较多的命令是 du h max depth 1 查看这个目录下的文件目录大小 du ah max depth 1查看这个目录下的文件目录包括文件的大小 具体的命
  • 项目经验分享:基于昇思MindSpore实现手写汉字识别

    项目信息Program Info 项目要求 基于MindSpore的实现在线手写汉字识别 主要包括手写汉字检测和手写汉字识别 能较准确的对标准字体的手写文字进行识别 识别后通过人工干预对文本进行适当修正 需要有一定的创新特性 代码达到合入社
  • Android开发学习【Button控件】

    Android开发学习 Day02 Button 与TextView相比 Button增加了两个新属性 书写一个点击显示当前时间的按钮 获取当前时间的java类 xml主界面 MainActivity类 点击事件和长按事件 使用setOnC
  • C++中的头文件.h 和 源文件.cpp 的关系

    在VS中 C 项目 我创建了一个类 会自动创建头文件和源文件 这两个文件有什么关系 如何快速切换 在头文件 h文件中声明的类方法 如何快速在源文件中进行具体实现 在 Visual Studio 中创建 C 项目时 当你添加一个新的类 它会自
  • 游戏外挂内存数据读取

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 源地址 http hi baidu com probill blog item 1d07d11efbd641f01ad576f3 html网络游戏 每一个数据比如你的血值
  • vue 父子间通信 总结

    vue 父子间通信 总结 组件之间通信 父组件向子组件传值 父传子 props 父组件 子组件 实现的效果图 父组件输入密码 子组件接收数据 子组件向父组件传值 子传父 emit eventName args 子组件 父组件 兄弟组件之间的
  • Qt学习笔记(五)【多窗口交互方法】

    在开发应用程序的过程中 难免会遇到多个进行交互的问题 Qt中多窗口交互有多种方式 方法一 利用主窗口指针的方式进行交互 在主窗口中创建子窗口时 会将this指针传递进去 则子窗口就会将主窗口作为父窗口 因此在子窗口中可以通过如下代码获取到主
  • 青海省招标投标投诉处理办法

    http baike baidu com view 12098489 htm
  • 图像均值、标准差、变异系数的意义

    目录 均值图像如何算 方差图像如何计算 变异系数是什么 极差 最大值 最小值 方差 数列中每个元素与均值之差的平方和 标准差 方差的开平方根 变异系数 正态分布 标准差 平均值 数字图像处理的配套视频教程 1 冈萨雷斯 数字图像处理 开始安
  • jquery vue 替代_关于jQuery和Vue两者技术架构的比较分析报告

    关于jQuery和Vue两者技术架构的比较分析报告 jQuery jQuery已经过时了 略做点补充 Zepto也是过时货了 还有Underscore Lodash等 也是过时了 但是过时不代表你就一定不可以再用 或者要从现有项目中清除抛弃
  • Vue路由守卫

    路由守卫的作用 对路由进行权限控制 分类 全局守卫 独享守卫 组件内守卫 1 全局守卫 全局前置路由守卫 初始化和每次路由切换时调用 router beforeEach to from next gt console log 前置路由守卫
  • vue在父组件如何获取子组件的ref

    步骤 1 给父组件定义一个ref 2 子组件也是一样的ref 父组件 div div
  • 【规划】RRT Planer 以及 python实现

    本文转载自头条号作者半杯茶的小酒杯 百度的研发工程师 文章多是自动驾驶相关 推介给大家 RRT Planer 快速搜索随机树 RRT Rapidly ExploringRandom Trees 是一种常见的用于机器人路径规划的方法 他的原始
  • Qt中的JSON操作

    JSON JavaScript Object Notation js对象标记 是一种轻量级的数据交换格式 它基于ECMAScript的一个子集 使用完全独立于编程语言的文本格式来存储和表示数据 简洁和清晰的的层次结构使得JSON成为理想的数