Bootstrap

【Qt】Json在Qt中的使用

Json

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,广泛用于互联网应用程序之间的数据传输。JSON基于JavaScript中的对象语法,但它是独立于语言的,因此在许多编程语言中都有对JSON的解析和生成支持。

Json包括Json对象和Json数组,两者都可以嵌套。

Json数组:

[
    ["a", 123, "c", false],
    ["周一", "周二", "周三", "周四"],
]

以下是一个JSON对象的例子:

{
    "name": "Alice",
    "age": 25,
    "isStudent": true,
    "hobbies": ["hiking", "reading"],
    "address": {
        "city": "New York",
        "zipCode": "10001"
    }
}

在上述例子中,name、age、isStudent等属性以键值对的形式存在,地址字段中又包含了另一个嵌套的JSON对象。

Qt中的Json类

包括:

  • QJsonValue:封装了Json支持的数据类型
  • QJsonObject:Qt中的Json对象
  • QJsonArray:Qt中的Json数组
  • QJsonDocument:实现Json数组/Json对象与字符串之间的转换

一张图带你理清Qt中Json类的关系:

在这里插入图片描述

QJsonValue

在 Qt 中,QJsonValue 是用于表示 JSON 数据的类,它可以包含 JSON 中的各种数据类型,包括对象、数组、字符串、数值、布尔值和 null 值。

  1. 多种数据类型支持: QJsonValue 可以存储 JSON 中的各种数据类型。它可以表示对象(QJsonObject)、数组(QJsonArray)、字符串(QString)、数值(double)、布尔值(bool)和 null 值(QJsonValue::Null)。

可以查询Qt Assistant了解QJsonValue的用法:
构造函数:
在这里插入图片描述

示例:

QJsonValue value1 = 123; // 数值类型
QJsonValue value2 = "Hello"; // 字符串类型
QJsonValue value3 = true; // 布尔类型
QJsonValue value4 = QJsonValue::Null; // null 类型
  1. 判断JSON 数据类型: 可以使用 QJsonValue 的方法来获取其存储的数据类型和值。
    使用 QJsonValue::isObject()QJsonValue::isArray()QJsonValue::isString() 等方法判断存储的是何种数据类型。

在这里插入图片描述

  1. 方便的转换和操作: QJsonValue 提供了用于转换和操作 JSON 数据的方法,如 toObject()toArray()toVariant()toBool() 等,这些方法能够方便地将 JSON 数据转换为其他数据结构进行进一步处理。

在这里插入图片描述
示例:

QJsonValue value = ...; // 一个 QJsonValue 对象
if (value.isString()) {
    QString stringValue = value.toString();
    // 处理字符串类型
} else if (value.isObject()) {
    QJsonObject objValue = value.toObject();
    // 处理对象类型
}
// 其他类型的处理...

QJsonObject

QJsonObject封装了Json中的对象,在里边可以存储多个键值对,为了方便操作,键值为字符串类型,值为QJsonValue类型

注意:QjsonObject内部按照key值升序排列(红黑树),所以添加顺序和实际顺序不一致。

  1. 创建 JSON 对象并插入:
    可以使用 QJsonObject::insert() 方法向对象中插入键值对,也可以直接使用赋值语句初始化 QJsonObject 对象。

在这里插入图片描述

QJsonObject jsonObj;
jsonObj.insert("name", "Alice");
jsonObj.insert("age", 25);
  1. 访问和操作 JSON 对象内容: 可以使用 QJsonObject 提供的方法来访问和操作对象中的键值对。比如使用 value() 方法获取特定键的值,使用 contains() 方法检查特定键是否存在,使用 remove() 方法删除特定键值对等。
    a. 通过key获得value
    在这里插入图片描述

    b. 通过下标获得value
    在这里插入图片描述
    c. 检查键是否存在
    在这里插入图片描述
    d. remove删除键值对,take删除键值对并返回删除的值
    在这里插入图片描述
    在这里插入图片描述

示例:

QJsonObject jsonObj;
jsonObj.insert("name", "Alice");
jsonObj.insert("age", 25);

// 访问键值对
QString name = jsonObj.value("name").toString();
int age = jsonObj.value("age").toInt();

// 检查键是否存在
bool hasName = jsonObj.contains("name");

// 删除键值对
jsonObj.remove("age");
  1. 遍历
    a. 使用下标[]遍历
    b. 使用QJsonObject::keys()得到键值,再遍历键值。

示例:

// 创建一个例子的 JSON 对象
    QJsonObject jsonObj;
    jsonObj.insert("name", "Alice");
    jsonObj.insert("age", 25);
    jsonObj.insert("city", "New York");

    // 使用 QJsonObject::keys() 获取键值
    QStringList keys = jsonObj.keys();

    // 遍历键,并访问对应的值
    foreach(QString key, keys) {
        QJsonValue value = jsonObj.value(key); // 获取键对应的值
        if(value.isString()) {
            qDebug() << "Key:" << key << ", Value:" << value.toString(); // 输出键值对
        }
        else {
            qDebug() << "Key:" << key << ", Value is not a string";
        }
    }

QJsonArray

QJsonArray是Qt中的Json数组,与QJsonObject不同,QJsonArray的插入顺序与实际存储顺序相同。

以下是 QJsonArray 主要的特性和用法:

  1. 创建 JSON 数组: 可以使用 QJsonArray 的构造函数或 append() 方法向数组中添加元素,也可以直接使用赋值语句初始化 QJsonArray 对象。
QJsonArray jsonArray;
jsonArray.append("Apple");
jsonArray.append("Banana");
jsonArray.append("Orange");
  1. 访问和操作 JSON 数组内容: 可以使用 QJsonArray 提供的方法来访问和操作数组中的元素。比如使用 at() 方法或 [] 操作符获取特定位置的元素,使用 size() 方法获取数组的大小等。
