Qt C++ :QJson使用详解

文章目录


Json的基本概念

Json 是一种数据格式,和语言无关,在什么语言中都可以使用 Json

Json中主要两种数据格式:Json数组Json对象

Json数组

  • Json数组使用 [] 表示,[] 里边是元素,元素和元素之间使用逗号间隔,最后一个元素后边没有逗号。
  • Json支持多种数据类型,包括:整形、 浮点型、 字符串、 布尔类型、 json数组、 json对象、 空值-null。
  • Json数组嵌套使用,Json数组中可以有Json数组。

Json对象

  • Json 对象使用 {} 来描述,每个 Json 对象中可以存储若干个元素,每一个元素对应一个键值(key:value 结构) 。
  • key 值必须是字符串,位于同一层级的键值不能重复(因为是通过键值取出对应的 value 值)。
  • value 值的类型是可选的,可根据实际需求指定,可用类型包括:整形、 浮点、 字符串、 布尔类型、 json数组、 json对象、 空值-null。

Qt 中 QJson 的核心类

Qt 提供了以下主要类用于处理 JSON:
QJsonDocument:表示整个 JSON 文档,是解析和生成 JSON 的入口。
QJsonObject:表示 JSON 对象(键值对集合,类似 std::map<QString, QJsonValue>)。
QJsonArray:表示 JSON 数组(有序的 QJsonValue 列表)。
QJsonValue:表示 JSON 中的一个值(可以是字符串、数字、布尔、null、对象或数组)。

所有字符串必须是 UTF-8 编码。

解析 JSON 字符串(反序列化)

cpp 复制代码
QString jsonString = R"({"name": "Alice", "age": 30, "hobbies": ["reading", "coding"]})";

QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8());
if (!doc.isNull() && doc.isObject()) {
    QJsonObject obj = doc.object();

    QString name = obj["name"].toString();
    int age = obj["age"].toInt();
    
    QJsonArray hobbies = obj["hobbies"].toArray();
    for (const QJsonValue &value : hobbies) {
        qDebug() << value.toString();
    }
}

注意:fromJson() 返回的文档若无效(如格式错误),isNull() 为 true。

生成 JSON 字符串(序列化)

cpp 复制代码
QJsonObject obj;
obj["name"] = "Bob";
obj["age"] = 25;

QJsonArray hobbies;
hobbies.append("gaming");
hobbies.append("music");
obj["hobbies"] = hobbies;

QJsonDocument doc(obj);
QString jsonString = QString::fromUtf8(doc.toJson(QJsonDocument::Compact));
// 或使用 QJsonDocument::Indented 输出带缩进的格式

QJsonDocument::toJson() 默认输出带换行和缩进,可用 QJsonDocument::Compact 减少体积。

嵌套结构处理示例

cpp 复制代码
// 构造 {"user": {"id": 1, "profile": {"email": "a@example.com"}}}
QJsonObject profile;
profile["email"] = "a@example.com";

QJsonObject user;
user["id"] = 1;
user["profile"] = profile;

QJsonObject root;
root["user"] = user;

解析时同样逐层访问:

cpp 复制代码
QJsonValue userVal = root["user"];
if (userVal.isObject()) {
    QJsonObject userObj = userVal.toObject();
    int id = userObj["id"].toInt();
    QJsonObject profileObj = userObj["profile"].toObject();
    QString email = profileObj["email"].toString();
}

判断值类型与安全访问

QJsonValue 提供类型判断方法:

cpp 复制代码
QJsonValue val = obj["key"];
if (val.isString()) { ... }
if (val.isDouble()) { ... } // 注意:整数在 JSON 中也是 double 类型
if (val.isArray()) { ... }
if (val.isObject()) { ... }
if (val.isNull()) { ... }   // 表示 null 或 key 不存在(需注意区别)

注意:如果访问一个不存在的 key,QJsonValue 会返回 QJsonValue::Undefined,其 isNull() 返回 false,但 isUndefined() 为 true。建议先用 contains() 检查 key 是否存在:

cpp 复制代码
if (obj.contains("name")) {
    QString name = obj["name"].toString();
}

错误处理建议

使用 QJsonParseError 获取解析错误详情:

cpp 复制代码
QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(jsonData, &error);
if (doc.isNull()) {
    qDebug() << "JSON 解析错误:" << error.errorString()
             << "位置:" << error.offset;
}
相关推荐
智者知已应修善业1 小时前
【51单片机不用数组动态数码管显示字符和LED流水灯】2023-10-3
c++·经验分享·笔记·算法·51单片机
AI进化营-智能译站2 小时前
ROS2 C++开发系列16-智能指针管理传感器句柄|告别ROS2节点内存泄漏与野指针
java·c++·算法·ai
报错小能手2 小时前
好好讲讲移动构造 移动赋值
c++
syker2 小时前
AIFerric深度学习框架:自研全栈AI基础设施的技术全景
开发语言·c++
xvhao20133 小时前
单源、多源最短路
数据结构·c++·算法·深度优先·动态规划·图论·图搜索算法
笑鸿的学习笔记4 小时前
qt-C++语法笔记之Qt Graphics View 框架中的类型辨析完全指南
c++·笔记·qt
山居秋暝LS4 小时前
安装C++版opencv和opencv_contrib
开发语言·c++·opencv
谭欣辰5 小时前
LCS(最长公共子序列)详解
开发语言·c++·算法
Cando学算法5 小时前
鸽笼原理(抽屉原理)
c++·算法·学习方法
郝学胜-神的一滴6 小时前
跨平台动态库与头文件:从原理到命名的深度解析
linux·c++·程序人生·unix·cmake