Qt中JSON操作的具體使用
JSON(JavaScript Object Notation,js對象標記)是一種輕量級的數(shù)據(jù)交換格式。它基于ECMAScript的一個子集,使用完全獨立于編程語言的文本格式來存儲和表示數(shù)據(jù)。簡潔和清晰的的層次結(jié)構(gòu)使得JSON成為理想的數(shù)據(jù)交換語言。易于人閱讀和編寫,同時也易于機器解析和生成,并有效的提升網(wǎng)絡(luò)傳輸效率。關(guān)于JSON的更多解釋,請參看JSON官網(wǎng)。
在Qt庫中,為JSON的相關(guān)操作提供了完整的類支持,包括QJsonValue,QJsonObject,QJsonArray,QJsonDocument和QJsonParseError。其中,QJsonValue類表示json格式中的一個值;QJsonObject表示一個json對象;QJsonArray顧名思義表示一個json數(shù)組;QJsonDocument主要用來讀寫json文檔;而QJsonParseError是用來表示json解析過程中出現(xiàn)的錯誤的方便類。下面,我們就來看看這些類的詳細信息。
QJsonValue
QJsonValue類封裝了一個json格式中的值。該值可以是如下6中基本類型:
- bool QJsonValue::Bool
- double QJsonValue::Double
- string QJsonValue::String
- array QJsonValue::Array
- object QJsonValue::Object
- null QJsonValue::Null
一個QJsonValue可以表示上面任何一種數(shù)據(jù)類型。此外,QJsonValue還有一個特殊的標志用來表示未定義的值。可以使用isUndefined()函數(shù)來進行判斷。而一個QJsonValue中存儲的類型可以通過type()或isBool(),isString()之類的函數(shù)進行查詢。同樣,QJsonValue中存儲的值可以通過toBool(),toString()等函數(shù)轉(zhuǎn)換到具體的類型。
QJsonValue中存儲的值在內(nèi)部是強類型的,并且和QVariant相反,它不會嘗試進行任何的隱式類型轉(zhuǎn)換。這意味著將QJsonValue轉(zhuǎn)換成一個不是它存儲的類型,將返回一個該類型的模型構(gòu)造函數(shù)返回的值。
其實,說到QJsonValue,還有另一個類要說,QJsonValueRef,該類是一個對于QJsonArray和QJsonObject來說的一個幫助類。當你獲得一個QJsonValueRef類的對象后,你可以把它當做一個QJsonValue對象的應(yīng)用來使用。如果你向他賦值,該值會實際作用到底層的QJsonArray或者QJsonObject對象中的元素上。而要想使用該類,可以使用一下的兩個方法:
- QJsonArray::operator[](int i)
- QJsonObject::operator[](const QString& key)const;
下面來看一下QJsonValue的構(gòu)造函數(shù):
QJsonValue(Type type = Null) QJsonValue(bool b) QJsonValue(double n) QJsonValue(int n) QJsonValue(qint64 n) QJsonValue(const QString &s) QJsonValue(QLatin1String s) QJsonValue(const char *s) QJsonValue(const QJsonArray &a) QJsonValue(const QJsonObject &o) QJsonValue(const QJsonValue &other)
可以看到,該類主要是對基本類型的一個包裝。
QJsonObject
QJsonObject類封裝了一個json對象。一個json對象是一個鍵值對的列表,其中key是唯一的字符串,而值就是一個我們上面講到的QJsonValue。一個QJsonObject的對象可以轉(zhuǎn)換到QVariantMap,要可以由QVariantMap轉(zhuǎn)換得到。 我們可以使用size()函數(shù)來查詢一個QJsonObject中存儲的鍵值對的個數(shù);使用insert()和remove()來插入或從中刪除鍵值對;還可以使用標準的C++迭代器來遍歷它。 QJsonObject類是一個隱式共享類。 其構(gòu)造函數(shù)如下:
QJsonObject object
{
{"property1", 1},
{"property2", 2}
};我們可以使用初始化列表來快速的構(gòu)建一個QJsonObject對象。如下:
QJsonObject object
{
{"property1", 1},
{"property2", 2}
};如此之外,比較常用的就是insert()函數(shù)了:
iterator QJsonObject::insert(const QString &key, const QJsonValue &value)
一般,我們可以先定義一個空的QJsonObject對象,然后使用該函數(shù)向其中插入需要的鍵值對。如果新插入的key已存在,那么會進行替換。
下面,我們通過一個例子還使用該類構(gòu)造如下json字符串:{"name":"lily", "age":23, "addr":{"city":"xxx", "province":"yyy"}} 代碼如下:
#include <QCoreApplication>
#include <QDebug>
#include <QJsonObject>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QJsonObject obj;
obj.insert("name", "lily");
obj.insert("age", 23);
QJsonObject addr;
addr.insert("city", "guangzhou");
addr.insert("province", "guangdong");
obj.insert("addr", addr);
qDebug() << obj;
return a.exec();
}我們先構(gòu)建了一個QJsonObject對象obj,然后向其中插入姓名和年齡鍵值對;因為地址又是一個QJsonObject,所以我們又構(gòu)建了addr對象,向其中插入城市和省份,最后,將該QJsonObject做為地址鍵值對的值,插入到obj中。打印結(jié)果如下:

