Qt中解析JSON文件

发布于:2025-09-14 ⋅ 阅读:(16) ⋅ 点赞:(0)

Qt中解析JSON文件

在Qt中解析JSON字符串主要有两种方式:使用QJsonDocument类或使用QJsonDocument结合QVariant。以下是详细的解析方法:

使用QJsonDocument(推荐)

这种方式的主要相关类如下:

QJsonDocument: QJsonDocument 是 Qt 中处理 JSON 数据的核心类,它提供了在内存中读写 JSON 文档的功能。

主要功能

  1. 解析 JSON:从 UTF-8 编码的文本创建 JSON 文档
  2. 生成 JSON:将内存中的 JSON 数据转换为字符串或二进制格式
  3. 数据访问:提供对 JSON 对象和数组的访问接口
  4. 格式转换:支持紧凑和缩进两种输出格式

QJsonObject:QJsonObject 是 Qt 中用于表示 JSON 对象的类,它存储键值对集合,其中键是字符串,值可以是各种 JSON 类型。

主要特性

  • 键值对存储:存储 QString 作为键,QJsonValue 作为值
  • 无序集合:键的顺序不保证与插入顺序一致
  • 隐式共享:使用写时复制技术,拷贝开销小
  • 类型安全:提供多种类型检查和转换方法

QJsonValue:

QJsonValue 是 Qt 中表示 JSON 值的类,它可以存储 JSON 标准支持的所有数据类型。它是 Qt JSON 系统的核心基础类。

主要特性

  • 多类型存储:可以存储 JSON 支持的所有数据类型
  • 值语义:拷贝和赋值操作是高效的(隐式共享)
  • 类型安全:提供严格的类型检查和转换方法
  • 空值和未定义值:支持 JSON null 和未定义值

支持的数据类型

QJsonValue 可以存储以下类型的值:

类型 描述 对应的 Qt 类型
Null JSON null 值 QJsonValue::Null
Bool 布尔值 bool
Double 双精度浮点数 double
String 字符串 QString
Array JSON 数组 QJsonArray
Object JSON 对象 QJsonObject
Undefined 未定义值(无效值) QJsonValue::Undefined

QJsonArray:

QJsonArray 是 Qt 中用于表示 JSON 数组的类,它存储有序的 QJsonValue 集合。JSON 数组是值的有序列表,可以包含不同类型的元素。

主要特性

  • 有序集合:元素保持插入顺序
  • 混合类型:可以存储不同类型的值
  • 隐式共享:使用写时复制技术,拷贝开销小
  • 动态大小:支持动态添加和删除元素
  • 索引访问:支持通过索引随机访问元素

下面我们就用进行简单的实战解析。

一、解析简单Json对象

#include <QCoreApplication>
#include<QJsonDocument>
#include<QJsonObject>
#include<QJsonValue>
#include<QJsonArray>

void PraseJson()
{
    QString strJson = R"({
           "name":"张三",
           "age":30,
           "isStudent":false
    })";

    QJsonDocument doc = QJsonDocument::fromJson(strJson.toUtf8());
    if(doc.isNull() || !doc.isObject())
    {
        qDebug() << "Json解析失败";
        return;
    }

    QJsonObject obj = doc.object();

    QString strName = obj["name"].toString();
    int nAge = obj["age"].toInt();
    bool bStudent = obj["isStudent"].toBool();

    qDebug() << "名字:" << strName;
    qDebug() << "年龄:" << nAge;
    qDebug() << "是否学生:" << bStudent;

}

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

    // Set up code that uses the Qt event loop here.
    // Call a.quit() or a.exit() to quit the application.
    // A not very useful example would be including
    // #include <QTimer>
    // near the top of the file and calling
    // QTimer::singleShot(5000, &a, &QCoreApplication::quit);
    // which quits the application after 5 seconds.

    // If you do not need a running Qt event loop, remove the call
    // to a.exec() or use the Non-Qt Plain C++ Application template.

    PraseJson();

    return a.exec();
}

代码运行结果:

