最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Qt QJsonDocument 的使用小結(jié)

 更新時間:2026年07月13日 10:01:00   作者:華麗的周遭  
Qt QJsonDocument 是 Qt 中處理 JSON 數(shù)據(jù)的核心容器類,本文輕松實現(xiàn)流媒體配置管理、設(shè)備狀態(tài)上報和固件更新,學(xué)會QJsonDocument,讓你在嵌入式Qt開發(fā)中高效處理JSON數(shù)據(jù)

一、QJsonDocument 概述

QJsonDocument是 Qt 中處理 JSON 數(shù)據(jù)的核心容器類,屬于 QtCore模塊(需包含頭文件 <QJsonDocument>,并在 .pro中添加 QT += core)。它的核心作用是:

  • 解析? JSON 字符串/字節(jié)流為結(jié)構(gòu)化的 Qt 對象(QJsonObject/QJsonArray);
  • 生成? JSON 字符串/字節(jié)流(從 QJsonObject/QJsonArray轉(zhuǎn)換);
  • 封裝? JSON 文檔的根元素(JSON 根必須是對象數(shù)組,不能是單個值)。

Qt 的 JSON 模塊是輕量級、隱式共享(Implicitly Shared)的,適合嵌入式場景,資源占用低且性能足夠。

二、核心功能與用法

1. 解析 JSON(從字符串/字節(jié)流到 Qt 對象)

使用靜態(tài)方法 QJsonDocument::fromJson()解析 JSON 數(shù)據(jù),需傳入UTF-8 編碼的 QByteArray(若源是 QString,需用 toUtf8()轉(zhuǎn)換)。

關(guān)鍵細(xì)節(jié):

  • 錯誤處理:通過 QJsonParseError結(jié)構(gòu)體獲取解析錯誤(如語法錯誤、非法字符);
  • 根元素判斷:解析后需用 isObject()/isArray()判斷根類型是對象還是數(shù)組。

示例:解析 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. 轉(zhuǎn)換為 UTF-8 字節(jié)流
    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

        // 讀取數(shù)組(status)
        QJsonArray statusArr = rootObj["status"].toArray();
        for (const QJsonValue &val : statusArr) {
            qDebug() << "狀態(tài):" << val.toString(); // "online", "recording"
        }
    }
}

2. 生成 JSON(從 Qt 對象到字符串/字節(jié)流)

使用 QJsonDocument::toJson()QJsonObject/QJsonArray轉(zhuǎn)換為 JSON 字符串,支持兩種格式:

  • QJsonDocument::Compact緊湊模式(無縮進(jìn),適合網(wǎng)絡(luò)傳輸);
  • QJsonDocument::Indented縮進(jìn)模式(帶換行和空格,適合日志/調(diào)試)。

示例:生成 JSON 配置?

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

