Qt服務(wù)應(yīng)用操作之JSON文件操作方法
引言
在Qt框架中,JSON(JavaScript Object Notation)是一種輕量級(jí)的數(shù)據(jù)交換格式,易于人閱讀和編寫(xiě),同時(shí)也易于機(jī)器解析和生成。Qt提供了多個(gè)類(lèi)來(lái)支持JSON的解析、生成、修改和序列化,使得在Qt應(yīng)用程序中處理JSON數(shù)據(jù)變得簡(jiǎn)單高效。本文將詳細(xì)介紹如何在Qt中操作JSON文件。
一、JSON基礎(chǔ)知識(shí)
JSON主要有兩種數(shù)據(jù)結(jié)構(gòu):JSON對(duì)象和JSON數(shù)組。
JSON對(duì)象:由鍵值對(duì)組成,每個(gè)鍵(key)是字符串,值(value)可以是字符串、數(shù)字、布爾值、null、JSON數(shù)組或JSON對(duì)象。對(duì)象以花括號(hào)
{}包裹,鍵值對(duì)之間用逗號(hào),分隔,鍵與值之間以冒號(hào):分隔。// 示例一:JSON對(duì)象 { "name": "John Doe", "age": 30, "isEmployed": true }JSON數(shù)組:一系列有序的值的集合,其元素可以是任何JSON類(lèi)型,包括其他數(shù)組或?qū)ο蟆?shù)組以方括號(hào)
[]包裹,元素之間用逗號(hào),分隔。// 示例二:JSON數(shù)組 ["Apple", "Banana", {"id": 1, "color": "Red"}]
二、Qt中處理JSON的關(guān)鍵類(lèi)
Qt中處理JSON數(shù)據(jù)主要涉及以下幾個(gè)類(lèi):
- QJsonDocument:代表整個(gè)JSON文檔,負(fù)責(zé)從/向UTF-8文本或Qt內(nèi)部二進(jìn)制格式進(jìn)行序列化與反序列化。
- QJsonObject:表示JSON對(duì)象,封裝了鍵值對(duì)的管理。
- QJsonArray:表示JSON數(shù)組,實(shí)現(xiàn)了動(dòng)態(tài)大小的值列表。
- QJsonValue:封裝了JSON支持的數(shù)據(jù)類(lèi)型,包括字符串、數(shù)字、布爾值、null、對(duì)象和數(shù)組。
- QJsonParseError:用于報(bào)告JSON解析中的錯(cuò)誤類(lèi)型。
// 相關(guān)頭文件 #include <QFile> // 文件操作 #include <QJsonObject> // JSON對(duì)象 #include <QJsonArray> // JSON數(shù)組 #include <QJsonDocument> // JSON文檔 #include <QJsonParseError> // JSON異常捕捉
三、生成JSON數(shù)據(jù)
在Qt中,可以通過(guò)組合使用上述類(lèi)來(lái)創(chuàng)建復(fù)雜的JSON數(shù)據(jù)結(jié)構(gòu)。以下是一個(gè)示例函數(shù),展示如何創(chuàng)建一個(gè)包含嵌套對(duì)象和數(shù)組的JSON對(duì)象:
// 生成復(fù)雜JSON對(duì)象
QJsonObject createJSONObject() {
QJsonObject personObject; // JSON對(duì)象
// 方式一:insert()方法
personObject.insert("name","John Doe");
personObject.insert("age", 30);
personObject.insert("isEmployed", true);
QJsonObject addressObject;
// 方式二:賦值
addressObject["street"] = "123 Main St.";
addressObject["city"] = "Anytown";
addressObject["country"] = "USA";
personObject["address"] = addressObject; // 嵌套JSON對(duì)象
QJsonArray hobbiesArray; // JSON數(shù)組
hobbiesArray.append("Reading");
hobbiesArray.append("Gaming");
personObject["hobbies"] = hobbiesArray; // 嵌套JSON數(shù)組
return personObject;
}
// 運(yùn)行結(jié)果在文章末尾四、解析JSON數(shù)據(jù)
給定一個(gè)JSON字符串,可以使用Qt的類(lèi)將其解析為相應(yīng)的對(duì)象或數(shù)組結(jié)構(gòu)。以下是一個(gè)解析JSON字符串的示例:
// 解析JSON對(duì)象
QString parseAndPrintJSON(const QString &jsonString) {
QString strtemp; // 解析后的內(nèi)容
QJsonParseError error; // 返回JSON解析錯(cuò)誤的時(shí)候,報(bào)告錯(cuò)誤信息
QJsonDocument document = QJsonDocument::fromJson(jsonString.toUtf8(), &error);
if (error.error != QJsonParseError::NoError) {
qCritical() << "JSON parsing error: " << error.errorString();
return NULL;
}
// 檢查保存的值是否是對(duì)象
if (document.isObject()) {
QJsonObject object = document.object(); // 將它轉(zhuǎn)換為JSON對(duì)象
for (auto it = object.begin(); it != object.end(); ++it) {
const QString key = it.key();
strtemp += "\nKey: " + key;
qDebug() << "Key:" << key;
// 此處可根據(jù)自己需求進(jìn)一步處理
}
}
return strtemp;
}五、保存JSON數(shù)據(jù)到文件
要將JSON數(shù)據(jù)保存到文件中,你可以使用QFile和QTextStream(或QDataStream,但通常對(duì)于文本數(shù)據(jù),QTextStream更合適)。首先,你需要將QJsonDocument對(duì)象序列化為QByteArray,然后將其寫(xiě)入文件。
// 保存JSON數(shù)據(jù)到文件
void saveJsonToFile(const QString &fileName, const QJsonObject &person) {
// 創(chuàng)建JSON文檔
QJsonDocument doc(person);
QFile file(fileName);
// 若文件打開(kāi)失敗,異常處理
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qCritical() << "無(wú)法打開(kāi)"<< fileName << "文件進(jìn)行寫(xiě)入" ;
return;
}
/*
若使用QTextStream,需包含頭文件"QTextStream"
QTextStream out(&file);
out << doc.toJson(QJsonDocument::Indented);
*/
// 這里使用QFile
file.write(doc.toJson(QJsonDocument::Indented)); // 使用縮進(jìn)格式使其更易于閱讀
file.close();
}在上面示例函數(shù)中,我們使用了QJsonDocument::Indented選項(xiàng)來(lái)生成格式化的JSON字符串,這使得文件內(nèi)容更易于人類(lèi)閱讀。然而,如果你關(guān)心文件大小或性能,可以選擇不使用縮進(jìn)(即省略QJsonDocument::Indented參數(shù))。
六、從文件讀取JSON數(shù)據(jù)
從文件讀取JSON數(shù)據(jù)是上述保存過(guò)程的逆過(guò)程,使用QFile和QTextStream讀取文件內(nèi)容,然后使用QJsonDocument::fromJson方法解析JSON字符串,。
// 讀取文件數(shù)據(jù)
QString loadJsonFromFile(const QString &fileName) {
QFile file(fileName);
// 若文件打開(kāi)失敗,異常處理
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCritical() << "無(wú)法打開(kāi)"<< fileName << "文件進(jìn)行讀取";
return NULL;
}
/*
若使用QTextStream,需包含頭文件"QTextStream"
QTextStream in(&file);
QString jsonString = in.readAll();
*/
QString jsonString = file.readAll(); // 讀取全部?jī)?nèi)容
file.close(); // 關(guān)閉文件
return jsonString; // 返回讀取內(nèi)容,注意:此處內(nèi)容未解析,可以和上述的解析函數(shù)結(jié)合使用
} 七、代碼及運(yùn)行結(jié)果
1. UI測(cè)試界面

