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

QJsonDocument
QJsonDocument類(lèi)提供了讀寫(xiě)JSON文檔的方法。QJsonDocument類(lèi)包裝了一個(gè)完整的JSON 文檔,我們可以以u(píng)tf-8編碼的文本格式和Qt自己的二進(jìn)制格式來(lái)操作該文檔。一個(gè)JSON文檔可以使用QJsonDocument::fromJson()函數(shù)轉(zhuǎn)換json文本字符串來(lái)得到。而toJson()可以將其轉(zhuǎn)換成文本。這個(gè)解析器是非??焖俸透咝У?,Qt也是使用它來(lái)將JSON對(duì)象轉(zhuǎn)換成其二進(jìn)制表示的。解析得到的文檔可以使用isNull()來(lái)判斷是否有效。還可以使用isArray()和isObject()函數(shù)來(lái)判斷該文檔所包含的是否是數(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ù)外,該類(lèi)還提供了兩個(gè)轉(zhuǎn)換函數(shù),可以將json文檔序列化為二進(jìn)制對(duì)象,然后我們就可以將該對(duì)象存儲(chǔ)到文件中,或發(fā)送到網(wǎng)絡(luò)上。
QByteArray toBinaryData() const QByteArray toJson(JsonFormat format = Indented) const
下面,我們就使用該類(lèi)將我們上面生成的json數(shù)組寫(xiě)入到文件中:
代碼如下:
#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ì)象寫(xiě)入到文件中,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ù),將我們寫(xiě)入到文件中的json對(duì)象再讀出來(lái),并生成一個(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ì)象,用來(lái)接收解析json字符串的過(guò)程中,有可能發(fā)生的錯(cuò)誤信息。
代碼運(yùn)行如下:

到此這篇關(guān)于Qt中JSON操作的具體使用的文章就介紹到這了,更多相關(guān)Qt JSON操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
深度解析三個(gè)常見(jiàn)的C語(yǔ)言?xún)?nèi)存函數(shù)
這篇文章主要深度解析了三個(gè)常見(jiàn)的C語(yǔ)言?xún)?nèi)存函數(shù)memcpy,memmove,memcmp,所以本文將對(duì)memcpy,memmove,memcmp 三個(gè)函數(shù)進(jìn)行詳解和模擬實(shí)現(xiàn),需要的朋友可以參考下2023-07-07
c語(yǔ)言實(shí)現(xiàn)從源文件從文本到可執(zhí)行文件經(jīng)歷的過(guò)程
這篇文章主要介紹了c語(yǔ)言實(shí)現(xiàn)從源文件從文本到可執(zhí)行文件經(jīng)歷的過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
C/C++ 實(shí)現(xiàn)遞歸和棧逆序字符串的實(shí)例
這篇文章主要介紹了C/C++ 實(shí)現(xiàn)遞歸和棧逆序字符串的實(shí)例的相關(guān)資料,這里提供實(shí)例代碼幫助大家學(xué)習(xí)掌握,需要的朋友可以參考下2017-08-08
大家注意vector, list, set, map成員函數(shù)erase
set和map是由紅黑樹(shù)來(lái)實(shí)現(xiàn)的,當(dāng)erase的時(shí)候迭代器就失效了,也就是說(shuō)我們要在迭代器失效之前保留一個(gè)副本,根據(jù)這個(gè)副本我們才能繼續(xù)遍歷下一個(gè)元素2013-09-09

