一、JSON格式介绍

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。

1、核心特点

  1. 轻量级: 相较于 XML 等其他数据格式,JSON 的结构更简洁,冗余更少。
  2. 文本格式: 基于纯文本,独立于编程语言,但使用了 JavaScript 对象字面量的语法。
  3. 可读性好: 结构清晰,格式简洁,便于人类理解和修改。
  4. 易于解析和生成: 各种编程语言都提供了简单易用的库来解析 JSON 字符串或生成 JSON 数据。

2、基本数据结构

JSON 主要使用两种结构来表示数据:

  1. 对象(Object):

    • 表示为一对大括号 {} 包围的无序集合。
    • 集合由逗号分隔的 键值对 组成。
    • 键(Key) 必须是一个用双引号 " " 包围的字符串
    • 值(Value) 可以是字符串、数值、布尔值、null、对象或数组。
    • 格式:{ "key1": value1, "key2": value2, ... }
    • 示例:
      {
      "name": "张三",
      "age": 30,
      "isStudent": false
      }
  2. 数组(Array):

    • 表示为一对方括号 [] 包围的有序集合。
    • 集合由逗号分隔的组成。
    • 值可以是字符串、数值、布尔值、null、对象或数组。
    • 格式:[ value1, value2, ... ]
    • 示例:
      ["苹果", "香蕉", "橙子"]
      [1, 2, 3, 4, 5]
      [
      {"name": "李四", "age": 25},
      {"name": "王五", "age": 28}
      ]

3、数据类型

JSON 值可以是以下数据类型:

  • 字符串(String): 必须用双引号 " " 包围。例如:"Hello, World!"
  • 数值(Number): 整数或浮点数。例如:42, 3.14159
  • 布尔值(Boolean):truefalse(必须小写)。
  • 空值(Null):null(必须小写)。
  • 对象(Object): 如上所述。
  • 数组(Array): 如上所述。

4、语法规则

  • 数据以键值对的形式组织。
  • 键名(Key)必须是字符串,用双引号包裹。
  • 值(Value)可以是字符串、数字、布尔值、数组、对象或 null。
  • 数据由逗号分隔。
  • 大括号 {} 保存对象。
  • 方括号 [] 保存数组。

5、一个综合示例

{
"user": {
"name": "赵六",
"age": 35,
"address": {
"street": "科技路",
"city": "北京",
"country": "中国"
},
"isMarried": true,
"hobbies": ["阅读", "旅行", "摄影"],
"children": null
}
}

6、主要用途

  • Web 应用程序的数据交换: 客户端(浏览器)和服务器之间传输数据(AJAX)。
  • 配置文件: 许多软件使用 JSON 格式存储配置信息。
  • API 接口: RESTful API 常使用 JSON 作为请求和响应的数据格式。
  • NoSQL 数据库: 如 MongoDB 存储文档数据。
  • 序列化数据: 将复杂的数据结构转换为字符串以便存储或传输。

7、注意事项

  • JSON 不支持注释。不能在 JSON 文件中添加注释。
  • 字符串必须使用双引号,单引号无效。
  • 键名也必须使用双引号
  • JSON 文件通常使用 .json 作为扩展名。

二、相关类介绍

在Qt中,JSON数据的解析主要通过以下核心类实现:


1、QJsonDocument

功能:处理完整的JSON文档,提供JSON数据的序列化与反序列化。
关键方法

  • fromJson():将JSON字符串解析为QJsonDocument对象。
  • toJson():将QJsonDocument转换为JSON字符串。
  • isObject() / isArray():判断文档类型(对象或数组)。
  • object() / array():获取文档中的QJsonObjectQJsonArray
QString jsonStr = R"({"name": "Qt", "version": 6})";
QJsonDocument doc = QJsonDocument::fromJson(jsonStr.toUtf8());
if (doc.isObject()) {
QJsonObject obj = doc.object();
QString name = obj["name"].toString(); // "Qt"
}

2、QJsonObject

功能:表示JSON中的对象(键值对集合)。
关键方法

  • insert(key, value):插入键值对。
  • value(key):获取指定键的值(返回QJsonValue)。
  • keys():获取所有键的列表。
  • remove(key):删除指定键。
QJsonObject obj;
obj.insert("language", "C++");
obj.insert("framework", "Qt");
// 遍历对象
for (const QString& key : obj.keys()) {
qDebug() << key << ":" << obj[key].toString();
}

3、QJsonArray

功能:表示JSON中的数组(有序值列表)。
关键方法

  • append(value):向数组末尾添加值。
  • at(index):获取索引处的值(返回QJsonValue)。
  • size():获取数组长度。
  • removeAt(index):删除指定索引的值。
QJsonArray arr;
arr.append(42);
arr.append("Qt6");
// 遍历数组
for (int i = 0; i < arr.size(); ++i) {
if (arr.at(i).isString()) {
qDebug() << arr.at(i).toString();
}
}

4、 QJsonValue

功能:封装JSON中的单一值(字符串、数字、布尔值、对象、数组等)。
关键方法

  • toBool() / toString() / toDouble():转换为基本类型。
  • toObject() / toArray():转换为QJsonObjectQJsonArray
  • isNull() / isUndefined():检查值类型。
