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

QJsonArray
顧名思義,QJsonArray封裝了一個(gè)JSON數(shù)組。一個(gè)JSON數(shù)組是一個(gè)值的列表。我們可以向這個(gè)列表中插入或刪除QJsonValue。
同時(shí),我們可以把一個(gè)QVariantList轉(zhuǎn)換成一個(gè)QJsonArray。也可以使用標(biāo)準(zhǔn)C++迭代器對(duì)它進(jìn)行遍歷。 其構(gòu)造函數(shù)如下:
QJsonArray() QJsonArray(std::initializer_list<QJsonValue> args) QJsonArray(const QJsonArray &other)
我們也可以像上面那樣,使用一個(gè)初始化列表來構(gòu)建一個(gè)QJsonArray對(duì)象:
QJsonArray array = { 1, 2.2, QString() };在此我們只使用了單個(gè)的值,沒有使用鍵值對(duì)。其實(shí),這樣的json對(duì)象,一般我們就稱為數(shù)組。
和QJsonObject一樣,我們一般也是通過它的insert()函數(shù)來生成我們需要的json數(shù)組:
void insert(int i, const QJsonValue &value) iterator insert(iterator before, const QJsonValue &value)
下面,我們繼續(xù)上面的例子,來生成一個(gè)表示人物信息的列表。代碼如下:
#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)建了三個(gè)人物的QJsonObject對(duì)象,然后將它們放入一個(gè)QJsonArray中。輸入結(jié)果如下:

QJsonDocument
QJsonDocument類提供了讀寫JSON文檔的方法。QJsonDocument類包裝了一個(gè)完整的JSON 文檔,我們可以以u(píng)tf-8編碼的文本格式和Qt自己的二進(jìn)制格式來操作該文檔。一個(gè)JSON文檔可以使用QJsonDocument::fromJson()函數(shù)轉(zhuǎn)換json文本字符串來得到。而toJson()可以將其轉(zhuǎn)換成文本。這個(gè)解析器是非常快速和高效的,Qt也是使用它來將JSON對(duì)象轉(zhuǎn)換成其二進(jìn)制表示的。解析得到的文檔可以使用isNull()來判斷是否有效。還可以使用isArray()和isObject()函數(shù)來判斷該文檔所包含的是否是數(shù)據(jù)或json對(duì)象。如果是,可以使用array()或object()函數(shù)還獲得其中的對(duì)象或數(shù)組。
其構(gòu)造函數(shù)如下:
QJsonDocument() QJsonDocument(const QJsonObject &object) QJsonDocument(const QJsonArray &array) QJsonDocument(const QJsonDocument &other)
除了構(gòu)造函數(shù)外,該類還提供了兩個(gè)轉(zhuǎn)換函數(shù),可以將json文檔序列化為二進(jìn)制對(duì)象,然后我們就可以將該對(duì)象存儲(chǔ)到文件中,或發(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)建出一個(gè)QJsonDocument對(duì)象,然后調(diào)用其toJson()方法,將該json文檔轉(zhuǎn)換成一個(gè)字節(jié)數(shù)組。注意,toJson()函數(shù)會(huì)接受一個(gè)格式化參數(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 | 定義一個(gè)緊湊的輸出格式,如下: {"Array": [true, 999, "string"], "key": "value", "null":null} |
toJson()函數(shù)默認(rèn)使用Indented,一縮進(jìn)的形式生成人們可讀的json文件。
運(yùn)行該程序后,在編譯目錄查看生成的json文件。結(jié)果如下:

當(dāng)然,除了將json對(duì)象寫入到文件中,QJsonDocument還提供了幾個(gè)靜態(tài)函數(shù),將從文件中讀取出的原始數(shù)據(jù)或json字符串轉(zhuǎn)換成一個(gè)QJsonDocument對(duì)象。函數(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對(duì)象再讀出來,并生成一個(gè)QJsonDocument對(duì)象。
代碼如下:
#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();
}在此,因?yàn)槲覀儚奈募凶x出的是一個(gè)json形式的字符串,所以可以使用fromJson()函數(shù),將其轉(zhuǎn)換成一個(gè)QJsonDocument對(duì)象。同時(shí),在調(diào)用fromJson()函數(shù)時(shí),我們還為它傳入了一個(gè)QJsonParseError對(duì)象,用來接收解析json字符串的過程中,有可能發(fā)生的錯(cuò)誤信息。
代碼運(yùn)行如下:

到此這篇關(guān)于Qt中JSON操作的具體使用的文章就介紹到這了,更多相關(guān)Qt JSON操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言代碼實(shí)現(xiàn)學(xué)生成績管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言代碼實(shí)現(xiàn)學(xué)生成績管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
C語言詳細(xì)分析貪心策略中最小生成樹的Prime算法設(shè)計(jì)與實(shí)現(xiàn)
最小生成樹的問題還是比較熱門的,最經(jīng)典的莫過于Prime算法和Kruskal算法了,這篇博文我會(huì)詳細(xì)講解Prime算法的設(shè)計(jì)思想與具體代碼的實(shí)現(xiàn),不要求數(shù)據(jù)結(jié)構(gòu)學(xué)的有多好,只要跟著我的思路來,一步一步的分析,調(diào)試,終能成就自己,那就讓我們開始吧2022-05-05
C語言將24小時(shí)制轉(zhuǎn)換為12小時(shí)制的方法
這篇文章主要介紹了C語言將24小時(shí)制轉(zhuǎn)換為12小時(shí)制的方法,涉及C語言針對(duì)時(shí)間的相關(guān)操作技巧,非常簡單實(shí)用,需要的朋友可以參考下2015-07-07
C語言詳細(xì)分析結(jié)構(gòu)體的內(nèi)存對(duì)齊規(guī)則
C 數(shù)組允許定義可存儲(chǔ)相同類型數(shù)據(jù)項(xiàng)的變量,結(jié)構(gòu)是 C 編程中另一種用戶自定義的可用的數(shù)據(jù)類型,它允許你存儲(chǔ)不同類型的數(shù)據(jù)項(xiàng),本篇讓我們來了解C 的結(jié)構(gòu)體內(nèi)存對(duì)齊2022-07-07
C++ 中malloc()和free()函數(shù)的理解
這篇文章主要介紹了C++ 中malloc()和free()函數(shù)的理解的相關(guān)資料,這里提供用法示例幫助大家理解這部分知識(shí),需要的朋友可以參考下2017-08-08
C語言庫函數(shù)strcpy的使用及模擬實(shí)現(xiàn)
本文主要介紹了C語言庫函數(shù)strcpy的使用及模擬實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-04-04
詳解c/c++賦值函數(shù)(重載=號(hào)運(yùn)算符)
大家都知道c++里的各種運(yùn)算符都是用函數(shù)實(shí)現(xiàn)的,比如=就等號(hào)函數(shù),所以當(dāng)用=給一個(gè)對(duì)象賦值的時(shí)候,實(shí)際調(diào)用的是=號(hào)所對(duì)應(yīng)的=號(hào)函數(shù)。下面通過本文給大家介紹c/c++賦值函數(shù)(重載=號(hào)運(yùn)算符),感興趣的朋友一起看看吧2018-08-08

