QJson基础
轉載自?愛編程的大丙
從 Qt 5.0 開始提供了對 Json 的支持,我們可以直接使用 Qt 提供的 Json 類進行數據的組織和解析。相關的類常用的主要有四個,具體如下:
| Json 類? ? | 介紹 |
| QJsonDocument | 它封裝了一個完整的 JSON 文檔,并且可以從 UTF-8 編碼的基于文本的表示以及 Qt 自己的二進制格式讀取和寫入該文檔。 |
| QJsonArray? | ?JSON 數組是一個值列表。可以通過從數組中插入和刪除 QJsonValue 來操作該列表。 |
| QJsonObject? | ?JSON 對象是鍵值對的列表,其中鍵是唯一的字符串,值由 QJsonValue 表示。 |
| QJsonValue | 該類封裝了 JSON 支持的數據類型。 |
1. QJsonValue
在 Qt 中 QJsonValue 可以封裝的基礎數據類型有六種(和 Json 支持的類型一致),分別為:
- 布爾類型:????????????????????????QJsonValue::Bool
- 浮點類型(包括整形):? QJsonValue::Double
- 字符串類型:? ? ? ? ? ? ? ? ? ? QJsonValue::String
- Json 數組類型:? ? ? ? ? ? ? ?QJsonValue::Array
- Json 對象類型:? ? ? ? ? ? ? ?QJsonValue::Object
- 空值類型:? ? ? ? ? ? ? ? ? ? ? ? QJsonValue::Null
這個類型可以通過 QJsonValue 的構造函數被封裝為一個類對象:
// Json對象 QJsonValue(const QJsonObject &o); // Json數組 QJsonValue(const QJsonArray &a); // 字符串 QJsonValue(const char *s); QJsonValue(QLatin1String s); QJsonValue(const QString &s); // 整形 and 浮點型 QJsonValue(qint64 v); QJsonValue(int v); QJsonValue(double v); // 布爾類型 QJsonValue(bool b); // 空值類型 QJsonValue(QJsonValue::Type type = Null);如果我們得到一個 QJsonValue 對象,如何判斷內部封裝的到底是什么類型的數據呢?這時候就需要調用相關的判斷函數了,具體如下:
// 是否是Json數組 bool isArray() const; // 是否是Json對象 bool isObject() const; // 是否是布爾類型 bool isBool() const; // 是否是浮點類型(整形也是通過該函數判斷) bool isDouble() const; // 是否是空值類型 bool isNull() const; // 是否是字符串類型 bool isString() const; // 是否是未定義類型(無法識別的類型) bool isUndefined() const;通過判斷函數得到對象內部數據的實際類型之后,如果有需求就可以再次將其轉換為對應的基礎數據類型,對應的 API 函數如下:
// 轉換為Json數組 QJsonArray toArray(const QJsonArray &defaultValue) const; QJsonArray toArray() const; // 轉換為布爾類型 bool toBool(bool defaultValue = false) const; // 轉換為浮點類型 double toDouble(double defaultValue = 0) const; // 轉換為整形 int toInt(int defaultValue = 0) const; // 轉換為Json對象 QJsonObject toObject(const QJsonObject &defaultValue) const; QJsonObject toObject() const; // 轉換為字符串類型 QString toString() const; QString toString(const QString &defaultValue) const;?
2. QJsonObject
QJsonObject 封裝了 Json 中的對象,在里邊可以存儲多個鍵值對,為了方便操作,鍵值為字符串類型,值為 QJsonValue 類型。關于這個類的使用類似于 C++ 中的 STL 類,仔細閱讀 API 文檔即可熟練上手使用,下面介紹一些常用 API 函數:
如何創建空的 Json 對象
QJsonObject::QJsonObject();?? ?// 構造空對象
將鍵值對添加到空對象中
iterator QJsonObject::insert(const QString &key, const QJsonValue &value);
將鍵值對添加到空對象中
iterator QJsonObject::insert(const QString &key, const QJsonValue &value);
通過 key 得到 value
QJsonValue QJsonObject::value(const QString &key) const; ? ?// utf8
QJsonValue QJsonObject::value(QLatin1String key) const;?? ? ? ?// 字符串不支持中文
QJsonValue QJsonObject::operator[](const QString &key) const;
QJsonValue QJsonObject::operator[](QLatin1String key) const;
刪除鍵值對
void QJsonObject::remove(const QString &key);
QJsonValue QJsonObject::take(const QString &key);?? ?// 返回key對應的value值
通過 key 進行查找
void QJsonObject::remove(const QString &key);
QJsonValue QJsonObject::take(const QString &key);?? ?// 返回key對應的value值
?遍歷,方式有三種:
- 使用相關的迭代器函數
- 使用 [] 的方式遍歷,類似于遍歷數組,[] 中是鍵值
- 先得到對象中所有的鍵值,在遍歷鍵值列表,通過 key 得到 value 值
QStringList QJsonObject::keys() const;
3. QJsonArray
QJsonArray 封裝了 Json 中的數組,在里邊可以存儲多個元素,為了方便操作,所有的元素類統一為 QJsonValue 類型。關于這個類的使用類似于 C++ 中的 STL 類,仔細閱讀 API 文檔即可熟練上手使用,下面介紹一些常用 API 函數:
創建空的 Json 數組
QJsonArray::QJsonArray();
添加數據
void QJsonArray::append(const QJsonValue &value);?? ?// 在尾部追加
void QJsonArray::insert(int i, const QJsonValue &value); // 插入到 i 的位置之前
iterator QJsonArray::insert(iterator before, const QJsonValue &value);
void QJsonArray::prepend(const QJsonValue &value); // 添加到數組頭部
void QJsonArray::push_back(const QJsonValue &value); // 添加到尾部
void QJsonArray::push_front(const QJsonValue &value); // 添加到頭部
計算數組元素的個數
int QJsonArray::count() const;
int QJsonArray::size() const;
從數組中取出某一個元素的值
QJsonValue QJsonArray::at(int i) const;
QJsonValue QJsonArray::first() const; // 頭部元素
QJsonValue QJsonArray::last() const; // 尾部元素
QJsonValueRef QJsonArray::operator[](int i);
刪除數組中的某一個元素
iterator QJsonArray::erase(iterator it); ? ?// 基于迭代器刪除
void QJsonArray::pop_back(); ? ? ? ? ? // 刪除尾部
void QJsonArray::pop_front(); ? ? ? ? ?// 刪除頭部
void QJsonArray::removeAt(int i); ? ? ?// 刪除i位置的元素
void QJsonArray::removeFirst(); ? ? ? ?// 刪除頭部
void QJsonArray::removeLast(); ? ? ? ? // 刪除尾部
QJsonValue QJsonArray::takeAt(int i); ?// 刪除i位置的原始, 并返回刪除的元素的值
Josn 數組的遍歷,常用的方式有兩種:
可以使用迭代器進行遍歷(和使用迭代器遍歷 STL 容器一樣)
可以使用數組的方式遍歷
4. QJsonDocument
它封裝了一個完整的 JSON 文檔,并且可以從 UTF-8 編碼的基于文本的表示以及 Qt 自己的二進制格式讀取和寫入該文檔。QJsonObject 和 QJsonArray 這兩個對象中的數據是不能直接轉換為字符串類型的,如果要進行數據傳輸或者數據的持久化,操作的都是字符串類型而不是 QJsonObject 或者 QJsonArray 類型,我們需要通過一個 Json 文檔類進行二者之間的轉換。
下面依次介紹一下這兩個轉換流程應該如何操作:
QJsonObject 或者 QJsonArray ===> 字符串
1、創建 QJsonDocument 對象
QJsonDocument::QJsonDocument(const QJsonObject &object);
QJsonDocument::QJsonDocument(const QJsonArray &array);
2、將文件對象中的數據進行序列化
// 二進制格式的json字符串
QByteArray QJsonDocument::toBinaryData() const;?? ??
// 文本格式
QByteArray QJsonDocument::toJson(JsonFormat format = Indented) const;?? ?
通過調用 toxxx() 方法就可以得到文本格式或者二進制格式的 Json 字符串了。
3、使用得到的字符串進行數據傳輸,或者磁盤文件持久化
字符串 ===> QJsonObject 或者 QJsonArray
一般情況下,通過網絡通信或者讀磁盤文件就會得到一個 Json 格式的字符串,如果想要得到相關的原始數據就需要對字符串中的數據進行解析,具體解析流程如下:
1、將得到的 Json 格式字符串通過 QJsonDocument 類的靜態函數轉換為 QJsonDocument 類對象
[static] QJsonDocument QJsonDocument::fromBinaryData(const QByteArray &data, DataValidation validation = Validate);
// 參數文件格式的json字符串
[static] QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR);
2、將文檔對象轉換為 json 數組 / 對象;
// 判斷文檔對象中存儲的數據是不是數組
bool QJsonDocument::isArray() const;
// 判斷文檔對象中存儲的數據是不是json對象
bool QJsonDocument::isObject() const
? ??
// 文檔對象中的數據轉換為json對象
QJsonObject QJsonDocument::object() const;
// 文檔對象中的數據轉換為json數組
QJsonArray QJsonDocument::array() const;
3、通過調用 QJsonArray , QJsonObject 類提供的 API 讀出存儲在對象中的數據。
關于 Qt 中 Json 數據對象以及字符串之間的轉換的操作流程是固定的,我們在編碼過程中只需要按照上述模板處理即可,相關的操作是沒有太多的技術含量可言的。
5、舉例
1、寫文件
void writeJson() {QJsonObject obj;obj.insert("Name", "Ace");obj.insert("Sex", "man");obj.insert("Age", 20);QJsonObject subObj;subObj.insert("Father", "Gol·D·Roger");subObj.insert("Mother", "Portgas·D·Rouge");QJsonArray array;array.append("Sabo");array.append("Monkey D. Luffy");subObj.insert("Brother", array);obj.insert("Family", subObj);obj.insert("IsAlive", false);obj.insert("Comment", "yyds");QJsonDocument doc(obj);QByteArray json = doc.toJson();QFile file("d:\\ace.json");file.open(QFile::WriteOnly);file.write(json);file.close(); }5.2讀文件
void MainWindow::readJson() {QFile file("d:\\ace.json");file.open(QFile::ReadOnly);QByteArray json = file.readAll();file.close();QJsonDocument doc = QJsonDocument::fromJson(json);if(doc.isObject()){QJsonObject obj = doc.object();QStringList keys = obj.keys();for(int i=0; i<keys.size(); ++i){QString key = keys.at(i);QJsonValue value = obj.value(key);if(value.isBool()){qDebug() << key << ":" << value.toBool();}if(value.isString()){qDebug() << key << ":" << value.toString();}if(value.isDouble()){qDebug() << key << ":" << value.toInt();}if(value.isObject()){qDebug()<< key << ":";// 直接處理內部鍵值對, 不再進行類型判斷的演示QJsonObject subObj = value.toObject();QStringList ls = subObj.keys();for(int i=0; i<ls.size(); ++i){QJsonValue subVal = subObj.value(ls.at(i));if(subVal.isString()){qDebug() << " " << ls.at(i) << ":" << subVal.toString();}if(subVal.isArray()){QJsonArray array = subVal.toArray();qDebug() << " " << ls.at(i) << ":";for(int j=0; j<array.size(); ++j){// 因為知道數組內部全部為字符串, 不再對元素類型進行判斷qDebug() << " " << array[j].toString();}}}}}} }一般情況下,對于 Json 字符串的解析函數都是有針對性的,因為需求不同設計的 Json 格式就會有所不同,所以不要試圖寫出一個通用的 Json 解析函數,這樣只會使函數變得臃腫而且不易于維護,每個 Json 格式對應一個相應的解析函數即可。
上面的例子中為了給大家演示 Qt 中 Json 類相關 API 函數的使用將解析步驟寫的復雜了,因為在解析的時候我們是知道 Json 對象中的所有 key 值的,可以直接通過 key 值將對應的 value 值取出來,因此上面程序中的一些判斷和循環其實是可以省去的。
總結
- 上一篇: jason概述
- 下一篇: chrome xp 扫描此文件时,防病毒