QJsonValue val = obj.value("version");
if (val.isDouble()) {
int version = val.toInt(); // 6
}

5、QJsonParseError

功能:在解析JSON时捕获错误信息。
关键属性

  • error:错误类型(如NoErrorUnterminatedObject)。
  • offset:错误在字符串中的位置。
QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(jsonStr, &error);
if (error.error != QJsonParseError::NoError) {
qDebug() << "JSON解析错误:" << error.errorString();
}

三、示例

1、效果展示

在这里插入图片描述

2、源码分享

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QCoreApplication>
  #include <QJsonDocument>
    #include <QJsonObject>
      #include <QJsonArray>
        #include <QJsonValue>
          #include <QDebug>
            #include <QFile>
              MainWindow::MainWindow(QWidget *parent)
              : QMainWindow(parent)
              , ui(new Ui::MainWindow)
              {
              ui->setupUi(this);
              // 安装自定义消息处理器
              void myMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg);
              qInstallMessageHandler(myMessageHandler);
              }
              MainWindow::~MainWindow()
              {
              delete ui;
              }
              void MainWindow::on_pushButton_clicked()
              {
              // 创建复杂JSON结构
              QJsonObject root;
              root.insert("projectName", "Qt6 JSON Demo");
              root.insert("version", 6.2);
              root.insert("active", true);
              // 创建嵌套对象
              QJsonObject author;
              author.insert("name", "Zhang San");
              author.insert("email", "zhangsan@example.com");
              author.insert("department", "R&D");
              root.insert("author", author);
              // 创建对象数组
              QJsonArray dependencies;
              QJsonObject dep1;
              dep1.insert("name", "QtCore");
              dep1.insert("version", "6.2.4");
              QJsonObject dep2;
              dep2.insert("name", "QtNetwork");
              dep2.insert("version", "6.2.4");
              dep2.insert("optional", true);
              dependencies.append(dep1);
              dependencies.append(dep2);
              root.insert("dependencies", dependencies);
              // 创建配置对象
              QJsonObject config;
              config.insert("maxThreads", 8);
              config.insert("timeout", 5000);
              QJsonArray allowedIPs;
              allowedIPs.append("192.168.1.1");
              allowedIPs.append("10.0.0.0/24");
              config.insert("allowedIPs", allowedIPs);
              root.insert("config", config);
              // 转换为JSON文档
              QJsonDocument doc(root);
              QString jsonString = doc.toJson(QJsonDocument::Indented);
              qDebug() << "Generated JSON:\n" << jsonString;
              // 解析JSON
              QJsonParseError parseError;
              QJsonDocument parsedDoc = QJsonDocument::fromJson(jsonString.toUtf8(), &parseError);
              if (parseError.error != QJsonParseError::NoError) {
              qDebug() << "Parse error:" << parseError.errorString();
              return;
              }
              if (!parsedDoc.isObject()) {
              qDebug() << "Document is not an object";
              return;
              }
              QJsonObject rootObj = parsedDoc.object();
              // 提取顶层数据
              QString projectName = rootObj["projectName"].toString();
              double version = rootObj["version"].toDouble();
              bool isActive = rootObj["active"].toBool();
              qDebug() << "\nProject:" << projectName;
              qDebug() << "Version:" << version;
              qDebug() << "Active:" << (isActive ? "Yes" : "No");
              // 解析嵌套对象
              if (rootObj.contains("author") && rootObj["author"].isObject()) {
              QJsonObject authorObj = rootObj["author"].toObject();
              qDebug() << "\nAuthor:" << authorObj["name"].toString()
              << "| Email:" << authorObj["email"].toString();
              }
              // 解析数组
              if (rootObj.contains("dependencies") && rootObj["dependencies"].isArray()) {
              QJsonArray depArray = rootObj["dependencies"].toArray();
              qDebug() << "\nDependencies:";
              for (int i = 0; i < depArray.size(); ++i) {
              if (depArray[i].isObject()) {
              QJsonObject dep = depArray[i].toObject();
              QString name = dep["name"].toString();
              QString version = dep["version"].toString();
              bool optional = dep.contains("optional") ? dep["optional"].toBool() : false;
              qDebug() << " -" << name << version << "(Optional:" << optional << ")";
              }
              }
              }
              // 解析复杂配置
              if (rootObj.contains("config") && rootObj["config"].isObject()) {
              QJsonObject configObj = rootObj["config"].toObject();
              qDebug() << "\nConfiguration:";
              qDebug() << "Max Threads:" << configObj["maxThreads"].toInt();
              qDebug() << "Timeout:" << configObj["timeout"].toInt() << "ms";
              if (configObj.contains("allowedIPs") && configObj["allowedIPs"].isArray()) {
              QJsonArray ipArray = configObj["allowedIPs"].toArray();
              qDebug() << "Allowed IPs:";
              for (const QJsonValue &ip : ipArray) {
              if (ip.isString()) {
              qDebug() << "  *" << ip.toString();
              }
              }
              }
              }
              }

在这里插入图片描述