QJsonArray
顧名思義,QJsonArray封裝了一個JSON數(shù)組。一個JSON數(shù)組是一個值的列表。我們可以向這個列表中插入或刪除QJsonValue。
同時,我們可以把一個QVariantList轉(zhuǎn)換成一個QJsonArray。也可以使用標準C++迭代器對它進行遍歷。 其構(gòu)造函數(shù)如下:
QJsonArray() QJsonArray(std::initializer_list<QJsonValue> args) QJsonArray(const QJsonArray &other)
我們也可以像上面那樣,使用一個初始化列表來構(gòu)建一個QJsonArray對象:
QJsonArray array = { 1, 2.2, QString() };在此我們只使用了單個的值,沒有使用鍵值對。其實,這樣的json對象,一般我們就稱為數(shù)組。
和QJsonObject一樣,我們一般也是通過它的insert()函數(shù)來生成我們需要的json數(shù)組:
void insert(int i, const QJsonValue &value) iterator insert(iterator before, const QJsonValue &value)
下面,我們繼續(xù)上面的例子,來生成一個表示人物信息的列表。代碼如下:
#include <QCoreApplication>
#include <QDebug>
#include <QJsonObject>
#include <QJsonArray>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QJsonObject obj1;
obj1.insert("name", "lily");
obj1.insert("age", 23);
QJsonObject addr1;
addr1.insert("city", "guangzhou");
addr1.insert("province", "guangdong");
obj1.insert("addr", addr1);
qDebug() << obj1;
QJsonObject obj2;
obj2.insert("name", "tom");
obj2.insert("age", 24);
QJsonObject addr2;
addr2.insert("city", "shenzhen");
addr2.insert("province", "guangdong");
obj2.insert("addr", addr2);
qDebug() << obj2;
QJsonObject obj3;
obj3.insert("name", "jerry");
obj3.insert("age", 24);
QJsonObject addr3;
addr3.insert("city", "foshan");
addr3.insert("province", "guangdong");
obj3.insert("addr", addr3);
qDebug() << obj3;
QJsonArray array;
array.push_back(obj1);
array.push_back(obj2);
array.push_back(obj3);
qDebug() << array;
return a.exec();
}在此,我們只是簡單的構(gòu)建了三個人物的QJsonObject對象,然后將它們放入一個QJsonArray中。輸入結(jié)果如下:

QJsonDocument
QJsonDocument類提供了讀寫JSON文檔的方法。QJsonDocument類包裝了一個完整的JSON 文檔,我們可以以utf-8編碼的文本格式和Qt自己的二進制格式來操作該文檔。一個JSON文檔可以使用QJsonDocument::fromJson()函數(shù)轉(zhuǎn)換json文本字符串來得到。而toJson()可以將其轉(zhuǎn)換成文本。這個解析器是非??焖俸透咝У?,Qt也是使用它來將JSON對象轉(zhuǎn)換成其二進制表示的。解析得到的文檔可以使用isNull()來判斷是否有效。還可以使用isArray()和isObject()函數(shù)來判斷該文檔所包含的是否是數(shù)據(jù)或json對象。如果是,可以使用array()或object()函數(shù)還獲得其中的對象或數(shù)組。
其構(gòu)造函數(shù)如下:
QJsonDocument() QJsonDocument(const QJsonObject &object) QJsonDocument(const QJsonArray &array) QJsonDocument(const QJsonDocument &other)
除了構(gòu)造函數(shù)外,該類還提供了兩個轉(zhuǎn)換函數(shù),可以將json文檔序列化為二進制對象,然后我們就可以將該對象存儲到文件中,或發(fā)送到網(wǎng)絡(luò)上。
QByteArray toBinaryData() const QByteArray toJson(JsonFormat format = Indented) const
下面,我們就使用該類將我們上面生成的json數(shù)組寫入到文件中:
代碼如下:
#include <QCoreApplication>
#include <QDebug>
#include <QJsonObject>
#include <QJsonArray>
#include <QFile>
#include <QJsonDocument>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QJsonObject obj1;
obj1.insert("name", "lily");
obj1.insert("age", 23);
QJsonObject addr1;
addr1.insert("city", "guangzhou");
addr1.insert("province", "guangdong");
obj1.insert("addr", addr1);
qDebug() << obj1;
QJsonObject obj2;
obj2.insert("name", "tom");
obj2.insert("age", 24);
QJsonObject addr2;
addr2.insert("city", "shenzhen");
addr2.insert("province", "guangdong");
obj2.insert("addr", addr2);
qDebug() << obj2;
QJsonObject obj3;
obj3.insert("name", "jerry");
obj3.insert("age", 24);
QJsonObject addr3;
addr3.insert("city", "foshan");
addr3.insert("province", "guangdong");
obj3.insert("addr", addr3);
qDebug() << obj3;
QJsonArray array;
array.push_back(obj1);
array.push_back(obj2);
array.push_back(obj3);
qDebug() << array;
QJsonDocument jsonDoc(array);
QByteArray ba = jsonDoc.toJson();
QFile file("result.json");
if(!file.open(QIODevice::WriteOnly))
{
qDebug() << "write json file failed";
return 0;
}
file.write(ba);
file.close();
return a.exec();
}我們先使用QJsonArray構(gòu)建出一個QJsonDocument對象,然后調(diào)用其toJson()方法,將該json文檔轉(zhuǎn)換成一個字節(jié)數(shù)組。注意,toJson()函數(shù)會接受一個格式化參數(shù):
QByteArray QJsonDocument::toJson(JsonFormat format = Indented) const
其中,format主要有兩種格式,一種是人們可讀的格式,一種是緊湊的格式。分別描述如下表:
| Constant | Value | Description |
| QJsonDocument::Indented | 0 | 定義人們可讀的輸出格式,如下: { "Array":[ true, 999, "string" ], "key": "value", "null": null } |
| QJsonDocument::Compact | 1 | 定義一個緊湊的輸出格式,如下: {"Array": [true, 999, "string"], "key": "value", "null":null} |
toJson()函數(shù)默認使用Indented,一縮進的形式生成人們可讀的json文件。
運行該程序后,在編譯目錄查看生成的json文件。結(jié)果如下:

當然,除了將json對象寫入到文件中,QJsonDocument還提供了幾個靜態(tài)函數(shù),將從文件中讀取出的原始數(shù)據(jù)或json字符串轉(zhuǎn)換成一個QJsonDocument對象。函數(shù)聲明信息如下:
QJsonDocument fromBinaryData(const QByteArray &data, DataValidation validation = Validate) QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR) QJsonDocument fromRawData(const char *data, int size, DataValidation validation = Validate) QJsonDocument fromVariant(const QVariant &variant)
下面,我們就使用這些函數(shù),將我們寫入到文件中的json對象再讀出來,并生成一個QJsonDocument對象。
代碼如下:
#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QJsonDocument>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QFile file("result.json");
if(!file.open(QIODevice::ReadOnly))
{
qDebug() << "read json file failed";
return 0;
}
QByteArray ba = file.readAll();
qDebug() << "讀出的數(shù)據(jù)如下:";
qDebug() << ba;
QJsonParseError e;
QJsonDocument jsonDoc = QJsonDocument::fromJson(ba, &e);
if(e.error == QJsonParseError::NoError && !jsonDoc.isNull())
{
qDebug() << jsonDoc;
}
return a.exec();
}在此,因為我們從文件中讀出的是一個json形式的字符串,所以可以使用fromJson()函數(shù),將其轉(zhuǎn)換成一個QJsonDocument對象。同時,在調(diào)用fromJson()函數(shù)時,我們還為它傳入了一個QJsonParseError對象,用來接收解析json字符串的過程中,有可能發(fā)生的錯誤信息。
代碼運行如下:

到此這篇關(guān)于Qt中JSON操作的具體使用的文章就介紹到這了,更多相關(guān)Qt JSON操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言詳細分析貪心策略中最小生成樹的Prime算法設(shè)計與實現(xiàn)
最小生成樹的問題還是比較熱門的,最經(jīng)典的莫過于Prime算法和Kruskal算法了,這篇博文我會詳細講解Prime算法的設(shè)計思想與具體代碼的實現(xiàn),不要求數(shù)據(jù)結(jié)構(gòu)學的有多好,只要跟著我的思路來,一步一步的分析,調(diào)試,終能成就自己,那就讓我們開始吧2022-05-05
C語言詳細分析結(jié)構(gòu)體的內(nèi)存對齊規(guī)則
C 數(shù)組允許定義可存儲相同類型數(shù)據(jù)項的變量,結(jié)構(gòu)是 C 編程中另一種用戶自定義的可用的數(shù)據(jù)類型,它允許你存儲不同類型的數(shù)據(jù)項,本篇讓我們來了解C 的結(jié)構(gòu)體內(nèi)存對齊2022-07-07
C++ 中malloc()和free()函數(shù)的理解
這篇文章主要介紹了C++ 中malloc()和free()函數(shù)的理解的相關(guān)資料,這里提供用法示例幫助大家理解這部分知識,需要的朋友可以參考下2017-08-08
C語言庫函數(shù)strcpy的使用及模擬實現(xiàn)
本文主要介紹了C語言庫函數(shù)strcpy的使用及模擬實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-04-04