2. 代碼示例
- qjsonoper.h
#ifndef QJSONOPER_H
#define QJSONOPER_H
#include <QDialog>
QT_BEGIN_NAMESPACE
namespace Ui { class QJsonOper; }
QT_END_NAMESPACE
class QJsonOper : public QDialog
{
Q_OBJECT
public:
QJsonOper(QWidget *parent = nullptr);
~QJsonOper();
private slots:
void on_wJsonBtn_clicked(); // 將數(shù)據(jù)信息寫(xiě)入JSON文件槽函數(shù)
void on_rJsonBtn_clicked();// 讀取JSON文件數(shù)據(jù)槽函數(shù)
private:
Ui::QJsonOper *ui;
};
#endif // QJSONOPER_H
- qjsonoper.cpp
#include "qjsonoper.h"
#include "ui_qjsonoper.h"
#include <QMessageBox>
#include <QDebug>
#include <QFile> // 文件操作
#include <QJsonObject> // JSON對(duì)象
#include <QJsonArray> // JSON數(shù)組
#include <QJsonDocument> // JSON文檔
#include <QJsonParseError> // JSON異常捕捉
QJsonOper::QJsonOper(QWidget *parent)
: QDialog(parent)
, ui(new Ui::QJsonOper)
{
ui->setupUi(this);
}
QJsonOper::~QJsonOper()
{
delete ui;
}
// 1. 生成復(fù)雜JSON對(duì)象
QJsonObject createJSONObject() {
QJsonObject personObject; // JSON對(duì)象
// 方式一:insert()方法
personObject.insert("name","John Doe");
personObject.insert("age", 30);
personObject.insert("isEmployed", true);
QJsonObject addressObject;
// 方式二:賦值
addressObject["street"] = "123 Main St.";
addressObject["city"] = "Anytown";
addressObject["country"] = "USA";
personObject["address"] = addressObject; // 嵌套JSON對(duì)象
QJsonArray hobbiesArray; // JSON數(shù)組
hobbiesArray.append("Reading");
hobbiesArray.append("Gaming");
personObject["hobbies"] = hobbiesArray; // 嵌套JSON數(shù)組
return personObject;
}
// 2. 解析JSON對(duì)象
QString parseAndPrintJSON(const QString &jsonString) {
QString strtemp; // 解析后的內(nèi)容
QJsonParseError error; // 返回JSON解析錯(cuò)誤的時(shí)候,報(bào)告錯(cuò)誤信息
QJsonDocument document = QJsonDocument::fromJson(jsonString.toUtf8(), &error);
if (error.error != QJsonParseError::NoError) {
qCritical() << "JSON parsing error: " << error.errorString();
return NULL;
}
// 檢查保存的值是否是對(duì)象
if (document.isObject()) {
QJsonObject object = document.object(); // 將它轉(zhuǎn)換為JSON對(duì)象
QStringList keys = object.keys(); //得到所有key
/*for (auto it = object.begin(); it != object.end(); ++it) {
const QString key = it.key();
strtemp += "\nKey: " + key;
qDebug() << "Key:" << key;
// 此處可根據(jù)自己需求進(jìn)一步處理
}*/
for (int i = 0; i < keys.size(); i++) // 遍歷每一個(gè)鍵值
{
QString key = keys.at(i);
QJsonValue value = object.value(key);
if (value.isBool())
{
strtemp += key + ":" + value.toBool() + "\n";
}
else if (value.isString())
{
strtemp += key + ":" + value.toString() + "\n";
}
else if (value.isDouble())
{
strtemp += key + ":" + value.toDouble() + "\n";
}
else if (value.isArray())
{
strtemp += keys.at(i) + ":" + "\n";
QJsonArray array = value.toArray();
for (int j = 0; j < array.size(); j++)
{
strtemp += " " + array[j].toString() + "\n";
}
}
else if (value.isObject())
{
strtemp += key + ":" + "\n";
QJsonObject subObj = value.toObject();
QStringList subKeys = subObj.keys();
for(int k = 0; k < subKeys.size(); ++k)
{
QJsonValue subValue = subObj.value(subKeys.at(k));
if (subValue.isString())
{
strtemp += " " + subKeys.at(k) + ":" + subValue.toString() + "\n";
}
else if (subValue.isArray())
{
strtemp += subKeys.at(k) + ":" + "\n";
QJsonArray array = subValue.toArray();
for (int m = 0; m < array.size(); m++)
{
strtemp += " " + array[m].toString() + "\n";
}
}
}
}
}
}
return strtemp;
}
// 3. 保存JSON數(shù)據(jù)到文件
void saveJsonToFile(const QString &fileName, const QJsonObject &person) {
// 創(chuàng)建JSON文檔
QJsonDocument doc(person);
QFile file(fileName);
// 若文件打開(kāi)失敗,異常處理
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qCritical() << "無(wú)法打開(kāi)"<< fileName << "文件進(jìn)行寫(xiě)入" ;
return;
}
/*
若使用QTextStream
QTextStream out(&file);
out << doc.toJson(QJsonDocument::Indented);
*/
// 這里使用QFile
file.write(doc.toJson(QJsonDocument::Indented)); // 使用縮進(jìn)格式使其更易于閱讀
file.close();
}
// 4. 讀取文件數(shù)據(jù)
QString loadJsonFromFile(const QString &fileName) {
QFile file(fileName);
// 若文件打開(kāi)失敗,異常處理
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCritical() << "無(wú)法打開(kāi)"<< fileName << "文件進(jìn)行讀取";
return NULL;
}
/*
若使用QTextStream,需包含頭文件"QTextStream"
QTextStream in(&file);
QString jsonString = in.readAll();
*/
QString jsonString = file.readAll(); // 讀取全部?jī)?nèi)容
file.close(); // 關(guān)閉文件
return jsonString; // 返回讀取內(nèi)容,注意:此處內(nèi)容未解析,可以和上述的解析函數(shù)結(jié)合使用
}
// 將數(shù)據(jù)信息寫(xiě)入JSON文件槽函數(shù)
void QJsonOper::on_wJsonBtn_clicked()
{
// 生成JSON對(duì)象
QJsonObject person = createJSONObject();
// 保存JSON數(shù)據(jù)到文件
saveJsonToFile("person.json", person);
// 若保存成功,對(duì)話(huà)框彈出
QMessageBox::information(this,"success", "恭喜你!成功保存JSON數(shù)據(jù)到文件!");
}
// 讀取JSON文件數(shù)據(jù)槽函數(shù)
void QJsonOper::on_rJsonBtn_clicked()
{
QString fileName = "person.json";
// 讀取JSON文件數(shù)據(jù),注意未解析
QString jsonString = loadJsonFromFile(fileName);
// 解析JSON對(duì)象
QString str = parseAndPrintJSON(jsonString);
// 若讀取成功,對(duì)話(huà)框彈出
QMessageBox::information(this,fileName, str, QMessageBox::Yes);
}
- main.cpp
#include "qjsonoper.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QJsonOper w;
w.show();
return a.exec();
}
3. 運(yùn)行結(jié)果
- 點(diǎn)擊:寫(xiě)入JSON文件信息