void generateJsonExample() {
    // 1. 構(gòu)建嵌套的 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. 構(gòu)建根對象
    QJsonObject rootObj;
    rootObj["device"] = "Portable Monitor";
    rootObj["model"] = "PM-2024";
    rootObj["stream"] = streamObj; // 嵌套對象
    rootObj["features"] = QJsonArray::fromStringList({"HDMI", "USB-C", "WiFi"}); // 數(shù)組

    // 3. 封裝為 QJsonDocument(根元素是對象)
    QJsonDocument doc(rootObj);

    // 4. 轉(zhuǎn)換為 JSON 字符串(縮進(jìn)模式,方便閱讀)
    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()

默認(rèn)構(gòu)造(空文檔,isNull()/isEmpty()均為 true)

QJsonDocument(const QJsonObject&)

用 JSON 對象初始化(根為對象)

QJsonDocument(const QJsonArray&)

用 JSON 數(shù)組初始化(根為數(shù)組)

static QJsonDocument fromJson(const QByteArray&, QJsonParseError*)

解析 JSON 字節(jié)流,返回文檔+錯誤信息

QByteArray toJson(Format format = Compact)

轉(zhuǎn)換為 JSON 字節(jié)流(Compact/Indented)

bool isObject() const

根元素是否為 JSON 對象

bool isArray() const

根元素是否為 JSON 數(shù)組

QJsonObject object() const

獲取根對象(若根是數(shù)組,返回空對象)

QJsonArray array() const

獲取根數(shù)組(若根是對象,返回空數(shù)組)

bool isEmpty() const

文檔是否為空(默認(rèn)構(gòu)造或未初始化)

bool isNull() const

文檔是否無效(同 isEmpty(),部分版本差異可忽略)

void swap(QJsonDocument&)

交換兩個文檔的內(nèi)容(高效)

三、與其他 QJson 類的協(xié)作

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

類名

作用

QJsonValue

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

QJsonObject

JSON 對象(鍵值對集合,類似 std::map<QString, QJsonValue>)

QJsonArray

JSON 數(shù)組(有序值集合,類似 QList<QJsonValue>)

QJsonParseError

解析錯誤的詳細(xì)信息(error枚舉+offset錯誤位置)

關(guān)系鏈:

QJsonDocument→ 包含 QJsonObject/QJsonArray→ 包含 QJsonValue→ 對應(yīng) JSON 基本類型。

四、實際場景應(yīng)用

用 ZynqMP + Qt 開發(fā),流媒體是核心方向。QJsonDocument可用于以下場景:

1. 流媒體配置管理

用 JSON 存儲設(shè)備的流媒體參數(shù)(如 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調(diào)整屏幕亮度。

2. 設(shè)備狀態(tài)上報

將監(jiān)視器的實時狀態(tài)(如播放狀態(tài)、碼率、溫度、剩余電量)封裝為 JSON,通過 HTTP/MQTT 上報到服務(wù)器。

示例狀態(tài) JSON

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

生成后:用 QNetworkAccessManager發(fā)送 POST 請求。

3. 固件/配置更新

通過 JSON 描述更新包的信息(版本號、下載地址、校驗和),解析后觸發(fā) OTA 升級。

五、注意事項與常見問題

1. 編碼問題

JSON 標(biāo)準(zhǔn)要求UTF-8 編碼,QJsonDocument僅支持 UTF-8。若源數(shù)據(jù)是 GBK 等其他編碼,需先轉(zhuǎn)換為 UTF-8(用 QString::fromLocal8Bit()QTextCodec)。

2. 根元素限制

JSON 根必須是對象數(shù)組,不能直接是字符串/數(shù)字。若要存儲單個值,需用對象包裝:

// 錯誤:根是字符串
// QJsonDocument doc("hello"); 
// 正確:用對象包裝
QJsonObject obj;
obj["message"] = "hello";
QJsonDocument doc(obj);

3. 錯誤處理

解析前務(wù)必檢查 QJsonParseError

常見錯誤:QJsonParseError::IllegalValue(非法值)、QJsonParseError::MissingObject(缺少對象)、QJsonParseError::SyntaxError(語法錯誤)。

4. 性能優(yōu)化

  • 隱式共享QJsonDocument拷貝時是淺拷貝,修改時才深拷貝,避免不必要的內(nèi)存開銷;
  • 大文檔處理:若 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() 取默認(rèn)值
QString url = obj.value("stream_url").toString("rtsp://default.url");

六、擴(kuò)展:QVariant 與 JSON 的轉(zhuǎn)換

QJsonDocument提供 fromVariant()/toVariant()方法,可將 QVariantMap(對應(yīng) JSON 對象)、QVariantList(對應(yīng) JSON 數(shù)組)與 JSON 互轉(zhuǎn),簡化 Qt 數(shù)據(jù)結(jié)構(gòu)與 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();

總結(jié)

QJsonDocument是 Qt 處理 JSON 的核心入口,結(jié)合 QJsonObject/QJsonArray可輕松實現(xiàn) JSON 的解析與生成。

到此這篇關(guān)于Qt QJsonDocument 的使用小結(jié)的文章就介紹到這了,更多相關(guān)Qt QJsonDocument 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++?ROS與boost:bind()使用詳解

    C++?ROS與boost:bind()使用詳解

    boost::bind是標(biāo)準(zhǔn)庫函數(shù)std::bind1st和std::bind2nd的一種泛化形式,其可以支持函數(shù)對象、函數(shù)、函數(shù)指針、成員函數(shù)指針,并且綁定任意參數(shù)到某個指定值上或者將輸入?yún)?shù)傳入任意位置,本文重點介紹下C++?ROS與boost:bind(),感興趣的朋友跟隨小編一起看看吧
    2023-01-01
  • C語言實現(xiàn)用?*?打印X形圖案

    C語言實現(xiàn)用?*?打印X形圖案

    這篇文章主要介紹了C語言實現(xiàn)用?*?打印X形圖案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • c++11新增的便利算法實例分析

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

    這篇文章主要介紹了c++11新增的便利算法,主要有用于判斷、查找、數(shù)組、序列等的操作算法,非常具有實用價值,需要的朋友可以參考下
    2014-09-09
  • C++11 并發(fā)指南之多線程初探

    C++11 并發(fā)指南之多線程初探

    這篇文章主要介紹了C++11 并發(fā)指南之多線程初探,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • C++中stack的pop()函數(shù)返回值解析

    C++中stack的pop()函數(shù)返回值解析

    這篇文章主要介紹了C++中stack的pop()函數(shù)返回值,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C++?Boost?CircularBuffer算法超詳細(xì)精講

    C++?Boost?CircularBuffer算法超詳細(xì)精講

    Boost是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱
    2022-11-11
  • Matlab實現(xiàn)三維投影繪制的示例代碼

    Matlab實現(xiàn)三維投影繪制的示例代碼

    這篇文章系小編為大家?guī)砹艘粋€三維投影繪制函數(shù)(三視圖繪制),函數(shù)支持三維曲線、曲面、三維多邊形、參數(shù)方程曲線、參數(shù)方程曲面的投影繪制,需要的可以參考一下
    2022-08-08
  • C++設(shè)計模式之策略模式(Strategy)

    C++設(shè)計模式之策略模式(Strategy)

    這篇文章主要為大家詳細(xì)介紹了C++設(shè)計模式之策略模式Strategy ,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • C語言隨機(jī)數(shù)生成教程(rand和srand用法)

    C語言隨機(jī)數(shù)生成教程(rand和srand用法)

    這篇文章主要介紹了C語言隨機(jī)數(shù)生成教程(rand和srand用法),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 詳解C語言中的fopen()函數(shù)和fdopen()函數(shù)

    詳解C語言中的fopen()函數(shù)和fdopen()函數(shù)

    這篇文章主要介紹了詳解C語言中的fopen()函數(shù)和fdopen()函數(shù),注意其之間指針功能相關(guān)的區(qū)別,需要的朋友可以參考下
    2015-08-08

最新評論

盐源县| 曲沃县| 台中县| 科技| 大竹县| 昆山市| 常宁市| 高邑县| 博野县| SHOW| 奈曼旗| 陈巴尔虎旗| 上蔡县| 囊谦县| 偏关县| 乌鲁木齐市| 临清市| 新民市| 吉木萨尔县| 股票| 成都市| 石嘴山市| 囊谦县| 永定县| 肇源县| 西吉县| 神农架林区| 天峨县| 永丰县| 治多县| 安达市| 疏附县| 黄平县| 中牟县| 白沙| 肥城市| 安岳县| 苍山县| 周至县| 邵东县| 桂平市|