August 14, 2023

Qt框架中的Json模块使用

这篇博客主要介绍Qt框架下的Json模块的使用

注:Json模块已经嵌入到QCore中,无需引入其他模块

需要使用的对象

QJsonDocument

这是Qt提供的一个用来序列化以及反序列化Json文本的类

QJsonDocument(const QJsonObject &*object*)

QJsonDocument常用的构造函数,会将传入的QJsonObject设置成主对象

fromJson(const QByteArray &json, QJsonParseError error = nullptr)

fromJson函数解析UTF-8编码的Json文本,并创建一个QJsonDocument对方返回,如果解析失败将会返回空值

object()

返回一个QJsonObject,如果文档为数组则返回空值

setObject(const QJsonObject &object)

将传入的QJsonObject设置成主对象,也就是Json文本的根对象

toJson(QJsonDocument::JsonFormat *format* = Indented) const

将存储在对象中的数据序列化为Json文本,需要传入一个变量,来确定转换之后的风格

QJsonDocument::Indented 可读模式,这个是有缩进的风格也就是下文会给出的Json文本的风格

QJsonDocument::Compact 紧凑模式,这个风格没有缩进是紧凑风格,一般用来减少占用使用

QJsonObject

operator[](QString &key)

对应键值存在就返回对应的QJsonValueRef,如果不存在就创建新的键,将新的值与其关联起来

take(const QString &key)

对应键值存在就返回对应的QJsonValue并且在QJsonObject中删除该键,不存在就返回一个null

value(const QString &key) const

对应键值存在便返回对应的QJsonValue,不存在就返回一个默认值,不会引发错误

insert(const QString &key, const QJsonValue &value)

传入的第一个变量为键,第二个变量是其对应的变量

erase(QJsonObject::iterator it)

擦除传入的迭代器指向的键值,并返回下一个对应的键值

QJsonValue

isInt()

如果值包含int类型则返回true,其他的函数同理

toInt(int defaultValue = 0) const

如果值为int or double类型便返回,如果值不是便返回defaultValue

其他to函数如果类型对应不上便返回defaultValue

toObject、toString、toArray如果不传入defaultValue便返回其无参构造函数构造的值

QJsonArray

这个比较好理解你只需要将其想成一个存放着QJsonValue的数组就可以了

at(qsizetype *i*) const

返回对应索引位置的元素,i的值必须是有效索引位置(0<=i<size)

takeAt(qsizetype i)

删除对应索引位置的元素并将其返回,i的值必须是有效索引位置

removeAt(qsizetype i)

同上但是不返回任何值

append(const QJsonValue &value)

将值插入到数组的末尾

示例解析

反序列化示例

我将给出一段代码,目的是反序列化这段Json文本

{
  "Text": "Hello Qt Json module",
  "Array": [
    {
      "ObjectName": "QWidget",
      "Widget": 1920,
      "High": 1080,
      "Hide": true
    },
    {
      "ObjectName": "QLable",
      "Widget": 114,
      "High": 514,
      "Hide": false
    }
  ]
}

这段代码反序列化了上面的Json文本并将存在里面的值输出了出来

#include <QtCore/QCoreApplication>
#include <QJsonArray>
#include <QJsonObject>
#include <QFile>
#include <QJsonDocument>
#include <QJsonValue>
int main(int argc, char* argv[]) {
 QCoreApplication a(argc, argv);
 QFile file("test.json");
 file.open(QIODeviceBase::ReadOnly);
 QJsonDocument document = QJsonDocument::fromJson(file.readAll());
 qDebug() << document.object()["Text"].toString();
 QJsonArray array = document.object()["Array"].toArray();
 for (auto item : array) {
  qDebug() << item.toObject()["ObjectName"].toString();
  qDebug() << item.toObject()["Widget"].toDouble();
  qDebug() << item.toObject()["High"].toDouble();
  qDebug() << item.toObject()["Hide"].toBool();
 }
 return a.exec();
}

接下来逐步解析一下

初始化file,设置文件名字为test.json

使用只读模式打开test.json文件

将test.json中的文本反序列化成QJsonDocument

QFile file("test.json");
file.open(QIODeviceBase::ReadOnly);
QJsonDocument document = QJsonDocument::fromJson(file.readAll());

读取Text键的值,将其转换成QString类型并输出

qDebug() << document.object()["Text"].toString();

读取Array键的值,将其转换成QJsonArray类型并赋值给array对象

QJsonArray array = document.object()["Array"].toArray();

使用for基于范围遍历array中的值,并输出item的值

for (auto item : array) {
 qDebug() << item.toObject()["ObjectName"].toString();
 qDebug() << item.toObject()["Widget"].toDouble();
 qDebug() << item.toObject()["High"].toDouble();
 qDebug() << item.toObject()["Hide"].toBool();
}

这便是一个简单的使用Qt框架中的Json模块反序列化的示例

序列化示例

这段代码生成了一段Json文本并写入了test.json文件中

#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QtCore/QCoreApplication>
int main(int argc, char* argv[]) {
  QCoreApplication a(argc, argv);
  QFile file("test.json");
  QJsonDocument document;
  QJsonObject jsonObject;
  QJsonArray array;
  file.open(QIODeviceBase::WriteOnly);
  QJsonValue value1("Hello World");
  jsonObject.insert("WelcomeText", value1);
  array.append(QJsonValue("ObjectName = Name"));
  array.append(QJsonValue("Hei!"));
  jsonObject.insert("Array", array);
  document.setObject(jsonObject);
  file.write(document.toJson(QJsonDocument::Indented));
  file.close();
  return a.exec();
}

初始化需要的变量,设置file的文件名为test.json

QFile file("test.json");
QJsonDocument document;
QJsonObject jsonObject;

使用只写模式打开

file.open(QIODeviceBase::WriteOnly);

构造一个QJsonValue并将其插入jsonObject中

QJsonValue value1("Hello World");
jsonObject.insert("WelcomeText", value1);

向array的尾部追加两个QJsonValue并插入到jsonObject中

array.append(QJsonValue("ObjectName = Name"));
array.append(QJsonValue("Hei!"));
jsonObject.insert("Array", array);

将jsonObject设置为document的主对象

将toJson使用Indented风格序列化出来的Json文本写入test.json文件中

并关闭test.json文件

document.setObject(jsonObject);
file.write(document.toJson(QJsonDocument::Indented));
file.close();

这段代码运行后会生成一个test.json文件,文件中内容为

{
  "Array": ["ObjectName = Name", "Hei!"],
  "WelcomeText": "Hello World"
}

最后来首音乐放松一下吧

About this Post

This post is written by JinHong Zeng, licensed under CC BY-NC 4.0.

#CPP#Qt#Json