Qt QJsonDocument 的使用小结

 更新时间:2026年07月13日 10:01:00   作者:华丽的周遭  
Qt QJsonDocument 是 Qt 中处理 JSON 数据的核心容器类,本文轻松实现流媒体配置管理、设备状态上报和固件更新,学会QJsonDocument,让你在嵌入式Qt开发中高效处理JSON数据

一、QJsonDocument 概述

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

  • 解析​ JSON 字符串/字节流为结构化的 Qt 对象(QJsonObject/QJsonArray);
  • 生成​ JSON 字符串/字节流(从 QJsonObject/QJsonArray转换);
  • 封装​ JSON 文档的根元素(JSON 根必须是对象数组,不能是单个值)。

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

二、核心功能与用法

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

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

关键细节:

  • 错误处理:通过 QJsonParseError结构体获取解析错误(如语法错误、非法字符);
  • 根元素判断:解析后需用 isObject()/isArray()判断根类型是对象还是数组。

示例:解析 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 字符串,支持两种格式:

  • QJsonDocument::Compact紧凑模式(无缩进,适合网络传输);
  • QJsonDocument::Indented缩进模式(带换行和空格,适合日志/调试)。

示例:生成 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. 性能优化

  • 隐式共享QJsonDocument拷贝时是浅拷贝,修改时才深拷贝,避免不必要的内存开销;
  • 大文档处理:若 JSON 文档过大(如超过 10MB),建议用流式解析(Qt 未提供原生流式 API,可考虑第三方库如 simdjson),但嵌入式场景下很少遇到。

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 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++ ROS与boost:bind()使用详解

    C++ ROS与boost:bind()使用详解

    boost::bind是标准库函数std::bind1st和std::bind2nd的一种泛化形式,其可以支持函数对象、函数、函数指针、成员函数指针,并且绑定任意参数到某个指定值上或者将输入参数传入任意位置,本文重点介绍下C++ ROS与boost:bind(),感兴趣的朋友跟随小编一起看看吧
    2023-01-01
  • C语言实现用 * 打印X形图案

    C语言实现用 * 打印X形图案

    这篇文章主要介绍了C语言实现用 * 打印X形图案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • c++11新增的便利算法实例分析

    c++11新增的便利算法实例分析

    这篇文章主要介绍了c++11新增的便利算法,主要有用于判断、查找、数组、序列等的操作算法,非常具有实用价值,需要的朋友可以参考下
    2014-09-09
  • C++11 并发指南之多线程初探

    C++11 并发指南之多线程初探

    这篇文章主要介绍了C++11 并发指南之多线程初探,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • C++中stack的pop()函数返回值解析

    C++中stack的pop()函数返回值解析

    这篇文章主要介绍了C++中stack的pop()函数返回值,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • C++ Boost CircularBuffer算法超详细精讲

    C++ Boost CircularBuffer算法超详细精讲

    Boost是为C++语言标准库提供扩展的一些C++程序库的总称。Boost库是一个可移植、提供源代码的C++库,作为标准库的后备,是C++标准化进程的开发引擎之一,是为C++语言标准库提供扩展的一些C++程序库的总称
    2022-11-11
  • Matlab实现三维投影绘制的示例代码

    Matlab实现三维投影绘制的示例代码

    这篇文章系小编为大家带来了一个三维投影绘制函数(三视图绘制),函数支持三维曲线、曲面、三维多边形、参数方程曲线、参数方程曲面的投影绘制,需要的可以参考一下
    2022-08-08
  • C++设计模式之策略模式(Strategy)

    C++设计模式之策略模式(Strategy)

    这篇文章主要为大家详细介绍了C++设计模式之策略模式Strategy ,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-04-04
  • C语言随机数生成教程(rand和srand用法)

    C语言随机数生成教程(rand和srand用法)

    这篇文章主要介绍了C语言随机数生成教程(rand和srand用法),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • 详解C语言中的fopen()函数和fdopen()函数

    详解C语言中的fopen()函数和fdopen()函数

    这篇文章主要介绍了详解C语言中的fopen()函数和fdopen()函数,注意其之间指针功能相关的区别,需要的朋友可以参考下
    2015-08-08

最新评论