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

Qt使用Json的項目實踐

 更新時間:2023年09月03日 10:04:46   作者:小瑞的學(xué)習(xí)筆記  
JSON是一種對源自Javascript的對象數(shù)據(jù)進行編碼的格式,但現(xiàn)在被廣泛用作互聯(lián)網(wǎng)上的數(shù)據(jù)交換格式,本文主要介紹了Qt使用Json的項目實踐,詳細(xì)的介紹了主要使用的類以及Json實戰(zhàn),感興趣的可以了解一下

JSON介紹

Qt支持處理JSON數(shù)據(jù)。JSON是一種對源自Javascript的對象數(shù)據(jù)進行編碼的格式,但現(xiàn)在被廣泛用作互聯(lián)網(wǎng)上的數(shù)據(jù)交換格式。

Qt中的JSON支持提供了一個易于使用的C++API來解析、修改和保存JSON數(shù)據(jù)。它還支持以二進制格式保存數(shù)據(jù),這種格式可以直接“mmap”,并且訪問速度非???。

主要使用的類

Json 類介紹
QJsonDocument它封裝了一個完整的 JSON 文檔,并且可以從 UTF-8 編碼的基于文本的表示以及 Qt 自己的二進制格式讀取和寫入該文檔。
QJsonArrayJSON 數(shù)組是一個值列表??梢酝ㄟ^從數(shù)組中插入和刪除 QJsonValue 來操作該列表。
QJsonObjectJSON 對象是鍵值對的列表,其中鍵是唯一的字符串,值由 QJsonValue 表示。
QJsonValue該類封裝了 JSON 支持的數(shù)據(jù)類型。

QJsonValue

在 Qt 中 QJsonValue 可以封裝的基礎(chǔ)數(shù)據(jù)類型有六種(和 Json 支持的類型一致),分別為:

  • 布爾類型:QJsonValue::Bool
  • 浮點類型(包括整形): QJsonValue::Double
  • 字符串類型: QJsonValue::String
  • Json 數(shù)組類型: QJsonValue::Array
  • Json 對象類型:QJsonValue::Object
  • 空值類型: QJsonValue::Null

這些類型可以通過 QJsonValue 的構(gòu)造函數(shù)被封裝為一個類對象:

// Json對象
QJsonValue(const QJsonObject &o);
// Json數(shù)組
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 對象,如何判斷內(nèi)部封裝的到底是什么類型的數(shù)據(jù)呢?這時候就需要調(diào)用相關(guān)的判斷函數(shù)了,具體如下:

// 是否是Json數(shù)組
bool isArray() const;
// 是否是Json對象
bool isObject() const;
// 是否是布爾類型
bool isBool() const;
// 是否是浮點類型(整形也是通過該函數(shù)判斷)
bool isDouble() const;
// 是否是空值類型
bool isNull() const;
// 是否是字符串類型
bool isString() const;
// 是否是未定義類型(無法識別的類型)
bool isUndefined() const;

通過判斷函數(shù)得到對象內(nèi)部數(shù)據(jù)的實際類型之后,如果有需求就可以再次將其轉(zhuǎn)換為對應(yīng)的基礎(chǔ)數(shù)據(jù)類型,對應(yīng)的 API 函數(shù)如下:

// 轉(zhuǎn)換為Json數(shù)組
QJsonArray toArray(const QJsonArray &defaultValue) const;
QJsonArray toArray() const;
// 轉(zhuǎn)換為布爾類型
bool toBool(bool defaultValue = false) const;
// 轉(zhuǎn)換為浮點類型
double toDouble(double defaultValue = 0) const;
// 轉(zhuǎn)換為整形
int toInt(int defaultValue = 0) const;
// 轉(zhuǎn)換為Json對象
QJsonObject toObject(const QJsonObject &defaultValue) const;
QJsonObject toObject() const;
// 轉(zhuǎn)換為字符串類型
QString toString() const;
QString toString(const QString &defaultValue) const;

QJsonObject

QJsonObject 封裝了 Json 中的對象,在里邊可以存儲多個鍵值對,為了方便操作,鍵值為字符串類型,值為 QJsonValue 類型。

  • 如何創(chuàng)建空的 Json 對象
QJsonObject::QJsonObject();	// 構(gòu)造空對象
  • 將鍵值對添加到空對象中
