C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > Qt QJsonDocument

Qt QJsonDocument 的使用小结

作者:华丽的周遭

Qt QJsonDocument 是 Qt 中处理 JSON 数据的核心容器类,本文轻松实现流媒体配置管理、设备状态上报和固件更新,学会QJsonDocument,让你在嵌入式Qt开发中高效处理JSON数据

一、QJsonDocument 概述

QJsonDocument是 Qt 中处理 JSON 数据的核心容器类,属于 QtCore模块(需包含头文件 <QJsonDocument>,并在 .pro中添加 QT += core)。它的核心作用是:

Qt 的 JSON 模块是轻量级、隐式共享(Implicitly Shared)的,适合嵌入式场景,资源占用低且性能足够。

二、核心功能与用法

1. 解析 JSON(从字符串/字节流到 Qt 对象)

使用静态方法 QJsonDocument::fromJson()解析 JSON 数据,需传入UTF-8 编码的 QByteArray(若源是 QString,需用 toUtf8()转换)。

关键细节:

示例:解析 JSON 字符串

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

void parseJsonExample() {
    // 1. 待解析的 JSON 字符串(UTF-8)
    QString jsonStr = R"({
        "device": "Portable Monitor",
        "model": "PM-2024",
        "stream": {
            "url": "rtsp://192.168.1.100/live",
            "codec": "H265",
            "resolution": "1920x1080",
            "fps": 30
        },
        "status": ["online", "recording"]
    })";

    // 2. 转换为 UTF-8 字节流
    QByteArray jsonData = jsonStr.toUtf8();

    // 3. 解析并捕获错误
    QJsonParseError parseError;
    QJsonDocument doc = QJsonDocument::fromJson(jsonData, &parseError);

    if (parseError.error != QJsonParseError::NoError) {
        qDebug() << "JSON 解析失败:" << parseError.errorString() 
                 << "(位置:" << parseError.offset << ")";
        return;
    }

    // 4. 访问根元素(此处是对象)
    if (doc.isObject()) {
        QJsonObject rootObj = doc.object();

        // 读取简单键值
        QString device = rootObj["device"].toString(); // "Portable Monitor"
        QString model = rootObj["model"].toString();   // "PM-2024"

        // 读取嵌套对象(stream)
        QJsonObject streamObj = rootObj["stream"].toObject();
        QString rtspUrl = streamObj["url"].toString();       // "rtsp://..."
        QString codec = streamObj["codec"].toString();       // "H265"
        int fps = streamObj["fps"].toInt();                   // 30

        // 读取数组(status)
        QJsonArray statusArr = rootObj["status"].toArray();
        for (const QJsonValue &val : statusArr) {
            qDebug() << "状态:" << val.toString(); // "online", "recording"
        }
    }
}

2. 生成 JSON(从 Qt 对象到字符串/字节流)

使用 QJsonDocument::toJson()QJsonObject/QJsonArray转换为 JSON 字符串,支持两种格式:

示例:生成 JSON 配置

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

void generateJsonExample() {
    // 1. 构建嵌套的 JSON 对象(模拟流媒体配置)
    QJsonObject streamObj;
    streamObj["url"] = "rtsp://192.168.1.101/preview";
    streamObj["codec"] = "H264";
    streamObj["resolution"] = "1280x720";
    streamObj["fps"] = 25;
    streamObj["protocol"] = "TCP"; // 流媒体常用 TCP/UDP

    // 2. 构建根对象
    QJsonObject rootObj;
    rootObj["device"] = "Portable Monitor";
    rootObj["model"] = "PM-2024";
    rootObj["stream"] = streamObj; // 嵌套对象
    rootObj["features"] = QJsonArray::fromStringList({"HDMI", "USB-C", "WiFi"}); // 数组

    // 3. 封装为 QJsonDocument(根元素是对象)
    QJsonDocument doc(rootObj);

    // 4. 转换为 JSON 字符串(缩进模式,方便阅读)
    QByteArray jsonData = doc.toJson(QJsonDocument::Indented);
    QString jsonStr = QString::fromUtf8(jsonData);

    qDebug() << "生成的 JSON:\n" << jsonStr;
    /* 输出:
    {
        "device": "Portable Monitor",
        "features": ["HDMI", "USB-C", "WiFi"],
        "model": "PM-2024",
        "stream": {
            "codec": "H264",
            "fps": 25,
            "protocol": "TCP",
            "resolution": "1280x720",
            "url": "rtsp://192.168.1.101/preview"
        }
    }
    */
}

3. 核心方法与属性

方法/属性

说明

QJsonDocument()

默认构造(空文档,isNull()/isEmpty()均为 true)

QJsonDocument(const QJsonObject&)

用 JSON 对象初始化(根为对象)

QJsonDocument(const QJsonArray&)

用 JSON 数组初始化(根为数组)