wechat_2025-09-13_104418_550

二、解析嵌套Json对象

void PraseJson2()
{
    QString strJson = R"({
           "person":{
                "name":"李四",
                "address":{
                    "city":"北京",
                    "street":"长安街"
                }
            },
           "hobbies":["读书","音乐","运动"]
    })";

    QJsonDocument doc = QJsonDocument::fromJson(strJson.toUtf8());
    if(doc.isNull() || !doc.isObject())
    {
        qDebug() << "Json解析失败";
        return;
    }

    QJsonObject rootObj = doc.object();

    QJsonObject personObj = rootObj["person"].toObject();
    QJsonObject addressObj = personObj["address"].toObject();

    QString strName = personObj["name"].toString();
    qDebug() << "名字:" << strName;
    QString strCity = addressObj["city"].toString();
    qDebug() << "城市" << strCity;
    QString strStreet = addressObj["street"].toString();
    qDebug() << "街道:" << strStreet;

   QJsonArray arr = rootObj["hobbies"].toArray();
   qDebug() << "爱好:";
   for (const QJsonValue& value: arr)
   {
       qDebug() << value.toString();
   }

}

代码运行结果:

wechat_2025-09-13_112527_476

三、解析Json数组

void PraseJson3()
{
    QString strJson = R"([
    {"name":"王五","age":30},
    {"name":"赵六","age":35},
    {"name":"张三","age":20}
    ])";

    QJsonDocument doc = QJsonDocument::fromJson(strJson.toUtf8());
    if(doc.isNull())
    {
        qDebug() << "Json解析失败";
        return;
    }

    if(doc.isArray())
    {
        QJsonArray arr = doc.array();
        for(const QJsonValue& value:arr)
        {
            QJsonObject obj = value.toObject();
            qDebug() << "名字:"<< obj["name"].toString() << ",年龄:" << obj["age"].toInt();
        }
    }
}

代码运行结果:

wechat_2025-09-13_115755_115

四、错误处理

void parseJsonWithErrorHandling() {
    QString jsonString = R"({"invalid": json})"; // 无效的JSON
    
    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8(), &error);
    
    if (error.error != QJsonParseError::NoError) {
        qDebug() << "JSON解析错误:" << error.errorString();
        return;
    }
    
    if (doc.isNull()) {
        qDebug() << "文档为空";
        return;
    }
    
    // 安全地获取值
    QJsonObject obj = doc.object();
    QString value = obj.value("key").toString("默认值"); // 如果key不存在,返回默认值
    
    // 检查值类型
    if (obj.contains("key") && obj["key"].isString()) {
        // 安全处理
    }
}

五、构建Json对象

void createJson() {
    QJsonObject person;
    person["name"] = "张三";
    person["age"] = 30;
    
    QJsonArray hobbies;
    hobbies.append("读书");
    hobbies.append("游泳");
    hobbies.append("编程");
    person["hobbies"] = hobbies;
    
    QJsonObject address;
    address["city"] = "上海";
    address["street"] = "南京路";
    person["address"] = address;
    
    QJsonDocument doc(person);
    QString jsonString = doc.toJson(QJsonDocument::Indented);
    
    qDebug() << "生成的JSON:";
    qDebug() << jsonString;
}

代码运行结果:

wechat_2025-09-13_121120_222

注意事项

  1. 编码问题: 确保JSON字符串使用UTF-8编码
  2. 错误处理: 总是检查解析是否成功
  3. 类型安全: 在访问值之前检查其类型
  4. 内存管理: Qt的JSON类使用隐式共享,无需担心深拷贝性能问题

常用方法

  • QJsonDocument::fromJson() - 从字符串创建文档
  • QJsonObject::value() - 安全获取值(可指定默认值)
  • QJsonValue::toInt(), toString(), toBool() - 类型转换
  • QJsonObject::contains() - 检查键是否存在
  • QJsonValue::isObject(), isArray(), isString() - 检查值类型

: Qt的JSON类使用隐式共享,无需担心深拷贝性能问题