iterator QJsonObject::insert(const QString &key, const QJsonValue &value);
  • 獲取對象中鍵值對個數(shù)
int QJsonObject::count() const;
int QJsonObject::size() const;
int QJsonObject::length() const;
  • 通過 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對應(yīng)的value值
  • 通過 key 進行查找
iterator QJsonObject::find(const QString &key);
bool QJsonObject::contains(const QString &key) const;

遍歷,方式有三種:

  • 使用相關(guān)的迭代器函數(shù)
  • 使用 [] 的方式遍歷,類似于遍歷數(shù)組,[] 中是鍵值
  • 先得到對象中所有的鍵值,在遍歷鍵值列表,通過 key 得到 value 值
QStringList QJsonObject::keys() const;

QJsonDocument

  • 它封裝了一個完整的 JSON 文檔,并且可以從 UTF-8 編碼的基于文本的表示以及 Qt 自己的二進制格式讀取和寫入該文檔。
  • QJsonObject 和 QJsonArray 這兩個對象中的數(shù)據(jù)是不能直接轉(zhuǎn)換為字符串類型的,如果要進行數(shù)據(jù)傳輸或者數(shù)據(jù)的持久化,操作的都是字符串類型而不是 QJsonObject 或者 QJsonArray 類型,我們需要通過一個 Json 文檔類進行二者之間的轉(zhuǎn)換。

下面依次介紹一下這兩個轉(zhuǎn)換流程應(yīng)該如何操作:

1. QJsonObject 或者 QJsonArray ===> 字符串

  • 創(chuàng)建 QJsonDocument 對象
QJsonDocument::QJsonDocument(const QJsonObject &object);
QJsonDocument::QJsonDocument(const QJsonArray &array);

可以看出,通過構(gòu)造函數(shù)就可以將實例化之后的 QJsonObject 或者 QJsonArray 轉(zhuǎn)換為 QJsonDocument 對象了。

  • 將文件對象中的數(shù)據(jù)進行序列化
// 二進制格式的json字符串
QByteArray QJsonDocument::toBinaryData() const;	 
// 文本格式
QByteArray QJsonDocument::toJson(JsonFormat format = Indented) const;

通過調(diào)用 toxxx() 方法就可以得到文本格式或者二進制格式的 Json 字符串了。

  • 使用得到的字符串進行數(shù)據(jù)傳輸,或者磁盤文件持久化

2. 字符串 ===> QJsonObject 或者 QJsonArray

一般情況下,通過網(wǎng)絡(luò)通信或者讀磁盤文件就會得到一個 Json 格式的字符串,如果想要得到相關(guān)的原始數(shù)據(jù)就需要對字符串中的數(shù)據(jù)進行解析,具體解析流程如下:

  • 將得到的 Json 格式字符串通過 QJsonDocument 類的靜態(tài)函數(shù)轉(zhuǎn)換為 QJsonDocument 類對象
[static] QJsonDocument QJsonDocument::fromBinaryData(const QByteArray &data, DataValidation validation = Validate);
// 參數(shù)文件格式的json字符串
[static] QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR);
  • 將文檔對象轉(zhuǎn)換為 json 數(shù)組 / 對象
// 判斷文檔對象中存儲的數(shù)據(jù)是不是數(shù)組
bool QJsonDocument::isArray() const;
// 判斷文檔對象中存儲的數(shù)據(jù)是不是json對象
bool QJsonDocument::isObject() const
// 文檔對象中的數(shù)據(jù)轉(zhuǎn)換為json對象
QJsonObject QJsonDocument::object() const;
// 文檔對象中的數(shù)據(jù)轉(zhuǎn)換為json數(shù)組
QJsonArray QJsonDocument::array() const;
  • 通過調(diào)用 QJsonArray , QJsonObject 類提供的 API 讀出存儲在對象中的數(shù)據(jù)。

關(guān)于 Qt 中 Json 數(shù)據(jù)對象以及字符串之間的轉(zhuǎn)換的操作流程是固定的,我們在編碼過程中只需要按照上述模板處理即可,相關(guān)的操作是沒有太多的技術(shù)含量可言的。

實戰(zhàn)

1. 手動寫Json文件

注意:[…] 中是數(shù)組元素,{…}中是Json對象

