原文链接:https://blog.csdn.net/Edwinwzy/article/details/131668533
做上位机的时候下发数据,数据是一个结构体,这里就阐述一下怎么通过TCP协议发送结构体。
我自己写的时候主要通过两种方式,一种是memcpy,另一种是用QDataStream。
先在mainwindow.h头文件中定义结构体:
struct EDWINWZY
{
char name='A';
int age=1;
}edwinwzy;
函数原型为void *memcpy(void *destin, void *source, unsigned n);函数的功能是从源内存地址的起始位置开始拷贝若干个字节到目标内存地址中,即从源source中拷贝n个字节到目标destin中
//定义bit流
QByteArray transfer;
//使用memcpy之前要分配内存空间
transfer.resize(sizeof(struct EDWINWZY));
//data.resize(sizeof(edwinwzy));//写法和上面一句效果一样
//内存拷贝
memcpy(transfer.data(),&edwinwzy,sizeof(edwinwzy));
//发送比特流数据
tcpSocket->write(transfer);
这种方式似乎就定死了只能发送结构体大小的数据,但其实不然,我可以通过QByteArray类的成员函数append来添加一个乃至多个字节的数据。
下面的append函数中备选的参数类型名就说明了很多,我可以添加单个字符,也可以添加n个同一个字符,也可以添加另外一个QByteArray的数据,即一串比特流数据,亦可以添加QString类型的数据。
那这是在发送完一整个结构体之后再添加数据,如果我想单独一个一个发结构体的变量呢?
那其实直接用append就可以了。
//定义bit流
QByteArray transfer;
transfer.append(edwinwzy.name);
transfer.append(edwinwzy.age);
transfer.append('\n');
//发送比特流数据
tcpSocket->write(transfer);
有个要注意的是,有时候我最后不加换行符,接收端可能会出现无法显示的情况。这个我只在书中TCPClient项目中出现过,我用串口转网口来接收网口的数据,在串口端接收到的数据都是正常的。
这个就类似于C++ 的std::cout了。
不过发送的数据有两种情况。
第一种情况是直接用<<符号进行发送,这种发送会额外发送几个字节数据用来表示我发送的数据所占的字节数。
QByteArray tranferdata;
//后面这个QIODevice什么的也可以不选择添加。
QDataStream out(&tranferdata,QIODevice::WriteOnly|QIODevice::Append);
char A=a,B=b,C=c,D=d;
out<<A<<B<<C<<D;
tcpSocket->write(transfer);
实际上我们收到的字节数据用应该是 04 61 62 63 64,而我们其实只要后面的四个abcd的ascii码数据,那这个方法就有点问题了。
下面这个写原始数据的writeRawData函数就解决了问题
如果我们要发送其他类型数据(不是char类型),那我们使用这个函数的时候最好做一个强制类型转换。
QByteArray tranferdata;
//后面这个QIODevice什么的也可以不选择添加。
QDataStream out(&tranferdata,QIODevice::WriteOnly|QIODevice::Append);
int A=91,B=92;
out.writeRawData((char*)&A,sizeof(A));
out.writeRawData((char*)&B,sizeof(B));
tcpSocket->write(transfer);
这种写法就解决了多发送字节的问题,只不过因为这里AB是以int举例,所以它们分别占4字节。
收到的数据就应该为 00 00 00 61 00 00 00 62
这篇博客主要针对TCP发送结构体数据遇到的问题进行了归纳,发单个以及发部分情况都可以实现。
原文链接:https://blog.csdn.net/IT_CREATE/article/details/119681949
先要明白json是什么,json说白了就是键值对形式的数据格式,key是字符串,值可以是对象、数组、字符串、基础数据类型等,主要用于场景是,前后端数据传输,作为项目配置文件,比如web端比较流行的vue,相比于xml格式的优点是体积更轻,更简洁,单位携带数据更多等特点,现在json格式已经说是应用非常广泛了。json格式的内容中不能出现注释,不然无法解析,相比于xml可以注释,这个也可以说是个遗憾,毕竟json属于轻量级文本,但是我们可以通过一些特殊处理达到注释的要求,这样,对于文本我们也就更容易理解,比如,web前端的webpack在解析配置json文件时就针对注释做了处理。
说回正题,qt中我们用qjson来进行解析。首先要使用需要引入相关头文件
#include
#include
以读取下面这个文件内容为例:
/* 目前只支持 (左斜杠* + *左斜杠) 作为注释,且不能交替,即注释(左斜杠* + *左斜杠)里面不能包含(左斜杠* + *左斜杠)嵌套 */
/* qt要成功使用mysql:请参考:https://blog.csdn.net/IT_CREATE/article/details/119155290?spm=1001.2014.3001.5501 */
{
"dataBaseDrive":"mysql", /* sql驱动名,当前支持mysql、sqllite */
"dataBaseNameParam":{ /* 数据库名称设置 */
"names":["infosystem", "infosystem.db"], /* 数据库名称集合 */
"useIndex":0 /* 需要连接使用的数据库名称所在索引值,从0开始,从上面的数据库名称数组中取;本项目中请遵循mysql使用不含.db后缀名称 , sqlite 使用含.db后缀名称 */
},
"dataBaseHostName":"localhost", /* mysql所在服务器ip,(sqllite不会使用)*/
"dataBasePort":3306, /* mysql连接端口,(sqllite不会使用) */
"dataBaseUserName":"root", /* mysql连接用户名,(sqllite不会使用) */
"dataBasePassWord":"root", /* mysql连接密码,(sqllite不会使用) */
"projectFirstStartLoadDefaultTableData":true /* 项目第一次启动是否加载默认数据,本项目的默认数据是学生表信息*/
}
要点就是:
1)通过QFile读出文件内容,这时候是字符串,如果有注释,可以按我的代码先把注释去掉
2)通过QJsonDocument::fromJson把字符串转换为QJsonDocument对象,再转变为QJsonObject 对象
3)通过QJsonObject .value(“键值”)的方式,取出json中这些键对应的值
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
loadSetting();
}
void loadSetting() {
QFile settingFile;
settingFile.setFileName(":/setting/setting.json");
if(settingFile.open(QFile::ReadOnly)) {
// 读取json文件的内容,当前读取的内容可能是错误的,因为json文件不能有注释,而我在json中添加了注释,所以需要把注释内容去掉
QByteArray setting = settingFile.readAll().trimmed();
// 循环删除掉注释内容
while (setting.contains("/*") && setting.contains("*/")) {
int start = setting.indexOf("/*"); // 注释左索引(这里会返回左斜杠所在索引值)
int end = setting.indexOf("*/") + 1; // 注释右索引(这里会返回*所在索引值,所以我们需要+1,将索引值切换到左斜杠位置)
setting = setting.remove(start, (end - start) + 1); // 移除 /* xxxx */ 这一块的注释内容,(结束索引-开始索引+1)是整个注释内容的长度
}
settingFile.close();
qDebug()<<"配置json文件内容:"<<QString(setting);
QJsonParseError jsonError;
QJsonDocument jsonDoc(QJsonDocument::fromJson(setting, &jsonError));
if(jsonError.error == QJsonParseError::NoError)
{
QJsonObject rootObj = jsonDoc.object();
// 下面调用toxxxx方法转换值时,传入方法的值是在没读取到相应属性时返回的默认值
QString dataBaseDrive = rootObj.value("dataBaseDrive").toString(UserDefineConstant::DATA_BASE_DRIVE_NAME); // 读取配置文件中sql驱动的指定
QJsonObject dataBaseNameParam = rootObj.value("dataBaseNameParam").toObject(QJsonObject()); // 读取配置文件中数据库名称设置参数
QJsonArray dataBaseNames = dataBaseNameParam.value("names").toArray(QJsonArray()); // 读取配置文件中数据库名称集合
int useIndex = dataBaseNameParam.value("useIndex").toInt(-1); // 读取配置文件中需要连接使用的数据库名称所在索引值
QString dataBaseName = useIndex < 0 || useIndex > dataBaseNames.size() - 1
? UserDefineConstant::DATA_BASE_NAME : dataBaseNames.at(useIndex).toString(UserDefineConstant::DATA_BASE_NAME); // 或取数据库名称
QString dataBaseHostName = rootObj.value("dataBaseHostName").toString(UserDefineConstant::DATA_BASE_HOST_NAME); // 读取配置文件中数据库连接ip地址
int dataBasePort = rootObj.value("dataBasePort").toInt(UserDefineConstant::DATA_BASE_PORT); // 读取配置文件中数据库连接端口
QString dataBaseUserName = rootObj.value("dataBaseUserName").toString(UserDefineConstant::DATA_BASE_USER_NAME); // 读取配置文件中数据库连接用户名
QString dataBasePassWord = rootObj.value("dataBasePassWord").toString(UserDefineConstant::DATA_BASE_PASS_WORD); // 读取配置文件中数据库连接密码
bool projectFirstStartLoadDefaultTableData = rootObj.value("projectFirstStartLoadDefaultTableData").toBool(UserDefineConstant::PROJECT_FIRST_START_LOAD_DEFAULT_TABLE_DATA); // 读取配置文件中工程第一次启动是否加载默认数据
// 如果配置文件中的指定数据库既不是mysql也不是sqllite,则默认采用sqllite
if(dataBaseDrive != UserDefineConstant::SQL_DRIVE_MYSQL_NAME && dataBaseDrive != UserDefineConstant::SQL_DRIVE_SQLLITE_NAME) {
UserDefineConstant::DATA_BASE_DRIVE_NAME = UserDefineConstant::SQL_DRIVE_SQLLITE_NAME;
qDebug()<<"读取到使用数据库类型:"<<dataBaseDrive <<"不属于【mysql、sqllite】, 已切换到默认sqllite";
} else {
UserDefineConstant::DATA_BASE_DRIVE_NAME = dataBaseDrive;
qDebug()<<"读取到使用数据库类型:"<<dataBaseDrive;
}
qDebug()<<"读取到转换后数据库配置:"
<<"dataBaseDrive:"+dataBaseDrive
<<"dataBaseName:"+dataBaseName
<<"dataBaseHostName:"+dataBaseHostName
<<"dataBasePort:"+QString::number(dataBasePort)
<<"dataBaseUserName:"+dataBaseUserName
<<"dataBasePassWord:"+dataBasePassWord;
UserDefineConstant::DATA_BASE_NAME = dataBaseName; // 设置连接数据库名称
// 以下数据库设置只对mysql生效
UserDefineConstant::DATA_BASE_HOST_NAME = dataBaseHostName; // 设置连接数据库ip
UserDefineConstant::DATA_BASE_PORT = dataBasePort; // 设置连接数据库端口
UserDefineConstant::DATA_BASE_USER_NAME = dataBaseUserName; // 设置连接数据库用户名
UserDefineConstant::DATA_BASE_PASS_WORD = dataBasePassWord; // 设置连接数据库密码
// 设置第一次启动是否加载默认数据(当前默认数据为学生信息)
UserDefineConstant::PROJECT_FIRST_START_LOAD_DEFAULT_TABLE_DATA = projectFirstStartLoadDefaultTableData;
qDebug()<<"读取到项目是否启动默认数据:"<<projectFirstStartLoadDefaultTableData;
} else {
qDebug() << "json error!" << jsonError.errorString();
}
}
}
以该json文件为例:
{
"logSwitchoverType": "time_period",
"switchoverNum": "30",
"switchoverTime": "2021-08-12 17:16:36"
}
要点就是:
1)先通过QJsonObject把需要写入json的参数先进行组装,这个有点类似于我们操作QMap;
2)再通过QJsonDocument 把QJsonObject对象转换成json字符串;
3)最后再将这个字符串写入到文件即可
// 写入备份参数到日志备份配置json文件中
void Log::writeLogParamJson()
{
QDateTime nowTime = QDateTime::currentDateTime();
QString switchoverTimeStr = "";
if(Log::logSwitchoverType == LogSwitchoverType::ALL_DAY) {
// 指定天数之后
Log::switchoverTime = nowTime.addDays(Log::switchoverNum);
switchoverTimeStr = switchoverTime.toString("yyyy-MM-dd");
} else if(Log::logSwitchoverType == LogSwitchoverType::TIME_PERIOD) {
// 指定秒之后
Log::switchoverTime = nowTime.addSecs(Log::switchoverNum);
switchoverTimeStr = nowTime.toString("yyyy-MM-dd hh:mm:ss");
}
QJsonObject jsonObject;//构建json对象json
jsonObject.insert("logSwitchoverType", Log::logSwitchoverTypeMap.value(Log::logSwitchoverType, ""));
jsonObject.insert("switchoverNum", QString::number(Log::switchoverNum));
jsonObject.insert("switchoverTime", switchoverTimeStr);
QJsonDocument document;
document.setObject(jsonObject);
QString jsonStr(document.toJson(QJsonDocument::Indented));
// 如果文件所在文件夹不存在则创建文件夹
QFileInfo fileInfo = QFileInfo(Log::logParamJsonFile->fileName());
QDir dir = fileInfo.absoluteDir();
if(!dir.exists()) {
dir.mkdir(dir.absolutePath());
}
if(Log::logParamJsonFile->open(QIODevice::WriteOnly | QIODevice::Text)) {
Log::logParamJsonFile->write(jsonStr.toUtf8());
Log::logParamJsonFile->flush();
Log::logParamJsonFile->close();
printSystemLog("info", "写入备份日志参数到"+fileInfo.absoluteFilePath()+",成功;参数:"+jsonStr);
} else {
printSystemLog("error", "写入备份日志参数到"+fileInfo.absoluteFilePath()+",失败");
}
}
原文链接:https://blog.csdn.net/hw5230/article/details/128649965
.ini 文件是Initialization File的缩写,即初始化文件。
除了windows现在很多其他操作系统下面的应用软件也有.ini文件,用来配置应用软件以实现不同用户的要求。一般不用直接编辑这些.ini文件,应用程序的图形界面即可操作以实现相同的功能。它可以用来存放软件信息,注册表信息等。
读INI文件
INI文件内容如下:
[conn]
ip=127.0.0.1
port=8080
databaseversion=QSQLITE
databasename=student
username=YYC
password=root
qreadini.h文件内容如下:
#ifndef QREADINI_H
#define QREADINI_H
#include
#define DATACONFIG QReadIni::getInstance()->getIniConfig()
typedef struct IniConfig
{
QString ip; //IP地址
QString port; //端口
QString dataBaseVersion; //数据库版本
QString dataBaseName; //数据库名称
QString userName; //用户名
QString passWord; //密码
}IniConfig;
class QReadIni
{
public:
static QReadIni*getInstance();
void readIni();
const IniConfig &getIniConfig();
private:
QReadIni();
IniConfig iniConfig;
static QReadIni*instance;
};
#endif // QREADINI_H
qreadini.cpp文件内容如下:
#include "qreadini.h"
QReadIni*QReadIni::instance = NULL;
QReadIni *QReadIni::getInstance()
{
if(instance == NULL)
{
instance = new QReadIni();
}
return instance;
}
QReadIni::QReadIni()
{
this->readIni();
}
void QReadIni::readIni()
{
QSettings * configIniRead = new QSettings("config.ini",QSettings::IniFormat);//初始化读取Ini文件对象
iniConfig.ip = configIniRead->value("conn/ip").toString(); //IP地址
iniConfig.port = configIniRead->value("conn/port").toString(); //端口
iniConfig.dataBaseVersion = configIniRead->value("conn/databaseversion").toString();//数据库版本
iniConfig.dataBaseName = configIniRead->value("conn/databasename").toString(); //数据库名称
iniConfig.userName = configIniRead->value("conn/username").toString(); //用户名
iniConfig.passWord = configIniRead->value("conn/password").toString(); //密码
delete configIniRead;
}
const IniConfig &QReadIni::getIniConfig()
{
return iniConfig;
}
写ini文件
#include
#include
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
//Qt中使用QSettings类读写ini文件
//QSettings构造函数的第一个参数是ini文件的路径,第二个参数表示针对ini文件,第三个参数可以缺省
QSettings *configIniWrite = new QSettings("hahaya.ini", QSettings::IniFormat);
//向ini文件中写入内容,setValue函数的两个参数是键值对
//向ini文件的第一个节写入内容,ip节下的第一个参数
configIniWrite->setValue("/ip/first", "192.168.0.1");
//向ini文件的第一个节写入内容,ip节下的第二个参数
configIniWrite->setValue("ip/second", "127.0.0.1");
//向ini文件的第二个节写入内容,port节下的第一个参数
configIniWrite->setValue("port/open", "2222");
//写入完成后删除指针
delete configIniWrite;
return a.exec();
}
{
"conn": {
"ip": "127.0.0.1",
"port": "8080",
"databaseversion": "QSQLITE",
"databasename": "student",
"username": "YYC",
"password": "root"
}
}
qreadjson.h文件内容如下
#ifndef QREADJSON_H
#define QREADJSON_H
#include
#include
#include
#include
#include
#include
#define JSONCONFIG QReadJson::getInstance()->getJsonConfig()
typedef struct JsonConfig
{
QString ip; //IP地址
QString port; //端口
QString dataBaseVersion; //数据库版本
QString dataBaseName; //数据库名称
QString userName; //用户名
QString passWord; //密码
}JsonConfig;
class QReadJson
{
public:
static QReadJson * getInstance();
bool readJson();
const JsonConfig &getJsonConfig();
private:
QReadJson();
static QReadJson * instance;
JsonConfig jsonConfig;
};
#endif // QREADJSON_H
qreadjson.cpp内容如下:
#include"qreadjson.h"
QReadJson * QReadJson::instance = NULL;
QReadJson *QReadJson::getInstance()
{
if(NULL == instance)
{
instance = new QReadJson();
}
return instance;
}
QReadJson::QReadJson()
{
this->readJson();
}
bool QReadJson::readJson()
{
QString strJson;
QFile *file=new QFile("config.json");
if(file->open(QIODevice::ReadOnly | QIODevice::Text))
{
strJson = file->readAll();
file->close();
}
else
{
return false;
}
file->close();
QJsonDocument jsonDom = QJsonDocument::fromJson(strJson.toUtf8());
QJsonObject jsonObject = jsonDom.object();
QJsonValue jsonValue = jsonObject.value(QString("conn"));
QJsonObject objectItem = jsonValue.toObject();
jsonConfig.ip = objectItem["ip"].toString();
jsonConfig.port = objectItem["port"].toString();
jsonConfig.dataBaseVersion = objectItem["databaseversion"].toString();
jsonConfig.dataBaseName = objectItem["databasename"].toString();
jsonConfig.userName = objectItem["username"].toString();
jsonConfig.passWord = objectItem["password"].toString();
delete file;
return true;
}
const JsonConfig &QReadJson::getJsonConfig()
{
return jsonConfig;
}
原文链接:https://blog.csdn.net/weixin_44050362/article/details/131136264
Qt可以使用JSON作为配置文件。Qt提供了QJsonDocument和QJsonObject等类来处理JSON数据,可以将JSON数据解析为Qt中的对象,也可以将Qt中的对象序列化为JSON数据。
读取了一个名为config.json的JSON文件,解析出其中的name和age字段,并将它们输出到控制台。
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 读取JSON文件
QFile file("config.json");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return 1;
// 解析JSON数据
QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qDebug() << "JSON解析错误:" << error.errorString();
return 1;
}
// 读取配置项
QJsonObject obj = doc.object();
QString name = obj["name"].toString();
int age = obj["age"].toInt();
qDebug() << "姓名:" << name;
qDebug() << "年龄:" << age;
return a.exec();
}
在Qt中,我们可以使用QJsonDocument和QJsonObject等类来处理JSON数据,从而实现修改JSON值的功能。
读取了一个名为config.json的JSON文件,解析出其中的name和age字段,并将它们修改为"Tom"和25,最后将修改后的JSON数据重新写入文件。
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 读取JSON文件
QFile file("config.json");
if (!file.open(QIODevice::ReadWrite | QIODevice::Text))
return 1;
// 解析JSON数据
QJsonParseError error;
QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &error);
if (error.error != QJsonParseError::NoError) {
qDebug() << "JSON解析错误:" << error.errorString();
return 1;
}
// 修改配置项
QJsonObject obj = doc.object();
obj["name"] = "Tom";
obj["age"] = 25;
// 将修改后的JSON数据重新写入文件
file.seek(0);
file.write(doc.toJson());
file.resize(file.pos());
return a.exec();
}
默认情况下,Qt的可执行文件是不会包含JSON配置文件的。如果你希望将JSON配置文件打包到可执行文件中,可以使用Qt提供的资源系统。
资源系统允许你将各种类型的文件(包括JSON文件)打包到Qt应用程序中,以便在运行时访问这些文件。在打包时,资源文件会被编译成二进制格式,并嵌入到可执行文件中。
要使用资源系统,你需要在Qt项目中创建一个.qrc文件,用于描述需要打包的文件。例如,假设你有一个名为config.json的JSON配置文件,你可以创建一个名为myapp.qrc的资源文件,并在其中添加一个名为config的资源项,如下所示:
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource>
<file>config.json</file>
</qresource>
</RCC>
在Qt项目中,你需要在.pro文件中添加以下行来将资源文件包含在可执行文件中:
RESOURCES += myapp.qrc
这样,当你使用qrc://config.json路径来访问JSON文件时,Qt会自动从嵌入在可执行文件中的资源中加载文件内容。
注意,如果你需要修改JSON配置文件,你需要在运行时将其解压缩到本地文件系统中,然后进行修改,最后再将其保存回资源文件中。
qt,需要对可执行文件中的json配置文件进行修改时,如何进行解压缩,如何保存回资源文件中
要对可执行文件中的JSON配置文件进行修改,需要先将其解压缩。可以使用Qt提供的QResource类来读取和保存资源文件。以下是一个简单的示例代码,演示了如何解压缩和保存回资源文件中:
#include
#include
#include
#include
#include
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 获取资源文件中的配置文件
QResource resource(":/config.json");
QByteArray data = resource.data();
// 将数据保存到临时文件中
QTemporaryFile tempFile;
tempFile.setAutoRemove(false);
tempFile.open();
tempFile.write(data);
tempFile.close();
// 对配置文件进行修改
QFile file(tempFile.fileName());
if (file.open(QIODevice::ReadWrite | QIODevice::Text))
{
QTextStream stream(&file);
QString content = stream.readAll();
content.replace("old_value", "new_value");
file.resize(0);
stream << content;
file.close();
// 将修改后的文件重新打包到资源文件中
QFile resourceFile(":/config.json");
if (resourceFile.open(QIODevice::WriteOnly))
{
QDataStream stream(&resourceFile);
stream.writeRawData(data.constData(), data.size());
stream.writeRawData(tempFile.readAll().constData(), tempFile.size());
resourceFile.close();
}
}
return a.exec();
}
这个示例代码做了以下几件事情:
1.使用QResource类读取资源文件中的配置文件,并将数据保存到QByteArray中。
2.将数据保存到一个临时文件中。
3. 使用QFile类打开临时文件,并对其中的配置文件进行修改。
4.将修改后的文件重新打包到资源文件中。
注意,这个示例代码只能在可写的目录中使用,因为它需要将临时文件保存在磁盘上。如果你需要在只读目录中使用,可以考虑使用QByteArray或QBuffer来代替QTemporaryFile。
qt C++,如何将json格式数据转成二进制并保存成文件,又如何将文件中的二进制转换回json格式
将JSON格式数据转换为二进制并保存为文件,可以使用QJsonDocument和QByteArray类。具体步骤如下:
将JSON格式数据转换为QJsonDocument对象:
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonStr.toUtf8());
其中,jsonStr为QString类型的JSON格式数据。
将QJsonDocument对象转换为QByteArray对象:
QByteArray byteArray = jsonDoc.toBinaryData();
将QByteArray对象保存为文件:
QFile file("data.bin");
if (file.open(QIODevice::WriteOnly)) {
file.write(byteArray);
file.close();
}
将文件中的二进制数据转换为JSON格式,可以使用QJsonDocument和QByteArray类。具体步骤如下:
读取文件中的二进制数据:
QFile file("data.bin");
if (file.open(QIODevice::ReadOnly)) {
QByteArray byteArray = file.readAll();
file.close();
}
将QByteArray对象转换为QJsonDocument对象:
QJsonDocument jsonDoc = QJsonDocument::fromBinaryData(byteArray);
将QJsonDocument对象转换为JSON格式字符串:
QString jsonStr = jsonDoc.toJson();
其中,jsonStr为QString类型的JSON格式数据。
qt C++,如何读取json数据中的某一项
在Qt C++中,可以使用QJsonDocument类来解析JSON数据。以下是一个简单的示例,演示如何读取JSON数据中的某一项:
// 假设我们有以下JSON数据
QByteArray jsonData = "{\"name\": \"张三\", \"age\": 25}";
// 将JSON数据转换为QJsonDocument对象
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData);
// 获取JSON对象
QJsonObject jsonObj = jsonDoc.object();
// 读取name项的值
QString name = jsonObj["name"].toString();
// 读取age项的值
int age = jsonObj["age"].toInt();
在上面的示例中,我们首先将JSON数据转换为QJsonDocument对象,然后获取JSON对象,并使用[]运算符读取特定项的值。请注意,如果JSON数据中不存在该项,则返回的值将是一个默认值,例如空字符串或零。
可以使用QJsonDocument类的fromJson()方法将QString类型的JSON格式数据转换成QJsonObject类型。具体实现如下:
QString jsonString = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}";
QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonString.toUtf8());
QJsonObject jsonObject = jsonDocument.object();
在这个例子中,我们首先定义了一个QString类型的JSON格式数据,然后使用QJsonDocument类的fromJson()方法将其转换成QJsonDocument类型。最后,我们使用QJsonDocument类的object()方法将QJsonDocument类型转换成QJsonObject类型。
需要注意的是,如果JSON格式数据不符合规范,或者转换过程中出现错误,fromJson()方法将返回一个空的QJsonDocument对象。因此,在实际使用中,需要进行错误处理。
原文链接:https://blog.csdn.net/cpp_learner/article/details/118421096
花了几天时间研究Qt如何操作Json文件,也是有一点心得,现在记录下来分享!
为什么要学习Json呢?Json是一个轻量级数据存储文件,其里面使用了大量的字符进行存储数据。JSON 是存储和交换文本信息的语法,类似 XML。JSON 比 XML 更小、更快,更易解析。
JSON 是一种编码来自 Javascript 的对象数据的格式,但现在已广泛用作互联网上的数据交换格式。
Qt 中的 JSON 支持提供了易于使用的C++ API 来解析、修改和保存 JSON 数据。
当然,我学习Json,主要是因为我的上一篇博客中学习了Qt的Socket编程,个人觉得,如果是需要在TCP与UDP进行数据传送的话,使用Json文件传输效率会比较高吧…个人理解,不喜勿喷!
所以呢,今天带来一篇,使用Qt操作Json格式文件的博客,供大家参考、借鉴!
操作Json文件所需要用到的类:
操作Json文件所需要用到的头文件:
#include < QJsonObject > // { }
#include < QJsonArray > // [ ]
#include < QJsonDocument > // 解析Json
#include < QJsonValue > // int float double bool null { } [ ]
#include < QJsonParseError >
"interest": {
"basketball": "篮球",
"badminton": "羽毛球"
},
代码实现上述效果:
// 定义 { } 对象
QJsonObject interestObj;
// 插入元素,对应键值对
interestObj.insert("basketball", "篮球");
interestObj.insert("badminton", "羽毛球");
"color": [ "black", "white"],
代码实现上述效果:
// 定义 [ ] 对象
QJsonArray colorArray;
// 往数组中添加元素
colorArray.append("black");
colorArray.append("white");
"like": [
{ "game": "三国杀", "price": 58.5 },
{ "game": "海岛奇兵", "price": 66.65 }
],
代码实现上述效果:
// 定义 { } 对象
QJsonObject likeObject1;
likeObject1.insert("game", "三国杀");
likeObject1.insert("price", 58.5);
QJsonObject likeObject2;
likeObject2.insert("game", "海岛奇兵");
likeObject2.insert("price", 66.65);
// 定义 [ ] 对象
QJsonArray likeArray;
likeArray.append(likeObject1);
likeArray.append(likeObject2);
"languages": {
"serialOne": { "language": "汉语", "grade": 10 },
"serialTwo": { "language": "英语", "grade": 6 }
},
代码实现上述效果:
// 定义 { } 对象
QJsonObject language1;
language1.insert("language", "汉语");
language1.insert("grade", 10);
QJsonObject language2;
language2.insert("language", "英语");
language2.insert("grade", 6);
QJsonObject languages;
// 将{ } 插入 { } 中
languages.insert("serialOne", language1);
languages.insert("serialTwo", language2);
// 定义根节点 也即是最外层 { }
QJsonObject rootObject;
// 插入元素
rootObject.insert("name", "老王");
rootObject.insert("age", 26);
rootObject.insert("interest", interestObj);
rootObject.insert("color", colorArray);
rootObject.insert("like", likeArray);
rootObject.insert("languages", languages);
rootObject.insert("vip", true);
rootObject.insert("address", QJsonValue::Null);
// 将json对象里的数据转换为字符串
QJsonDocument doc;
// 将object设置为本文档的主要对象
doc.setObject(rootObject);
QFile file("../Json/js.json");
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
qDebug() << "can't open error!";
return;
}
QTextStream stream(&file);
stream.setCodec("UTF-8"); // 设置写入编码是UTF8
// 写入文件
stream << doc.toJson();
file.close();
这里需要注意的是,我们写入文件时,指定的编码是UTF8,所以在读取出来时也需要使用UTF8编码进行读取!
在这里创建好的json,下面也有对应的解析讲解!
那么,这种数组包含数组的效果该如何实现呢?
"color": [
[ "black", "white" ],
[ "red", "greed" ]
]
代码实现上述效果:
// 定义 [ ] 对象
QJsonArray colorArray;
// 定义 [ ] 对象
QJsonArray colorArray1;
// 往数组中添加元素
colorArray1.append("black");
colorArray1.append("white");
// 定义 [ ] 对象
QJsonArray colorArray2;
// 往数组中添加元素
colorArray2.append("red");
colorArray2.append("greed");
colorArray.append(colorArray1);
colorArray.append(colorArray2);
把代码写好后,编译运行,会在自己的项目路径中创建一个JSON文件,并写入内容,文件内容如下:
顺序可能有点乱,但是不妨碍我们阅读与下面解析!
解析根据上图进行!
在使用JSON对象或者JSON数组对象得到对应的value之后,该value值并不是最总的数据类型,而是一个QJsonValue类型的属性,我们必须通过该对象判断该类型的实际类型,然后在将其转换为对应的数据类型。
可以使用下面表格的方法,也可以使用代码中的方法进行判断,
类型判断相关成员方法:
QFile file("../Json/js.json");
if (!file.open(QFile::ReadOnly | QFile::Text)) {
qDebug() << "can't open error!";
return;
}
// 读取文件的全部内容
QTextStream stream(&file);
stream.setCodec("UTF-8"); // 设置读取编码是UTF8
QString str = stream.readAll();
file.close();
注意编码啊!设置读取编码是UTF8
// QJsonParseError类用于在JSON解析期间报告错误。
QJsonParseError jsonError;
// 将json解析为UTF-8编码的json文档,并从中创建一个QJsonDocument。
// 如果解析成功,返回QJsonDocument对象,否则返回null
QJsonDocument doc = QJsonDocument::fromJson(str.toUtf8(), &jsonError);
// 判断是否解析失败
if (jsonError.error != QJsonParseError::NoError && !doc.isNull()) {
qDebug() << "Json格式错误!" << jsonError.error;
return;
}
QJsonObject rootObj = doc.object();
// 根据键获取值
QJsonValue nameValue = rootObj.value("name");
qDebug() << "name = " << nameValue.toString();
QJsonValue ageValue = rootObj.value("age");
qDebug() << "age = " << ageValue.toInt();
// 解析 bool类型
QJsonValue vipValue = rootObj.value("vip");
qDebug() << "vip = " << vipValue.toBool();
// 解析 null类型
QJsonValue addressValue = rootObj.value("address");
if (addressValue.type() == QJsonValue::Null) {
qDebug() << "address = " << "null";
}
QJsonValue interestValue = rootObj.value("interest");
// 判断是否是object类型
if (interestValue.type() == QJsonValue::Object) {
// 转换为QJsonObject类型
QJsonObject interestObj = interestValue.toObject();
QJsonValue basketballValue = interestObj.value("basketball");
qDebug() << "basketball = " << basketballValue.toString();
QJsonValue badmintonValue = interestObj.value("badminton");
qDebug() << "badminton = " << badmintonValue.toString();
}
通过value函数根据键获取到一个QJsonValue 类型数据,然后进行判断是否是对应类型,然后转换成对应类型,就可以使用value函数进行获取QJsonValue值,再转换类型就可以拿到数据了。
QJsonValue colorValue = rootObj.value("color");
// 判断是否是Array类型
if (colorValue.type() == QJsonValue::Array) {
// 转换为QJsonArray类型
QJsonArray colorArray = colorValue.toArray();
for (int i = 0; i < colorArray.size(); i++) {
QJsonValue color = colorArray.at(i);
qDebug() << "color = " << color.toString();
}
}
// 根键获取值
QJsonValue likeValue = rootObj.value("like");
// 判断类型是否是数组类型
if (likeValue.type() == QJsonValue::Array) {
// 转换成数组类型
QJsonArray likeArray = likeValue.toArray();
// 遍历数组
for (int i = 0; i < likeArray.count(); i++) {
// 获取数组的第一个元素,类型是QJsonValue
QJsonValue likeValueChild = likeArray.at(i);
// 判断是不是对象类型
if (likeValueChild.type() == QJsonValue::Object) {
// 转换成对象类型
QJsonObject likeObj = likeValueChild.toObject();
// 最后通过value函数就可以获取到值了,解析成功!
QJsonValue gameLikeValue = likeObj.value("game");
qDebug() << "game = " << gameLikeValue.toString();
QJsonValue priceLikeValue = likeObj.value("price");
qDebug() << "price = " << priceLikeValue.toDouble();
}
}
}
// 根据建获取值
QJsonValue languagesValue = rootObj.value("languages");
// 判断是不是对象类型
if (languagesValue.type() == QJsonValue::Object) {
// 转换成对象类型
QJsonObject languagesObj = languagesValue.toObject();
// 根据建获取值
QJsonValue serialOneValue = languagesObj.value("serialOne");
// 判断是不是对象类型
if (serialOneValue.type() == QJsonValue::Object) {
// 转换成对象类型
QJsonObject serialOneObj = serialOneValue.toObject();
// 根据建获取值
QJsonValue languageValue = serialOneObj.value("language");
// 最后转换成对应类型就解析出来了!
qDebug() << "language = " << languageValue.toString();
QJsonValue gradeValue = serialOneObj.value("grade");
qDebug() << "grade = " << gradeValue.toInt();
}
QJsonValue serialTwoValue = languagesObj.value("serialTwo");
if (serialTwoValue.type() == QJsonValue::Object) {
QJsonObject serialTwoObj = serialTwoValue.toObject();
QJsonValue languageValue = serialTwoObj.value("language");
qDebug() << "language = " << languageValue.toString();
QJsonValue gradeValue = serialTwoObj.value("grade");
qDebug() << "grade = " << gradeValue.toInt();
}
}
// 根键获取值
QJsonValue colorValue = rootObject.value("color");
// 判断类型是否是数组类型
if (colorValue.type() == QJsonValue::Array) {
// 转换成数组类型
QJsonArray colorArray = colorValue.toArray();
// 遍历数组
for (int i = 0; i < colorArray.count(); i++) {
// 获取数组的第一个元素,类型是QJsonValue
QJsonValue colorValueChild = colorArray.at(i);
// 判断是不是数组类型
if (colorValueChild.type() == QJsonValue::Array) {
// 转换成数组类型
QJsonArray colorArr = colorValueChild.toArray();
for (int i = 0; i < colorArr.size(); i++) {
QJsonValue color = colorArr.at(i);
qDebug() << "color = " << color.toString();
}
}
}
}
修改的过程就是:将数据从文件中读取出来,解析成QJsonDocument对象后,在获取跟对象{ },通过跟对象在获取其他的对象{}或者数组[],修改后,再赋值给跟对象{},达到替换效果,也就是修改了,最后再写入文件即可!
读取数据解析成QJsonDocument代码省略,跟上面一样
获取根节点对象
// 获取根 { }
QJsonObject rootObj = doc.object();
// 修改name属性
rootObj["name"] = "老李";
rootObj["vip"] = false;
QJsonValue colorValue = rootObj.value("color");
if (colorValue.type() == QJsonValue::Array) {
QJsonArray colorArray = colorValue.toArray();
// 修改数组中的值
colorArray.replace(0, "blue");
colorArray.replace(1, "green");
// 赋值覆盖原有数组属性
rootObj["color"] = colorArray;
}
QJsonValue interestValue = rootObj.value("interest");
if (interestValue.type() == QJsonValue::Object) {
QJsonObject interestObject = interestValue.toObject();
interestObject["badminton"] = "乒乓球";
interestObject["basketball"] = "足球";
rootObj["interest"] = interestObject;
}
QJsonValue languagesValue = rootObj.value("languages");
if (languagesValue.type() == QJsonValue::Object) {
QJsonObject languagesObj = languagesValue.toObject();
// 找到内部第一个 { }
QJsonValue serialOneValue = languagesObj.value("serialOne");
if (serialOneValue.type() == QJsonValue::Object) {
QJsonObject serialOneObj = serialOneValue.toObject();
serialOneObj["grade"] = "20";
languagesObj["serialOne"] = serialOneObj;
}
// 找到内部第二个 { }
QJsonValue serialTwoValue = languagesObj.value("serialTwo");
if (serialTwoValue.type() == QJsonValue::Object) {
QJsonObject serialTwoObj = serialTwoValue.toObject();
serialTwoObj["grade"] = "10";
serialTwoObj["language"] = "粤语";
languagesObj["serialTwo"] = serialTwoObj;
}
rootObj["languages"] = languagesObj;
}
QJsonValue likeValue = rootObj.value("like");
if (likeValue.type() == QJsonValue::Array) {
QJsonArray likeArray = likeValue.toArray();
// 根据索引获得对应{ }
QJsonObject obj1 = likeArray[0].toObject();
obj1["game"] = "欢乐斗地主";
obj1["price"] = 88.8;
QJsonObject obj2 = likeArray[1].toObject();
obj2["game"] = "欢乐斗牛";
obj2["price"] = 77.7;
// 替换覆盖
likeArray.replace(0, obj1);
likeArray.replace(1, obj2);
rootObj["like"] = likeArray;
}
修改前:
修改后:
写入文件
最后,再将跟节点对象{ }重新设置给QJsonDocument对象,在重新写入文件即可!
// 将object设置为本文档的主要对象
doc.setObject(rootObj);
// 重写打开文件,覆盖原有文件,达到删除文件全部内容的效果
QFile writeFile("../Json/js.json");
if (!writeFile.open(QFile::WriteOnly | QFile::Truncate)) {
qDebug() << "can't open error!";
return;
}
// 将修改后的内容写入文件
QTextStream wirteStream(&writeFile);
wirteStream.setCodec("UTF-8"); // 设置读取编码是UTF8
wirteStream << doc.toJson(); // 写入文件
writeFile.close(); // 关闭文件
五、删除Json
删除跟修改类似的,使用跟节点对象找到对象{}或者数组[]后,使用remove函数指定键参数进行删除!
读取数据解析成QJsonDocument代码省略,跟上面一样
获取根节点对象
// 获取根 { }
QJsonObject rootObj = doc.object();
// 删除age
rootObj.remove("age");
QJsonValue colorValue = rootObj.value("color");
if (colorValue.type() == QJsonValue::Array) {
QJsonArray colorArray = colorValue.toArray();
// 删除数组中索引为1的值
colorArray.removeAt(1);
// 赋值覆盖原有数组属性
rootObj["color"] = colorArray;
}
QJsonValue interestValue = rootObj.value("interest");
if (interestValue.type() == QJsonValue::Object) {
QJsonObject interestObject = interestValue.toObject();
// 删除键为basketball的属性元素
interestObject.remove("basketball");
rootObj["interest"] = interestObject;
}
QJsonValue languagesValue = rootObj.value("languages");
if (languagesValue.type() == QJsonValue::Object) {
QJsonObject languagesObj = languagesValue.toObject();
// 删除键为serialTwo的对象 { }
languagesObj.remove("serialTwo");
rootObj["languages"] = languagesObj;
}
QJsonValue likeValue = rootObj.value("like");
if (likeValue.type() == QJsonValue::Array) {
QJsonArray likeArray = likeValue.toArray();
// 删除索引为1数组中的值
likeArray.removeAt(1);
rootObj["like"] = likeArray;
}
// 删除 [ ]
rootObj.remove("color");
// 删除 { }
rootObj.remove("interest");
删除后就没有啦!
我这代码使用VS2017新建一个QT空项目写出来的!
指定编码
#pragma execution_character_set(“utf-8”) // qt支持显示中文
#include
#include // { }
#include // [ ]
#include // 解析Json
#include // int float double bool null { } [ ]
#include
#include
#include
#include
#pragma execution_character_set("utf-8") // qt支持显示中文
// 封装Json
void createJson() {
/*
* "interest": {
* "basketball": "篮球",
* "badminton": "羽毛球"
* },
*/
// 定义 { } 对象
QJsonObject interestObj;
// 插入元素,对应键值对
interestObj.insert("basketball", "篮球");
interestObj.insert("badminton", "羽毛球");
/*
* "color": [ "black", "white"],
*/
// 定义 [ ] 数组
QJsonArray colorArray;
// 往数组中添加元素
colorArray.append("black");
colorArray.append("white");
/*
* "like": [
* { "game": "三国杀", "price": 58.5 },
* { "game": "海岛奇兵", "price": 66.65 }
* ],
*/
// 定义 { } 对象
QJsonObject likeObject1;
likeObject1.insert("game", "三国杀");
likeObject1.insert("price", 58.5);
QJsonObject likeObject2;
likeObject2.insert("game", "海岛奇兵");
likeObject2.insert("price", 66.65);
// 定义 [ ] 对象
QJsonArray likeArray;
likeArray.append(likeObject1);
likeArray.append(likeObject2);
/*
* "languages": {
* "serialOne": { "language": "汉语", "grade": 10 },
* "serialTwo": { "language": "英语", "grade": 6 }
* },
*/
// 定义 { } 对象
QJsonObject language1;
language1.insert("language", "汉语");
language1.insert("grade", 10);
QJsonObject language2;
language2.insert("language", "英语");
language2.insert("grade", 6);
QJsonObject languages;
// 将{ } 插入 { } 中
languages.insert("serialOne", language1);
languages.insert("serialTwo", language2);
// 定义根节点 也即是最外层 { }
QJsonObject rootObject;
// 插入元素
rootObject.insert("name", "老王");
rootObject.insert("age", 26);
rootObject.insert("interest", interestObj);
rootObject.insert("color", colorArray);
rootObject.insert("like", likeArray);
rootObject.insert("languages", languages);
rootObject.insert("vip", true);
rootObject.insert("address", QJsonValue::Null);
// 将json对象里的数据转换为字符串
QJsonDocument doc;
// 将object设置为本文档的主要对象
doc.setObject(rootObject);
// Json字符串保存到json文件里
QFile file("../Json/js.json");
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
qDebug() << "can't open error!";
return;
}
QTextStream stream(&file);
stream.setCodec("UTF-8"); // 设置写入编码是UTF8
// 写入文件
stream << doc.toJson();
file.close();
}
// 解析Json
void analysisJson() {
QFile file("../Json/js.json");
if (!file.open(QFile::ReadOnly | QFile::Text)) {
qDebug() << "can't open error!";
return;
}
// 读取文件的全部内容
QTextStream stream(&file);
stream.setCodec("UTF-8"); // 设置读取编码是UTF8
QString str = stream.readAll();
file.close();
/* 解析Json */
// QJsonParseError类用于在JSON解析期间报告错误。
QJsonParseError jsonError;
// 将json解析为UTF-8编码的json文档,并从中创建一个QJsonDocument。
// 如果解析成功,返回QJsonDocument对象,否则返回null
QJsonDocument doc = QJsonDocument::fromJson(str.toUtf8(), &jsonError);
// 判断是否解析失败
if (jsonError.error != QJsonParseError::NoError && !doc.isNull()) {
qDebug() << "Json格式错误!" << jsonError.error;
return;
}
// 获取根 { }
QJsonObject rootObj = doc.object();
// 根据键获取值
QJsonValue nameValue = rootObj.value("name");
qDebug() << "name = " << nameValue.toString();
QJsonValue ageValue = rootObj.value("age");
qDebug() << "age = " << ageValue.toInt();
// 解析对象 { }
QJsonValue interestValue = rootObj.value("interest");
// 判断是否是object类型
if (interestValue.type() == QJsonValue::Object) {
// 转换为QJsonObject类型
QJsonObject interestObj = interestValue.toObject();
QJsonValue basketballValue = interestObj.value("basketball");
qDebug() << "basketball = " << basketballValue.toString();
QJsonValue badmintonValue = interestObj.value("badminton");
qDebug() << "badminton = " << badmintonValue.toString();
}
// 解析数组 [ ]
QJsonValue colorValue = rootObj.value("color");
// 判断是否是Array类型
if (colorValue.type() == QJsonValue::Array) {
// 转换为QJsonArray类型
QJsonArray colorArray = colorValue.toArray();
for (int i = 0; i < colorArray.size(); i++) {
QJsonValue color = colorArray.at(i);
qDebug() << "color = " << color.toString();
}
}
// 解析数组中的对象 [ { } ]
QJsonValue likeValue = rootObj.value("like");
if (likeValue.type() == QJsonValue::Array) {
QJsonArray likeArray = likeValue.toArray();
for (int i = 0; i < likeArray.count(); i++) {
QJsonValue likeValueChild = likeArray.at(i);
if (likeValueChild.type() == QJsonValue::Object) {
QJsonObject likeObj = likeValueChild.toObject();
QJsonValue gameLikeValue = likeObj.value("game");
qDebug() << "game = " << gameLikeValue.toString();
QJsonValue priceLikeValue = likeObj.value("price");
qDebug() << "price = " << priceLikeValue.toDouble();
}
}
}
// 解析 对象 中 对象 { { } }
QJsonValue languagesValue = rootObj.value("languages");
if (languagesValue.type() == QJsonValue::Object) {
QJsonObject languagesObj = languagesValue.toObject();
QJsonValue serialOneValue = languagesObj.value("serialOne");
if (serialOneValue.type() == QJsonValue::Object) {
QJsonObject serialOneObj = serialOneValue.toObject();
QJsonValue languageValue = serialOneObj.value("language");
qDebug() << "language = " << languageValue.toString();
QJsonValue gradeValue = serialOneObj.value("grade");
qDebug() << "grade = " << gradeValue.toInt();
}
QJsonValue serialTwoValue = languagesObj.value("serialTwo");
if (serialTwoValue.type() == QJsonValue::Object) {
QJsonObject serialTwoObj = serialTwoValue.toObject();
QJsonValue languageValue = serialTwoObj.value("language");
qDebug() << "language = " << languageValue.toString();
QJsonValue gradeValue = serialTwoObj.value("grade");
qDebug() << "grade = " << gradeValue.toInt();
}
}
// 解析 bool类型
QJsonValue vipValue = rootObj.value("vip");
qDebug() << "vip = " << vipValue.toBool();
// 解析 null类型
QJsonValue addressValue = rootObj.value("address");
if (addressValue.type() == QJsonValue::Null) {
qDebug() << "address = " << "null";
}
}
// 修改Json数据
void alterJson() {
/* 修改也就再重写写一遍覆盖掉就行 */
QFile readFile("../Json/js.json");
if (!readFile.open(QFile::ReadOnly | QFile::Truncate)) {
qDebug() << "can't open error!";
return;
}
// 读取文件的全部内容
QTextStream readStream(&readFile);
readStream.setCodec("UTF-8"); // 设置读取编码是UTF8
QString str = readStream.readAll();
readFile.close();
/* 修改Json */
// QJsonParseError类用于在JSON解析期间报告错误。
QJsonParseError jsonError;
// 将json解析为UTF-8编码的json文档,并从中创建一个QJsonDocument。
// 如果解析成功,返回QJsonDocument对象,否则返回null
QJsonDocument doc = QJsonDocument::fromJson(str.toUtf8(), &jsonError);
if (jsonError.error != QJsonParseError::NoError && !doc.isNull()) {
qDebug() << "Json格式错误!" << jsonError.error;
return;
}
// 获取根 { }
QJsonObject rootObj = doc.object();
// 修改name属性
rootObj["name"] = "老李";
rootObj["vip"] = false;
// 修改数组[]中的元素
QJsonValue colorValue = rootObj.value("color");
if (colorValue.type() == QJsonValue::Array) {
QJsonArray colorArray = colorValue.toArray();
// 修改数组中的值
colorArray.replace(0, "blue");
colorArray.replace(1, "green");
// 赋值覆盖原有数组属性
rootObj["color"] = colorArray;
}
// 修改 { } 中的值
QJsonValue interestValue = rootObj.value("interest");
if (interestValue.type() == QJsonValue::Object) {
QJsonObject interestObject = interestValue.toObject();
interestObject["badminton"] = "乒乓球";
interestObject["basketball"] = "足球";
rootObj["interest"] = interestObject;
}
// 修改 { { } } 中的值
QJsonValue languagesValue = rootObj.value("languages");
if (languagesValue.type() == QJsonValue::Object) {
QJsonObject languagesObj = languagesValue.toObject();
// 找到内部第一个 { }
QJsonValue serialOneValue = languagesObj.value("serialOne");
if (serialOneValue.type() == QJsonValue::Object) {
QJsonObject serialOneObj = serialOneValue.toObject();
serialOneObj["grade"] = "20";
languagesObj["serialOne"] = serialOneObj;
}
// 找到内部第二个 { }
QJsonValue serialTwoValue = languagesObj.value("serialTwo");
if (serialTwoValue.type() == QJsonValue::Object) {
QJsonObject serialTwoObj = serialTwoValue.toObject();
serialTwoObj["grade"] = "10";
serialTwoObj["language"] = "粤语";
languagesObj["serialTwo"] = serialTwoObj;
}
rootObj["languages"] = languagesObj;
}
// 修改 [ { } ]
QJsonValue likeValue = rootObj.value("like");
if (likeValue.type() == QJsonValue::Array) {
QJsonArray likeArray = likeValue.toArray();
// 根据索引获得对应{ }
QJsonObject obj1 = likeArray[0].toObject();
obj1["game"] = "欢乐斗地主";
obj1["price"] = 88.8;
QJsonObject obj2 = likeArray[1].toObject();
obj2["game"] = "欢乐斗牛";
obj2["price"] = 77.7;
// 替换覆盖
likeArray.replace(0, obj1);
likeArray.replace(1, obj2);
rootObj["like"] = likeArray;
}
// 将object设置为本文档的主要对象
doc.setObject(rootObj);
// 重写打开文件,覆盖原有文件,达到删除文件全部内容的效果
QFile writeFile("../Json/js.json");
if (!writeFile.open(QFile::WriteOnly | QFile::Truncate)) {
qDebug() << "can't open error!";
return;
}
// 将修改后的内容写入文件
QTextStream wirteStream(&writeFile);
wirteStream.setCodec("UTF-8"); // 设置读取编码是UTF8
wirteStream << doc.toJson(); // 写入文件
writeFile.close(); // 关闭文件
}
// 删除Json
void delJson() {
QFile readFile("../Json/js.json");
if (!readFile.open(QFile::ReadOnly | QFile::Truncate)) {
qDebug() << "can't open error!";
return;
}
// 读取文件的全部内容
QTextStream readStream(&readFile);
readStream.setCodec("UTF-8"); // 设置读取编码是UTF8
QString str = readStream.readAll();
readFile.close();
/* 修改Json */
// QJsonParseError类用于在JSON解析期间报告错误。
QJsonParseError jsonError;
// 将json解析为UTF-8编码的json文档,并从中创建一个QJsonDocument。
// 如果解析成功,返回QJsonDocument对象,否则返回null
QJsonDocument doc = QJsonDocument::fromJson(str.toUtf8(), &jsonError);
if (jsonError.error != QJsonParseError::NoError && !doc.isNull()) {
qDebug() << "Json格式错误!" << jsonError.error;
return;
}
// 获取根 { }
QJsonObject rootObj = doc.object();
// 删除age
rootObj.remove("age");
// 删除数组[]中的元素
QJsonValue colorValue = rootObj.value("color");
if (colorValue.type() == QJsonValue::Array) {
QJsonArray colorArray = colorValue.toArray();
// 删除数组中索引为1的值
colorArray.removeAt(1);
// 赋值覆盖原有数组属性
rootObj["color"] = colorArray;
}
// 删除 { } 中的值
QJsonValue interestValue = rootObj.value("interest");
if (interestValue.type() == QJsonValue::Object) {
QJsonObject interestObject = interestValue.toObject();
// 删除键为basketball的属性元素
interestObject.remove("basketball");
rootObj["interest"] = interestObject;
}
// 删除 { { } } 中的值
QJsonValue languagesValue = rootObj.value("languages");
if (languagesValue.type() == QJsonValue::Object) {
QJsonObject languagesObj = languagesValue.toObject();
// 删除键为serialTwo的对象 { }
languagesObj.remove("serialTwo");
rootObj["languages"] = languagesObj;
}
// 删除 [ ] 中的 { }
QJsonValue likeValue = rootObj.value("like");
if (likeValue.type() == QJsonValue::Array) {
QJsonArray likeArray = likeValue.toArray();
// 删除索引为1数组中的值
likeArray.removeAt(1);
rootObj["like"] = likeArray;
}
// 删除 [ ]
rootObj.remove("color");
// 删除 { }
rootObj.remove("interest");
// 将object设置为本文档的主要对象
doc.setObject(rootObj);
// 重写打开文件,覆盖原有文件,达到删除文件全部内容的效果
QFile writeFile("../Json/js.json");
if (!writeFile.open(QFile::WriteOnly | QFile::Truncate)) {
qDebug() << "can't open error!";
return;
}
// 将修改后的内容写入文件
QTextStream wirteStream(&writeFile);
wirteStream.setCodec("UTF-8"); // 设置读取编码是UTF8
wirteStream << doc.toJson(); // 写入文件
writeFile.close(); // 关闭文件
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
createJson();
analysisJson();
alterJson();
delJson();
return a.exec();
}
可能讲的不是很清楚,很多细节没有详细的描述。但是该有的操作都已经用代码操作出来了,可以根据自己的项目需求进行截取观看理解,不懂的在评论区留言,我再帮你解答吧,我尽力了!
另外,真的,真的,真的需要注意编码统一的问题,我在写解析时,就是没有考虑到编码问题,导致我找中文乱码问题找了两天,最后还是请教网上的大佬才解决,太郁闷了!(记得写入文件是什么格式,读取出来就得是什么格式,还有,由于我在代码开头就指定了编码是UTF-8,所以我写入文件和读取文件,都是指定了UTF-8格式,这样才不会出现中文乱码的情况!)
原文链接:https://blog.csdn.net/qq_41632571/article/details/131847372
Qt的配置类QSettings主要是键值结构的配置,若需要的配置项为树形结构,例如配置学校\学院\班级\学生这样,使用键值结构已经不满足我们的需求了,我们可以使用xml文件或json文件实现树形结构的配置。本文实现自定义的json文件配置类,实现快速的对json文件的增删改查。
本代码示例对学院\班级\课程的配置,配置的结构有变化可自行修改代码,对json文件的增删改查结构可以通用。
jsonConfig.h
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
#include
//班级
struct mClass{
QString ClassName = ""; //班级名
QVector<QString> CourseName ={}; //课程列表
};
//学院
struct mFaculty {
QString FacultyName = ""; //学院名
QVector<mClass> Class = {}; //班级列表
};
class jsonConfig : public QObject
{
Q_OBJECT
public:
~jsonConfig();
jsonConfig& operator = (const jsonConfig&) = delete;
static jsonConfig& getInstance(void);
QJsonObject mStruct2JsonObject(mFaculty);
mFaculty jsonObject2MStruct(QJsonObject);
bool find(QString name, mFaculty* out_mStruct = NULL);
void add(mFaculty);
void modify(mFaculty);
void remove(QString facultyName);
QVector<mFaculty> readAll();
private:
jsonConfig();
static jsonConfig* instance;
QFile *jsonFile;
};
jsonConfig.cpp
#include "jsonConfig.h"
jsonConfig* jsonConfig::instance = NULL;
jsonConfig::jsonConfig()
{
QDir* dir = new QDir();
if (!dir->exists("./config"))
dir->mkpath("./config");
jsonFile = new QFile("./config/jsonConfigFile.json");
if (!jsonFile->exists()) {
if (jsonFile->open(QFile::WriteOnly)) {
QJsonObject obj;
QJsonArray arr;
obj.insert("Faculty", arr);
QJsonDocument doc(obj);
QByteArray data = doc.toJson();
jsonFile->write(data);
jsonFile->close();
}
}
}
jsonConfig::~jsonConfig()
{}
jsonConfig& jsonConfig::getInstance(void)
{
if (instance == NULL)
instance = new jsonConfig();
return *instance;
}
bool jsonConfig::find(QString name, mFaculty* out_mStruct)
{
if (!jsonFile->open(QIODevice::ReadOnly))
return false;
QByteArray data = jsonFile->readAll();
jsonFile->close();
QJsonParseError parseError;
QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
if (parseError.error != QJsonParseError::NoError) {
return false;
}
QJsonObject rootObj = doc.object();
if (rootObj.contains("Faculty")) {
if (rootObj.value("Faculty").type() == QJsonValue::Array) {
QJsonArray sceneArray = rootObj.value("Faculty").toArray();
for (int i = 0; i < sceneArray.size(); i++) {
if (sceneArray.at(i).type() == QJsonValue::Object) {
QJsonObject obj = sceneArray.at(i).toObject();
if (obj.value("facultyName").toString() == name) {
*out_mStruct = jsonObject2MStruct(obj);
return true;
}
}
}
}
}
return false;
}
QJsonObject jsonConfig::mStruct2JsonObject(mFaculty faculty)
{
QJsonObject obj;
obj.insert("facultyName", faculty.FacultyName);
QJsonArray classArray;
for (int i = 0; i < faculty.Class.size(); i++){
QJsonObject classObj;
classObj.insert("className", faculty.Class.at(i).ClassName);
QJsonArray courseArray;
for(QString course : faculty.Class.at(i).CourseName){
if(!course.isEmpty())
courseArray.append(course);
}
classObj.insert("classCourses",courseArray);
classArray.append(classObj);
}
obj.insert("class", classArray);
return obj;
}
mFaculty jsonConfig::jsonObject2MStruct(QJsonObject jsonObject)
{
mFaculty faculty;
if (jsonObject.value("facultyName").type() == QJsonValue::String)
faculty.FacultyName = jsonObject.value("facultyName").toString();
if (jsonObject.value("class").type() == QJsonValue::Array) {
QJsonArray classArray = jsonObject.value("class").toArray();
for (int i = 0; i < classArray.size(); i++) {
mClass Class;
QJsonObject classObj = classArray.at(i).toObject();
if(classObj.value("className").type() == QJsonValue::String)
Class.ClassName = classObj.value("className").toString();
if(classObj.value("classCourses").type() == QJsonValue::Array){
QJsonArray courseArray = classObj.value("classCourses").toArray();
for (int j = 0; j < courseArray.size(); j++) {
if(!courseArray.at(j).toString().isEmpty())
Class.CourseName.append(courseArray.at(j).toString());
}
}
faculty.Class.append(Class);
}
}
return faculty;
}
void jsonConfig::add(mFaculty faculty)
{
QJsonObject addObj = mStruct2JsonObject(faculty);
if (!jsonFile->open(QIODevice::ReadOnly))
return;
QByteArray data = jsonFile->readAll();
jsonFile->close();
QJsonParseError parseError;
QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
if (parseError.error != QJsonParseError::NoError) {
return;
}
QJsonObject rootObj = doc.object();
if (rootObj.contains("Faculty")) {
if (rootObj.value("Faculty").type() == QJsonValue::Array) {
QJsonArray sceneArray = rootObj.value("Faculty").toArray();
sceneArray.append(addObj);
rootObj["Faculty"] = sceneArray;
}
}
doc.setObject(rootObj);
if (!jsonFile->open(QFile::WriteOnly | QFile::Truncate))
return;
QByteArray writeData = doc.toJson();
jsonFile->write(writeData);
jsonFile->close();
}
void jsonConfig::modify(mFaculty faculty)
{
QJsonObject modifyObj = mStruct2JsonObject(faculty);
if (!jsonFile->open(QIODevice::ReadOnly))
return;
QByteArray data = jsonFile->readAll();
jsonFile->close();
QJsonParseError parseError;
QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
if (parseError.error != QJsonParseError::NoError) {
return;
}
QJsonObject rootObj = doc.object();
if (rootObj.contains("Faculty")) {
if (rootObj.value("Faculty").type() == QJsonValue::Array) {
QJsonArray facultyArray = rootObj.value("Faculty").toArray();
for (int i = 0; i < facultyArray.size(); i++) {
if (facultyArray.at(i).type() == QJsonValue::Object) {
QJsonObject obj = facultyArray.at(i).toObject();
if (obj.value("facultyName").toString() == modifyObj.value("facultyName").toString()) {
facultyArray.removeAt(i);
facultyArray.append(modifyObj);
}
}
}
rootObj["Faculty"] = facultyArray;
}
}
doc.setObject(rootObj);
if (!jsonFile->open(QFile::WriteOnly | QFile::Truncate))
return;
QByteArray writeData = doc.toJson();
jsonFile->write(writeData);
jsonFile->close();
}
void jsonConfig::remove(QString facultyName)
{
if (!jsonFile->open(QIODevice::ReadOnly))
return;
QByteArray data = jsonFile->readAll();
jsonFile->close();
QJsonParseError parseError;
QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
if (parseError.error != QJsonParseError::NoError) {
return;
}
QJsonObject rootObj = doc.object();
if (rootObj.contains("Faculty")) {
if (rootObj.value("Faculty").type() == QJsonValue::Array) {
QJsonArray sceneArray = rootObj.value("Faculty").toArray();
for (int i = 0; i < sceneArray.size(); i++) {
if (sceneArray.at(i).type() == QJsonValue::Object) {
QJsonObject obj = sceneArray.at(i).toObject();
if (obj.value("facultyName").toString() == facultyName)
sceneArray.removeAt(i);
}
}
rootObj["Faculty"] = sceneArray;
}
}
doc.setObject(rootObj);
if (!jsonFile->open(QFile::WriteOnly | QFile::Truncate))
return;
QByteArray writeData = doc.toJson();
jsonFile->write(writeData);
jsonFile->close();
}
QVector<mFaculty> jsonConfig::readAll()
{
QVector<mFaculty> faculty;
if (!jsonFile->open(QIODevice::ReadOnly))
return faculty;
QByteArray data = jsonFile->readAll();
jsonFile->close();
QJsonParseError parseError;
QJsonDocument doc = QJsonDocument::fromJson(data, &parseError);
if (parseError.error != QJsonParseError::NoError) {
return faculty;
}
QJsonObject rootObj = doc.object();
if (rootObj.contains("Faculty")) {
if (rootObj.value("Faculty").type() == QJsonValue::Array) {
QJsonArray facultyArray = rootObj.value("Faculty").toArray();
for (int i = 0; i < facultyArray.size(); i++) {
if (facultyArray.at(i).type() == QJsonValue::Object) {
QJsonObject obj = facultyArray.at(i).toObject();
mFaculty scene = jsonObject2MStruct(obj);
faculty.push_back(scene);
}
}
}
}
return faculty;
}
#include "jsonConfig.h"
int main(int argc, char *argv[])
{
//添加到配置文件
mFaculty faculty;
faculty.FacultyName = "数学学院";
jsonConfig::getInstance().add(faculty);
//从配置文件删除
jsonConfig::getInstance().remove("美术学院");
//查找并修改配置
mFaculty findFaculty;
jsonConfig::getInstance().find("音乐学院",&findFaculty);
for(int i = 0; i <findFaculty.Class.size(); i++){
mClass c = findFaculty.Class.at(i);
if(c.ClassName == "1班"){
if(c.CourseName.contains("高等数学")){
c.CourseName.removeOne(高等数学);//删除课程
findFaculty.Class.remove(i);
findFaculty.Class.append(c);
break;
}
c.CourseName.append("高等数学2"); //添加课程
}
}
jsonConfig::getInstance().modify(findFaculty);//修改配置
//读取json中学院
QVector<mFaculty> facultys = jsonConfig::getInstance().readAll();
}