查看person.json文件:

- 點(diǎn)擊:讀取JSON文件信息

八、總結(jié)
在Qt中處理JSON數(shù)據(jù)是一個(gè)常見(jiàn)且重要的任務(wù),特別是在需要與Web服務(wù)、配置文件或其他基于JSON的數(shù)據(jù)源進(jìn)行交互的應(yīng)用程序中。通過(guò)本文的講解,我們了解了在Qt中處理JSON數(shù)據(jù)的幾個(gè)關(guān)鍵步驟,包括生成JSON數(shù)據(jù)、解析JSON字符串、遍歷JSON對(duì)象和數(shù)組、以及將JSON數(shù)據(jù)保存到文件和從文件讀取JSON數(shù)據(jù)。
生成JSON數(shù)據(jù):
我們使用QJsonObject和QJsonArray來(lái)構(gòu)建JSON對(duì)象和數(shù)組。QJsonObject用于存儲(chǔ)鍵值對(duì),而QJsonArray則用于存儲(chǔ)值的數(shù)組。通過(guò)將這些對(duì)象組合起來(lái),我們可以構(gòu)建復(fù)雜的JSON結(jié)構(gòu)。解析JSON字符串:
使用QJsonDocument::fromJson()方法將JSON格式的字符串解析為QJsonDocument對(duì)象。如果解析成功,我們可以進(jìn)一步將QJsonDocument對(duì)象轉(zhuǎn)換為QJsonObject或QJsonArray,以便訪(fǎng)問(wèn)JSON數(shù)據(jù)。遍歷JSON對(duì)象和數(shù)組:
對(duì)于QJsonObject,我們可以使用value()方法來(lái)訪(fǎng)問(wèn)其鍵值對(duì)。對(duì)于QJsonArray,我們可以使用迭代器或索引來(lái)遍歷其元素。每個(gè)元素可以是另一個(gè)QJsonObject、QJsonArray或基本數(shù)據(jù)類(lèi)型的值。保存JSON數(shù)據(jù)到文件:
將QJsonDocument對(duì)象轉(zhuǎn)換為QByteArray,然后使用QFile和QTextStream(或QDataStream,但通常對(duì)于文本數(shù)據(jù),QTextStream更合適)將字節(jié)數(shù)組寫(xiě)入文件。我們可以使用QJsonDocument::toJson()方法,并可選地指定縮進(jìn),以生成易于閱讀的JSON格式。從文件讀取JSON數(shù)據(jù):
使用QFile和QTextStream(或QDataStream)從文件讀取JSON字符串,然后使用QJsonDocument::fromJson()方法將其解析為QJsonDocument對(duì)象。錯(cuò)誤處理:
在解析JSON字符串和打開(kāi)文件時(shí),我們始終應(yīng)該檢查是否發(fā)生了錯(cuò)誤,并適當(dāng)?shù)靥幚硭鼈?。例如,如果JSON字符串格式不正確或文件無(wú)法打開(kāi),我們應(yīng)該向用戶(hù)報(bào)告錯(cuò)誤并可能采取恢復(fù)措施。
通過(guò)掌握這些基本技能,你可以在Qt應(yīng)用程序中有效地使用JSON數(shù)據(jù),無(wú)論是用于配置管理、網(wǎng)絡(luò)通信還是數(shù)據(jù)持久化。JSON的靈活性、易用性和普及性使其成為許多現(xiàn)代應(yīng)用程序中數(shù)據(jù)交換的首選格式。
到此這篇關(guān)于Qt服務(wù)應(yīng)用操作之JSON文件操作方法的文章就介紹到這了,更多相關(guān)Qt JSON文件操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)小貓釣魚(yú)算法
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)小貓釣魚(yú)算法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01
C語(yǔ)言結(jié)構(gòu)體鏈表和指針實(shí)現(xiàn)學(xué)生管理系統(tǒng)
這篇文章主要介紹了C語(yǔ)言結(jié)構(gòu)體鏈表和指針實(shí)現(xiàn)學(xué)生管理系統(tǒng),包括學(xué)生檔案管理子系統(tǒng)和學(xué)生成績(jī)管理子系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
對(duì)比分析C語(yǔ)言中的gcvt()和ecvt()以及fcvt()函數(shù)
這篇文章主要介紹了對(duì)比分析C語(yǔ)言中的gcvt和ecvt以及fcvt函數(shù),都是將數(shù)字轉(zhuǎn)化為字符串,注意其之間的功能區(qū)別,需要的朋友可以參考下2015-08-08
C語(yǔ)言中字符串的內(nèi)存地址操作的相關(guān)函數(shù)簡(jiǎn)介
這篇文章主要介紹了C語(yǔ)言中字符串的內(nèi)存地址操作的相關(guān)函數(shù),包括bcopy()函數(shù)和bzero()函數(shù)以及bcmp()函數(shù),需要的朋友可以參考下2015-08-08
C++編程使用findfirst和findnext查找及遍歷文件實(shí)現(xiàn)示例
這篇文章主要為大家介紹了C++編程如何使用findfirst和findnext查找及遍歷文件實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10
C語(yǔ)言實(shí)現(xiàn)自動(dòng)分配地址的示例
本文介紹了兩種自動(dòng)分配地址的方法,包括通過(guò)宏定義實(shí)現(xiàn)地址分配和將EE地址作為一個(gè)結(jié)構(gòu)體,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-11-11