在這里插入圖片描述

2. 實現(xiàn)程序(從Json文件中讀取數(shù)據(jù),更改Json文件中的數(shù)據(jù))

mainwindow.h

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    QVector<struct Animal> readJson();// 讀取Json文件
    bool changeDate();// 改變Json文件中的數(shù)據(jù)
private:
    Ui::MainWindow *ui;
};
struct Food{
    QString stapleFood;
    QString meat;
};
struct Animal{
    QString name;
    int age;
    QVector<QString> eatTimeArr;
    struct Food food;
};

mainwindow.cpp

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    changeDate();
    readJson();
}
MainWindow::~MainWindow()
{
    delete ui;
}
// 增加數(shù)據(jù)直接在手動修改Json文件
// 查數(shù)據(jù)(已知Json數(shù)據(jù)格式的情況下):將Json中所有animal類保存到vector中全部返回
QVector<struct Animal> MainWindow::readJson()
{
    QFile file("D:\\Qt\\homework\\text01\\studyJson.json");
    bool ret = file.open(QFile::ReadOnly);
    QByteArray bytes = file.readAll();// 把文件中所有數(shù)據(jù)讀取出來
    QJsonDocument doc = QJsonDocument::fromJson(bytes);// 將讀出的數(shù)據(jù)保存為Json文檔
    QJsonArray groupArr = doc.array();// 獲取數(shù)組
    QVector<struct Animal> ans;// 用于保存獲取到的數(shù)據(jù)
   for(int i = 0; i < groupArr.size(); i++)
   {
       QJsonObject obj = groupArr.at(i).toObject();// 把數(shù)組中每一個數(shù)據(jù)都轉(zhuǎn)化為 QJsonObject
       struct Animal animal;
       animal.name = obj.value("name").toString();
       animal.age = obj.value("age").toInt();
       // eatTime 對應(yīng)的值為一個數(shù)組
       QJsonArray foodArr = obj.value("eatTime").toArray();
       for(int i = 0; i < foodArr.size(); i++)
       {
           animal.eatTimeArr.push_back(foodArr.at(i).toString());
       }
       // food 對應(yīng)的值為一個 QJsonObject 類型
       QJsonObject subObj = obj.value("food").toObject();
       animal.food.stapleFood = subObj.value("stapleFood").toString();
       animal.food.meat = subObj.value("meat").toString();
       ans.push_back(animal);// 將獲取到的數(shù)據(jù)加入容器中
       qDebug() << "name =" << animal.name
                << "age =" << animal.age
                << "eatTime =" << animal.eatTimeArr[0] << animal.eatTimeArr[1] << animal.eatTimeArr[2]
                << "food.stapleFood =" << animal.food.stapleFood
                << "food.meat =" << animal.food.meat;
   }
   return ans;
}
// 改數(shù)據(jù):從studyJson.json讀取數(shù)據(jù)并且富貴的年齡改為10歲
bool MainWindow::changeDate()
{
    // 打開文件
    QFile file("D:\\Qt\\homework\\text01\\studyJson.json");
    file.open(QIODevice::ReadWrite);
    QByteArray bytes = file.readAll();// 讀取文件所有內(nèi)容
    file.close();
    QJsonDocument doc = QJsonDocument::fromJson(bytes);// 將讀出的數(shù)據(jù)保存為Json文檔
    QJsonArray groupArr = doc.array();// 獲取數(shù)組
    QJsonObject obj = groupArr.at(0).toObject();// 獲取數(shù)組中第一個元素
    // 判斷 "age"節(jié)點是否存在
    if(obj.contains("age")){
        obj["age"] = 10;// 將數(shù)組第一個元素中的年齡改變
        // 此時我們新建一個數(shù)組,把更新好的元素加入數(shù)組,并且把之前數(shù)組中沒有改變的元素加入
        QJsonArray arr;
        arr.append(obj);
        arr.append(groupArr.at(1).toObject());
        // 保存至Json文檔  注意:調(diào)用setArray后,先會把之前保存所有的數(shù)據(jù)清除,然后再保存新的數(shù)據(jù)
        doc.setArray(arr);
    }
    // 把最新數(shù)據(jù)寫入QIODevice::Truncate
    file.open(QFile::WriteOnly|QFile::Truncate);
    file.seek(0);// 使寫入位置為起始位置
    file.write(doc.toJson());
}

