QT解析JSON

本文介绍如何在Qt应用程序中使用QtScript解析JSON数据,包括数组和单个对象的解析方法。
有时应用程序需要加载数据库中有用数据,目前交主流的就是动态语言创建JSON数据格式,然后应用程序可以解析。
1、在pro文件中添加script,如右: QT += script
2、需要添加头文件#include<QtScript>

3、代码如下,代码str1为json数组,str2为json单个对象的字符串。

#include "json.h"
#include <QApplication>
#include <QtScript>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Json w;
    w.show();
    QString str1 = "[{\"user\":\"hwb\"},{\"user\":\"zbh\"},{\"user\":\"zf\"}]";
    QString str2 = "{\"age\":\"26\"}";
    QScriptEngine engine;
    QScriptValue sc = engine.evaluate("value=" + str1);
    if(sc.isArray()) //解析数组
    {
        QScriptValueIterator it(sc);
        while (it.hasNext())
        {
            it.next();
            if(!it.value().property("user").toString().isEmpty())
            {
                qDebug()<<it.value().property("user").toString();
            }
        }
    }
    sc = engine.evaluate("value=" + str2);
    QScriptValueIterator it(sc);   //解析json数据
    if (it.hasNext())
    {
        it.next();
        qDebug()<<it.name()<<":"<<it.value().toString();
    }
    return a.exec();
}