static QJsonDocument fromJson(const QByteArray&, QJsonParseError*)

解析 JSON 字节流,返回文档+错误信息

QByteArray toJson(Format format = Compact)

转换为 JSON 字节流(Compact/Indented)

bool isObject() const

根元素是否为 JSON 对象

bool isArray() const

根元素是否为 JSON 数组

QJsonObject object() const

获取根对象(若根是数组,返回空对象)

QJsonArray array() const

获取根数组(若根是对象,返回空数组)

bool isEmpty() const

文档是否为空(默认构造或未初始化)

bool isNull() const

文档是否无效(同 isEmpty(),部分版本差异可忽略)

void swap(QJsonDocument&)

交换两个文档的内容(高效)

三、与其他 QJson 类的协作

QJsonDocument是容器,需配合以下类完成完整的 JSON 处理:

类名

作用

QJsonValue

JSON 基本值的封装(null/bool/int/double/string/object/array)

QJsonObject

JSON 对象(键值对集合,类似 std::map<QString, QJsonValue>)

QJsonArray

JSON 数组(有序值集合,类似 QList<QJsonValue>)

QJsonParseError

解析错误的详细信息(error枚举+offset错误位置)

关系链:

QJsonDocument→ 包含 QJsonObject/QJsonArray→ 包含 QJsonValue→ 对应 JSON 基本类型。

四、实际场景应用

用 ZynqMP + Qt 开发,流媒体是核心方向。QJsonDocument可用于以下场景:

1. 流媒体配置管理

用 JSON 存储设备的流媒体参数(如 RTSP 地址、编码格式、分辨率),通过 QJsonDocument解析后配置播放器。

示例配置 JSON

{
    "stream": {
        "input": "rtsp://admin:123@192.168.1.100/stream1",
        "decoder": "H265",
        "resolution": "1920x1080",
        "fps": 30,
        "buffer_size": 1024
    },
    "display": {
        "brightness": 70,
        "contrast": 50,
        "fullscreen": false
    }
}

解析后:提取 stream.input给 GStreamer/FFmpeg 播放器,display.brightness调整屏幕亮度。

2. 设备状态上报

将监视器的实时状态(如播放状态、码率、温度、剩余电量)封装为 JSON,通过 HTTP/MQTT 上报到服务器。

示例状态 JSON

{
    "device_id": "PM-2024-001",
    "timestamp": 1718236800,
    "status": {
        "play_state": "playing",
        "bitrate": 2048,
        "fps": 29.97,
        "temperature": 45,
        "battery": 80
    }
}

生成后:用 QNetworkAccessManager发送 POST 请求。

3. 固件/配置更新

通过 JSON 描述更新包的信息(版本号、下载地址、校验和),解析后触发 OTA 升级。

五、注意事项与常见问题

1. 编码问题

JSON 标准要求UTF-8 编码QJsonDocument仅支持 UTF-8。若源数据是 GBK 等其他编码,需先转换为 UTF-8(用 QString::fromLocal8Bit()QTextCodec)。

2. 根元素限制

JSON 根必须是对象数组,不能直接是字符串/数字。若要存储单个值,需用对象包装:

// 错误:根是字符串
// QJsonDocument doc("hello"); 
// 正确:用对象包装
QJsonObject obj;
obj["message"] = "hello";
QJsonDocument doc(obj);

3. 错误处理

解析前务必检查 QJsonParseError

常见错误:QJsonParseError::IllegalValue(非法值)、QJsonParseError::MissingObject(缺少对象)、QJsonParseError::SyntaxError(语法错误)。

4. 性能优化

5. 键不存在的处理

访问 QJsonObject的不存在的键时,返回无效的 QJsonValueisUndefined()true)。需用以下方式安全取值:

QJsonObject obj = ...;
// 方法1:先判断键存在
if (obj.contains("stream_url")) {
    QString url = obj["stream_url"].toString();
}
// 方法2:用 value() 取默认值
QString url = obj.value("stream_url").toString("rtsp://default.url");

六、扩展:QVariant 与 JSON 的转换

QJsonDocument提供 fromVariant()/toVariant()方法,可将 QVariantMap(对应 JSON 对象)、QVariantList(对应 JSON 数组)与 JSON 互转,简化 Qt 数据结构与 JSON 的交互:

// QVariantMap → JSON
QVariantMap config;
config["device"] = "PM-2024";
config["stream_url"] = "rtsp://...";
QJsonDocument doc = QJsonDocument::fromVariant(config);
// JSON → QVariantMap
QVariantMap config2 = doc.toVariant().toMap();

总结

QJsonDocument是 Qt 处理 JSON 的核心入口,结合 QJsonObject/QJsonArray可轻松实现 JSON 的解析与生成。

到此这篇关于Qt QJsonDocument 的使用小结的文章就介绍到这了,更多相关Qt QJsonDocument 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文