打印調(diào)試信息

在這里插入圖片描述

執(zhí)行changeDate()后,Json文件改變

這里需要注意:如果用Json自己寫入文件,他所有數(shù)據(jù)會根據(jù)key的字典序排列

在這里插入圖片描述

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

相關(guān)文章

  • C語言遞歸操作用法總結(jié)

    C語言遞歸操作用法總結(jié)

    這篇文章主要介紹了C語言遞歸操作用法,結(jié)合實例形式總結(jié)分析了C語言遞歸操作的原理、實現(xiàn)技巧與相關(guān)應(yīng)用,需要的朋友可以參考下
    2016-02-02
  • 老生常談C++ explicit關(guān)鍵字

    老生常談C++ explicit關(guān)鍵字

    這篇文章主要介紹了C++ explicit關(guān)鍵字,explicit關(guān)鍵字只需用于類內(nèi)的單參數(shù)構(gòu)造函數(shù)前面,由于無參數(shù)的構(gòu)造函數(shù)和多參數(shù)的構(gòu)造函數(shù)總是顯式調(diào)用,這種情況在構(gòu)造函數(shù)前加explicit無意義,需要的朋友可以參考下
    2023-03-03
  • c語言使用fdk_aac實現(xiàn)aac音頻解碼為pcm

    c語言使用fdk_aac實現(xiàn)aac音頻解碼為pcm

    這篇文章主要為大家詳細(xì)介紹了c語言如何使用fdk_aac庫實現(xiàn)aac音頻解碼為pcm的功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-11-11
  • C++11?constexpr使用詳解

    C++11?constexpr使用詳解

    constexpr是一種比const?更嚴(yán)格的束縛,?它修飾的表達(dá)式本身在編譯期間可知,?并且編譯器會盡可能的?evaluate?at?compile?time,本文重點給大家介紹C++11?constexpr使用,需要的朋友可以參考下
    2021-12-12
  • C語言return知識點總結(jié)

    C語言return知識點總結(jié)

    在本篇文章里小編給大家整理的是關(guān)于C語言return知識點總結(jié)內(nèi)容,需要的朋友們可以學(xué)習(xí)參考下。
    2020-02-02
  • C++音樂播放按鈕的封裝過程詳解

    C++音樂播放按鈕的封裝過程詳解

    此篇文章用于記錄學(xué)習(xí)C++封裝音樂播放按鈕,封裝將對象的屬性和行為作為一個整體,表現(xiàn)生活中的事物、將屬性和行為加以權(quán)限控制,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • C語言中的socket編程實例代碼

    C語言中的socket編程實例代碼

    這篇文章主要介紹了如何用C語言實現(xiàn)socket編程,文中代碼非常詳細(xì),供大家學(xué)習(xí)參考,感興趣的朋友可以了解下
    2020-06-06
  • ipv6實現(xiàn)tcp編程示例

    ipv6實現(xiàn)tcp編程示例

    這篇文章主要介紹了ipv6實現(xiàn)tcp編程示例,需要的朋友可以參考下
    2014-03-03
  • C/C++實現(xiàn)線性順序表的示例代碼

    C/C++實現(xiàn)線性順序表的示例代碼

    使用順序存儲結(jié)構(gòu)的線性存儲結(jié)構(gòu)的表為線性順序表。本文將分別利用C語言和C++實現(xiàn)線性順序表,文中示例代碼講解詳細(xì),需要的可以參考一下
    2022-05-05
  • C語言實現(xiàn)窗口抖動

    C語言實現(xiàn)窗口抖動

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)窗口抖動,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11

最新評論

靖江市| 昆山市| 广水市| 噶尔县| 色达县| 四川省| 云浮市| 南雄市| 长宁区| 大余县| 九龙县| 华坪县| 梧州市| 眉山市| 习水县| 英德市| 沾化县| 北辰区| 榆林市| 神池县| 青川县| 句容市| 区。| 邯郸县| 遵义市| 商城县| 新野县| 财经| 仪陇县| 武义县| 剑川县| 滕州市| 恭城| 正阳县| 治多县| 乌鲁木齐县| 陕西省| 舒城县| 炉霍县| 手游| 聂荣县|