<think> 我们正在讨论如何使用Qt解析JSON数据。根据引用,Qt从5.0开始提供了对JSON的支持,主要使用四个类:QJsonDocument、QJsonObject、QJsonArray和QJsonValue。以下将详细介绍解析步骤和方法。 ### 一、Qt JSON解析核心类 根据引用[1][3][4],Qt JSON解析主要依赖以下类: 1. **QJsonDocument**:读写JSON文档的接口,可将JSON数据转换为可操作对象[^1][^4] 2. **QJsonObject**:封装JSON对象(键值对集合),键为字符串,值为JSON支持的类型[^3] 3. **QJsonArray**:封装JSON数组(值的有序列表)[^4] 4. **QJsonValue**:封装JSON支持的数据类型(包括字符串、数字、布尔值、数组、对象等)[^1] ### 二、JSON解析步骤 参考引用[1][4]的代码示例,标准解析流程如下: #### 1. 读取原始JSON数据 ```cpp // 从网络回复读取数据(示例见引用[4]) QByteArray data = replay->readAll(); // 或直接使用字符串(示例见引用[5]) QString str = "{\"name\":\"xiaotang\", \"age\":\"23\"}"; QByteArray data = str.toUtf8(); ``` #### 2. 转换为QJsonDocument 使用`QJsonDocument::fromJson()`解析原始数据: ```cpp QJsonParseError jsonError; // 错误信息对象 QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); // 检查解析错误 if(jsonError.error != QJsonParseError::NoError) { qDebug() << "JSON格式错误:" << jsonError.errorString(); return; } ``` #### 3. 判断文档类型并获取根对象 JSON文档有两种类型:对象(`{}`)或数组(`[]`): ```cpp if(jsonDoc.isObject()) { // 根节点是对象 QJsonObject rootObj = jsonDoc.object(); parseObject(rootObj); // 自定义解析函数 } else if(jsonDoc.isArray()) { // 根节点是数组 QJsonArray rootArray = jsonDoc.array(); parseArray(rootArray); // 自定义解析函数 } ``` ### 三、数据提取方法 #### 1. 解析JSON对象(QJsonObject) 引用[3][4]展示了对象解析: ```cpp void parseObject(const QJsonObject &obj) { // 检查键是否存在 if(obj.contains("Name")) { // 获取值并判断类型 QJsonValue nameValue = obj.value("Name"); if(nameValue.isString()) { QString name = nameValue.toString(); qDebug() << "Name:" << name; // 输出: Name: "Qt" } } // 直接取值(简化版) int year = obj["From"].toInt(); // 直接转换为int bool crossPlatform = obj["Cross Platform"].toBool(); } ``` #### 2. 解析JSON数组(QJsonArray) 引用[5]中的数组解析示例: ```cpp // 解析引用[5]中的chi数组 QJsonArray chiArray = rootObj["chi"].toArray(); for(int i = 0; i < chiArray.size(); i++) { QJsonObject item = chiArray[i].toObject(); QString a = item["a"].toString(); // 输出: 第一项"aa", 第二项"aaa" QString b = item["b"].toString(); // 输出: 第一项"bb", 第二项"bbb" } ``` ### 四、完整解析示例(引用[4]网络请求场景) ```cpp void MainWindow::replyFinished(QNetworkReply* replay) { if(replay->error() == QNetworkReply::NoError) { QByteArray data = replay->readAll(); QJsonParseError jsonError; QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); if(jsonError.error == QJsonParseError::NoError) { if(jsonDoc.isObject()) { QJsonObject rootObj = jsonDoc.object(); if(rootObj.contains("weatherinfo")) { QJsonValue weatherValue = rootObj.value("weatherinfo"); if(weatherValue.isObject()) { QJsonObject weatherObj = weatherValue.toObject(); // 转换为QVariantMap便于使用 QVariantMap weatherMap = weatherObj.toVariantMap(); QString city = weatherMap["city"].toString(); qDebug() << "城市:" << city; } } } } } } ``` ### 五、常见错误处理 1. **键不存在时的处理** ```cpp // 安全取值方法 if(obj.contains("key") && obj["key"].isString()) { QString value = obj["key"].toString(); } ``` 2. **类型转换失败** ```cpp QJsonValue value = obj.value("age"); if(value.isString()) { // 即使数字也可能被解析为字符串 bool ok; int age = value.toString().toInt(&ok); if(!ok) qDebug() << "age转换失败"; } ``` 3. **嵌套对象/数组访问** ```cpp // 访问深层数据:data.list[0].id if(rootObj.contains("data") && rootObj["data"].isObject()) { QJsonObject dataObj = rootObj["data"].toObject(); if(dataObj.contains("list") && dataObj["list"].isArray()) { QJsonArray listArray = dataObj["list"].toArray(); if(listArray.size() > 0 && listArray[0].isObject()) { QJsonObject item = listArray[0].toObject(); int id = item["id"].toInt(); } } } ``` > **关键点**:Qt JSON解析采用链式安全访问,必须逐层检查类型和键是否存在[^4]。 ### 六、JSON生成方法 引用[3]展示了如何构建JSON: ```cpp // 创建JSON对象 QJsonObject json; json.insert("Name", "Qt"); json.insert("From", 2016); json.insert("Cross Platform", true); // 添加数组 QJsonArray versions; versions.append(5.9); versions.append(5.12); versions.append(6.0); json.insert("Versions", versions); // 转换为文档 QJsonDocument jsonDoc(json); QString jsonString = jsonDoc.toJson(); // 生成JSON字符串 ``` ### 性能优化建议 1. **避免大文件解析阻塞UI线程**:网络请求或大文件解析使用`QCoreApplication::processEvents()`分块处理 2. **减少临时对象**:尽量使用`const QJsonObject&`传递引用 3. **二进制存储**:对重复使用的JSON数据,用`jsonDoc.toBinaryData()`保存为二进制格式加快加载 §§相关问题§§ 1. Qt中如何实现JSON数据与自定义对象的相互转换? 2. 如何处理JSON解析中的编码问题(如中文乱码)? 3. Qt网络请求(QNetworkAccessManager)如何与JSON解析结合使用? [^1]: QT——JSON解析 [^2]: QT Json解析方法 [^3]: Qt--解析Json [^4]: Qt解析Json的总结 [^5]: Qt解析JSON数据 </think> ### Qt JSON解析方法详解 根据引用内容,Qt从5.0开始提供原生JSON支持,主要使用以下四个核心类进行解析: #### 一、关键JSON解析类 | 类名 | 功能 | 示例代码 | |------|------|----------| | `QJsonDocument` | JSON文档读写入口 | `QJsonDocument::fromJson(data, &error)`[^4] | | `QJsonObject` | 封装JSON对象(键值对集合) | `json.insert("Name", "Qt")`[^3] | | `QJsonArray` | 封装JSON数组(有序值列表) | `QJsonArray versions = {5.9, 5.12, 6.0}` | | `QJsonValue` | 封装JSON支持的数据类型 | `if(obj["weatherinfo"].isObject())`[^4] | #### 二、标准解析流程 1. **准备原始数据** ```cpp // 从网络获取(引用[4]示例) QByteArray data = replay->readAll(); // 或直接定义字符串(引用[5]示例) QString str = R"({"name":"xiaotang", "age":23, "languages":["C++", "Python"]})"; ``` 2. **转换为JSON文档** ```cpp QJsonParseError jsonError; // 错误处理对象 QJsonDocument jsonDoc = QJsonDocument::fromJson(data.toUtf8(), &jsonError); if(jsonError.error != QJsonParseError::NoError) { // 检查格式错误 qDebug() << "JSON格式错误:" << jsonError.errorString(); return; } ``` 3. **获取根对象/数组** ```cpp if(jsonDoc.isObject()) { // 根节点是对象 QJsonObject rootObj = jsonDoc.object(); parseObject(rootObj); } else if(jsonDoc.isArray()) { // 根节点是数组 QJsonArray rootArray = jsonDoc.array(); parseArray(rootArray); } ``` 4. **递归解析嵌套结构** ```cpp void parseObject(const QJsonObject &obj) { // 获取字符串值 if(obj.contains("name")) { QString name = obj["name"].toString(); qDebug() << "Name:" << name; } // 获取嵌套对象 if(obj.contains("weatherinfo") && obj["weatherinfo"].isObject()) { QJsonObject weather = obj["weatherinfo"].toObject(); parseObject(weather); // 递归解析 } // 获取数组 if(obj.contains("languages") && obj["languages"].isArray()) { QJsonArray langArray = obj["languages"].toArray(); for(const QJsonValue &val : langArray) { qDebug() << "Language:" << val.toString(); } } } ``` #### 三、完整网络请求解析示例 基于引用[4]的增强实现: ```cpp void handleNetworkReply(QNetworkReply* reply) { if(reply->error() == QNetworkReply::NoError) { QByteArray data = reply->readAll(); QJsonParseError jsonError; QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError); if(jsonError.error == QJsonParseError::NoError) { if(jsonDoc.isObject()) { QJsonObject root = jsonDoc.object(); if(root.contains("weatherinfo")) { QJsonObject weather = root["weatherinfo"].toObject(); // 安全提取数据 QString city = weather.value("city").toString("Unknown"); double temp = weather.value("temp").toDouble(0.0); qDebug() << city << "当前温度:" << temp << "℃"; } } } else { qWarning() << "JSON解析错误:" << jsonError.errorString(); } } else { qCritical() << "网络错误:" << reply->errorString(); } reply->deleteLater(); // 清理资源 } ``` #### 四、常见问题解决方案 1. **中文乱码处理** ```cpp // 设置全局编码(main函数中) QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); ``` 2. **类型安全访问** ```cpp // 安全获取值(避免崩溃) int age = obj.value("age").toInt(-1); // -1表示默认值 if(age == -1) qWarning() << "age字段缺失或类型错误"; ``` 3. **动态键名处理** ```cpp QStringList keys = obj.keys(); for(const QString &key : keys) { QJsonValue val = obj.value(key); if(val.isString()) { qDebug() << key << ":" << val.toString(); } } ``` #### 五、性能优化建议 1. **避免深度嵌套**:JSON层级不宜超过5层 2. **使用二进制格式**:频繁读写时用`QJsonDocument::toBinaryData()` 3. **异步解析**:大文件使用`QtConcurrent::run()`在后台线程解析 4. **内存管理**:及时释放`QNetworkReply`对象(`deleteLater()`) > 最佳实践:对于超过1MB的JSON文件,建议使用流式解析器(如`QJsonStreamReader`)替代DOM解析[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值