QJsonArray jsonArray;
jsonArray.append("Apple");
jsonArray.append("Banana");
jsonArray.append("Orange");

// 遍历数组
for (int i = 0; i < jsonArray.size(); ++i) {
    qDebug() << jsonArray.at(i).toString(); // 输出数组元素
}
  1. 删除
    在 Qt 的 QJsonArray 类中,可以使用以下方法来删除数组中的元素:

    1. removeAt(int index): 该方法用于删除指定索引位置上的元素。

    2. removeFirst()removeLast(): 这两个方法分别用于删除数组中的第一个元素和最后一个元素。

    3. removeAll(const QJsonValue &value): 该方法用于删除数组中所有与指定值相等的元素。

QJsonDocument

QJsonDocument 是 Qt 中用于表示和操作 JSON 文档的类,它提供了一种方便的方式来解析、创建和处理 JSON 数据。QJsonDocument 可以用于将 JSON 数据表示为树形结构,并提供了方法用于序列化和反序列化 JSON 数据,以及在应用程序中方便地访问和操作 JSON 数据。

以下是 QJsonDocument 主要的特性和用法:

  1. 解析 JSON 数据: 使用 QJsonDocument 类可以将来自字符串、文件或其他来源的 JSON 数据解析为一个 JSON 文档,便于应用程序进一步操作。
QByteArray jsonData = "{\"name\":\"Alice\", \"age\":25}";
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData);

// 如果数据解析成功
if (!jsonDoc.isNull()) {
    QJsonObject jsonObj = jsonDoc.object();
    qDebug() << "Name:" << jsonObj.value("name").toString();
    qDebug() << "Age:" << jsonObj.value("age").toInt();
}
  1. 序列化 JSON 数据: 可以使用 toJson() 方法将 QJsonDocument 转换为 JSON 格式的字节数组,方便用于存储或网络传输。
QJsonObject jsonObj;
jsonObj.insert("name", "Alice");
jsonObj.insert("age", 25);
QJsonDocument jsonDoc(jsonObj);

QByteArray jsonData = jsonDoc.toJson();
qDebug() << jsonData;
  1. 访问和操作 JSON 文档内容: 可以通过 QJsonDocument 提供的方法,如 object()、isArray() 和 isNull(),来获取文档中的 JSON 对象或数组,以及检查文档是否为空。
QJsonDocument jsonDoc = QJsonDocument::fromJson(someData);
if (!jsonDoc.isNull()) {
    if (jsonDoc.isObject()) {
        QJsonObject jsonObj = jsonDoc.object();
        // 处理 JSON 对象
    } else if (jsonDoc.isArray()) {
        QJsonArray jsonArray = jsonDoc.array();
        // 处理 JSON 数组
    }
}

QJsonDocument 类提供了一种方便的方式来解析、操作和序列化 JSON 数据,使得在 Qt 应用程序中处理 JSON 数据变得更加简单和灵活。通过使用 QJsonDocument,您可以方便地在应用程序中加载、保存和处理各种格式的 JSON 数据。

示例

{
    "name": "Alice",
    "age": 25,
    "isStudent": true,
    "hobbies": ["hiking", "reading"],
    "address": {
        "city": "New York",
        "zipCode": "10001"
    }
}

头文件:

#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QDebug>

将上述json对象写入文件:

 QJsonObject jsonObject;
 jsonObject.insert("name", "Alice");
 jsonObject.insert("age", 25);
 jsonObject.insert("isStudent", true);

 QJsonArray hobbiesArray;
 hobbiesArray.append("hiking");
 hobbiesArray.append("reading");
 jsonObject.insert("hobbies", hobbiesArray);

 QJsonObject addressObject;
 addressObject.insert("city", "New York");
 addressObject.insert(zipCode", "10001");
 jsonObject.insert("address", addressObject);

 QJsonDocument doc(jsonObject);

 QFile file("D:\\data.json");
 if(file.open(QFile::WriteOnly)){
 	QByteArray json = doc.toJson();
	file.write(json);
 	file.close();
 	 qDebug() << "JSON object has been written to" << fileName;
 } else {
     qDebug() << "Failed to open file for writing";
 }

从文件读取:

 QFile file("D:\\data.json");
 if (file.open(QFile::ReadOnly)) {
    QByteArray jsonData = file.readAll();//全部读取
    file.close();
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData);

	if(jsonDoc.isObject())
	{
	    QJsonObject obj = jsonDoc.object();
	    QStringList keys = obj.keys();
	    for(int i=0; i<keys.size(); ++i)
	    {
	        QString key = keys.at(i);
	        QJsonValue value = obj.value(key);
	        if(value.isBool())
	        {
	            qDebug() << key << ":" << value.toBool();
	        }
	        if(value.isString())
	        {
	            qDebug() << key << ":" << value.toString();
	        }
	        if(value.isDouble())
	        {
	            qDebug() << key << ":" << value.toInt();
	        }
	        if(value.isObject())
	        {
	            qDebug()<< key << ":";
	            QJsonObject subObj = value.toObject();
	            QStringList ls = subObj.keys();
	            for(int j=0; j<ls.size(); ++j)
	            {
	                QJsonValue subVal = subObj.value(ls.at(j));
	                qDebug() << "   " << ls.at(j) << ":" << subVal.toString();
	            }
	        }
	        if(value.isArray())
            {
                QJsonArray array = value.toArray();
                qDebug() << key << ":" ;
                for(int j=0; j<array.size(); ++j)
                {
                    qDebug() << "       " << array[j].toString();
                }
            }
	    }
	}
}
;