QT通过TCP协议发送结构体数据
QT通过TCP协议发送结构体数据
- Chapter1 QT通过TCP协议发送结构体数据
- 前言
- 1. memcpy方式
- 1.1 发送整个结构体
- 1.2 发送部分数据
- 2. QDataStream
- 2.1 符号<<
- 2.2 wrieteRawData
- 总结
- Chapter2 qt中操作json,读取json,写入json,转换json
- 一、说明
- 二、qt使用json
- 1、读取json文件
- 2、写入json文件
- Chapter3 Qt读写三种文件,QSettings读ini配置文件,QJsonDocument读JSON文件,QDomDocument读xml文件
- 第一种INI配置文件
- 第二种JSON格式配置文件
- Chapter4 在qt中使用json作为配置文件
- 在qt中,使用json作为配置文件
- qt使用json作为配置文件时,怎么通过程序修改json值
- qt使用json作为配置文件时,将程序打包成可执行文件后,json文件会同步到执行文件中吗
- 如何将QString类型的JSON格式数据,转换成QJsonObject类型
- Chapter5 Qt 操作Json格式文件(创建、插入、解析、修改、删除)
- 一、准备工作
- 二、封装Json
- 三、解析Json
- 四、修改Json
- 六、全部代码
- 七、总结
- Chapter6 Qt 之 自定义json配置文件类,QJsonDocument应用
- 一、前言
- 二、头文件代码
- 三、源文件代码
- 四、使用示例
- 五、使用效果
Chapter1 QT通过TCP协议发送结构体数据
原文链接:https://blog.csdn.net/Edwinwzy/article/details/131668533
前言
做上位机的时候下发数据,数据是一个结构体,这里就阐述一下怎么通过TCP协议发送结构体。
我自己写的时候主要通过两种方式,一种是memcpy,另一种是用QDataStream。
先在mainwindow.h头文件中定义结构体:
struct EDWINWZY{char name='A';int age=1;}edwinwzy;
1. memcpy方式
1.1 发送整个结构体
函数原型为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类型的数据。
1.2 发送部分数据
那这是在发送完一整个结构体之后再添加数据,如果我想单独一个一个发结构体的变量呢?
那其实直接用append就可以了。
//定义bit流QByteArray transfer;transfer.append(edwinwzy.name);transfer.append(edwinwzy.age);transfer.append('\n');//发送比特流数据tcpSocket->write(transfer);
有个要注意的是,有时候我最后不加换行符,接收端可能会出现无法显示的情况。这个我只在书中TCPClient项目中出现过,我用串口转网口来接收网口的数据,在串口端接收到的数据都是正常的。
2. QDataStream
这个就类似于C++ 的std::cout了。
不过发送的数据有两种情况。
2.1 符号<<
第一种情况是直接用<<符号进行发送,这种发送会额外发送几个字节数据用来表示我发送的数据所占的字节数。
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码数据,那这个方法就有点问题了。
2.2 wrieteRawData
下面这个写原始数据的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发送结构体数据遇到的问题进行了归纳,发单个以及发部分情况都可以实现。
Chapter2 qt中操作json,读取json,写入json,转换json
原文链接:https://blog.csdn.net/IT_CREATE/article/details/119681949
一、说明
先要明白json是什么,json说白了就是键值对形式的数据格式,key是字符串,值可以是对象、数组、字符串、基础数据类型等,主要用于场景是,前后端数据传输,作为项目配置文件,比如web端比较流行的vue,相比于xml格式的优点是体积更轻,更简洁,单位携带数据更多等特点,现在json格式已经说是应用非常广泛了。json格式的内容中不能出现注释,不然无法解析,相比于xml可以注释,这个也可以说是个遗憾,毕竟json属于轻量级文本,但是我们可以通过一些特殊处理达到注释的要求,这样,对于文本我们也就更容易理解,比如,web前端的webpack在解析配置json文件时就针对注释做了处理。
二、qt使用json
说回正题,qt中我们用qjson来进行解析。首先要使用需要引入相关头文件
#include <qjsondocument.h>
#include <qjsonobject.h>
1、读取json文件
以读取下面这个文件内容为例:
/* 目前只支持 (左斜杠* + *左斜杠) 作为注释,且不能交替,即注释(左斜杠* + *左斜杠)里面不能包含(左斜杠* + *左斜杠)嵌套 */
/* 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 <QDebug>
#include <QFile>
#include <qjsondocument.h>
#include <qjsonobject.h>
#include <qbytearray.h>
#include <qstring.h>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,则默认采用sqlliteif(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; // 设置连接数据库ipUserDefineConstant::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();}}
}
2、写入json文件
以该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对象jsonjsonObject.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()+",失败");}
}
Chapter3 Qt读写三种文件,QSettings读ini配置文件,QJsonDocument读JSON文件,QDomDocument读xml文件
原文链接:https://blog.csdn.net/hw5230/article/details/128649965
第一种INI配置文件
.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<QSettings>#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 <QtCore/QCoreApplication>
#include <QSettings>
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();
}
第二种JSON格式配置文件
{"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 <QString>
#include <QFile>
#include <QIODevice>
#include <QDomNodeList>
#include <QJsonDocument>
#include <QJsonObject>#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;
}
Chapter4 在qt中使用json作为配置文件
原文链接:https://blog.csdn.net/weixin_44050362/article/details/131136264
在qt中,使用json作为配置文件
Qt可以使用JSON作为配置文件。Qt提供了QJsonDocument和QJsonObject等类来处理JSON数据,可以将JSON数据解析为Qt中的对象,也可以将Qt中的对象序列化为JSON数据。
读取了一个名为config.json的JSON文件,解析出其中的name和age字段,并将它们输出到控制台。
#include <QCoreApplication>
#include <QJsonDocument>
#include <QJsonObject>
#include <QFile>
#include <QDebug>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使用json作为配置文件时,怎么通过程序修改json值
在Qt中,我们可以使用QJsonDocument和QJsonObject等类来处理JSON数据,从而实现修改JSON值的功能。
读取了一个名为config.json的JSON文件,解析出其中的name和age字段,并将它们修改为"Tom"和25,最后将修改后的JSON数据重新写入文件。
#include <QCoreApplication>
#include <QJsonDocument>
#include <QJsonObject>
#include <QFile>
#include <QDebug>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配置文件的。如果你希望将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 <QCoreApplication>
#include <QResource>
#include <QDebug>
#include <QTemporaryFile>
#include <QFile>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数据中不存在该项,则返回的值将是一个默认值,例如空字符串或零。
如何将QString类型的JSON格式数据,转换成QJsonObject类型
可以使用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对象。因此,在实际使用中,需要进行错误处理。
Chapter5 Qt 操作Json格式文件(创建、插入、解析、修改、删除)
原文链接: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 >
下图是这篇博客所操作的JSON文件:
二、封装Json
- { }
"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);
- 实例化QJsonDocument对象
// 将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();
这里需要注意的是,我们写入文件时,指定的编码是UTF8,所以在读取出来时也需要使用UTF8编码进行读取!
- 这是补充的内容:[ [ ], [ ] ]
这是2021年11月11日补充的内容。偶然间在csdn问答模块看到有人问这种数组包含数组的Json方式该如何实现,于是我点开自己这一篇博客一看,发现没有记录这种做法,于是乎今天将这种用法补充一下!
在这里创建好的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对象或者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
- 将字符串解析成QJsonDocument对象
// 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();}}}
}
四、修改Json
修改的过程就是:将数据从文件中读取出来,解析成QJsonDocument对象后,在获取跟对象{ },通过跟对象在获取其他的对象{}或者数组[],修改后,再赋值给跟对象{},达到替换效果,也就是修改了,最后再写入文件即可!
-
读取数据解析成QJsonDocument代码省略,跟上面一样
-
获取根节点对象
// 获取根 { }
QJsonObject rootObj = doc.object();
- 修改属性
// 修改name属性
rootObj["name"] = "老李";
rootObj["vip"] = false;
修改前:
修改后:
4. 修改数组 [ ] 中的元素
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;
}
修改前:
修改后:
6. 修改 { { } } 中的值
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");
删除后就没有啦!
- 写入文件
最后,再将跟节点对象{ }重新设置给QJsonDocument对象,在重新写入文件即可!
与上同,这里就不写下代码了!
六、全部代码
我这代码使用VS2017新建一个QT空项目写出来的!
指定编码
#pragma execution_character_set(“utf-8”) // qt支持显示中文
#include <QCoreApplication>#include <QJsonObject> // { }
#include <QJsonArray> // [ ]
#include <QJsonDocument> // 解析Json
#include <QJsonValue> // int float double bool null { } [ ]
#include <QJsonParseError>#include <QDebug>
#include <QFile>
#include <QTextStream>#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"); // 设置读取编码是UTF8QString str = stream.readAll();file.close();/* 解析Json */// QJsonParseError类用于在JSON解析期间报告错误。QJsonParseError jsonError;// 将json解析为UTF-8编码的json文档,并从中创建一个QJsonDocument。// 如果解析成功,返回QJsonDocument对象,否则返回nullQJsonDocument 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"); // 设置读取编码是UTF8QString str = readStream.readAll();readFile.close();/* 修改Json */// QJsonParseError类用于在JSON解析期间报告错误。QJsonParseError jsonError;// 将json解析为UTF-8编码的json文档,并从中创建一个QJsonDocument。// 如果解析成功,返回QJsonDocument对象,否则返回nullQJsonDocument 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"); // 设置读取编码是UTF8wirteStream << 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"); // 设置读取编码是UTF8QString str = readStream.readAll();readFile.close();/* 修改Json */// QJsonParseError类用于在JSON解析期间报告错误。QJsonParseError jsonError;// 将json解析为UTF-8编码的json文档,并从中创建一个QJsonDocument。// 如果解析成功,返回QJsonDocument对象,否则返回nullQJsonDocument doc = QJsonDocument::fromJson(str.toUtf8(), &jsonError);if (jsonError.error != QJsonParseError::NoError && !doc.isNull()) {qDebug() << "Json格式错误!" << jsonError.error;return;}// 获取根 { }QJsonObject rootObj = doc.object();// 删除agerootObj.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"); // 设置读取编码是UTF8wirteStream << 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格式,这样才不会出现中文乱码的情况!)
Chapter6 Qt 之 自定义json配置文件类,QJsonDocument应用
原文链接:https://blog.csdn.net/qq_41632571/article/details/131847372
一、前言
Qt的配置类QSettings主要是键值结构的配置,若需要的配置项为树形结构,例如配置学校\学院\班级\学生这样,使用键值结构已经不满足我们的需求了,我们可以使用xml文件或json文件实现树形结构的配置。本文实现自定义的json文件配置类,实现快速的对json文件的增删改查。
本代码示例对学院\班级\课程的配置,配置的结构有变化可自行修改代码,对json文件的增删改查结构可以通用。
二、头文件代码
jsonConfig.h
#pragma once#include <QObject>
#include <QDir>
#include <QFile>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QTextStream>
#include <QVector>//班级
struct mClass{QString ClassName = ""; //班级名QVector<QString> CourseName ={}; //课程列表
};
//学院
struct mFaculty {QString FacultyName = ""; //学院名QVector<mClass> Class = {}; //班级列表
};class jsonConfig : public QObject
{Q_OBJECTpublic:~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();}
五、使用效果
使用后添加内容后,在文件夹下生成jsonConfigFile.json文件。
相关文章:

QT通过TCP协议发送结构体数据
QT通过TCP协议发送结构体数据 Chapter1 QT通过TCP协议发送结构体数据前言1. memcpy方式1.1 发送整个结构体1.2 发送部分数据 2. QDataStream2.1 符号<<2.2 wrieteRawData 总结 Chapter2 qt中操作json,读取json,写入json,转换json一、说…...
C++标准库之numeric
文章目录 一. numeric库介绍二.详解accumulate1. 计算数组中所有元素的和2. 计算数组中所有元素的乘积3. 计算数组中每个元素乘以3之后的和4.计算数组中每个元素减去3之后的和5.计算班级内学生的平均分6.拼接字符串 adjacent_differenceinner_productpartial_sumiota 三. 参考 …...
第六章:最新版零基础学习 PYTHON 教程—Python 正则表达式(第二节 - Python 中的正则表达式与示例套装)
正则表达式 (RegEx)是一种特殊的字符序列,它使用搜索模式来查找字符串或字符串集。它可以通过将文本与特定模式进行匹配来检测文本是否存在,并且还可以将模式拆分为一个或多个子模式。Python 提供了一个re模块,支持在 Python 中使用正则表达式。它的主要功能是提供搜索,其中…...

【Python】WebUI自动化—Selenium的下载和安装、基本用法、项目实战(16)
文章目录 一.介绍二.下载安装selenium三.安装浏览器驱动四.QuickStart—自动访问百度五.Selenium基本用法1.定位节点1.1.单个元素定位1.2.多个元素定位 2.控制浏览器2.1.设置浏览器窗口大小、位置2.2.浏览器前进、刷新、后退、关闭3.3.等待3.4.Frame3.5.多窗口3.6.元素定位不到…...

c++视觉处理---图像重映射
图像重映射:cv::remap cv::remap 是OpenCV中的一个函数,用于执行图像重映射,允许您通过重新映射像素的位置来变换图像。这个函数非常有用,可以用于各种图像处理任务,如校正畸变、透视变换、几何变换等。 下面是 cv::…...

基于YOLO算法的单目相机2D测量(工件尺寸和物体尺寸)
1.简介 1.1 2D测量技术 基于单目相机的2D测量技术在许多领域中具有重要的背景和意义。 工业制造:在工业制造过程中,精确测量是确保产品质量和一致性的关键。基于单目相机的2D测量技术可以用于检测和测量零件尺寸、位置、形状等参数,进而实…...
Insight h2database 执行计划评估以及 Selectivity
生成执行计划是任何一个数据库不可缺少的过程。通过本文看执行计划生成原理。 最优的执行计划就是寻找最小计算成本的过程。 本文侧重 BTree 索引的成本计算的实现 以及 基础概念选择度的分析。 寻找最优执行计划 找到最佳的索引,实现最少的遍历,得到想要…...

[天翼杯 2021]esay_eval - RCE(disabled_function绕过||AS_Redis绕过)+反序列化(大小写wakeup绕过)
[天翼杯 2021]esay_eval 1 解题流程1.1 分析1.2 解题1.2.1 一阶段1.2.2 二阶段二、思考总结题目代码: <?php class A{public $code = "";...

基于SSM+Vue的在线作业管理系统的设计与实现
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用Vue技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…...

Webapck 解决:[webpack-cli] Error: Cannot find module ‘vue-loader/lib/plugin‘ 的问题
1、问题描述: 其一、报错为: [webpack-cli] Error: Cannot find module vue-loader/lib/plugin 中文为: [webpack-cli] 错误:找不到模块“vue-loader/lib/plugin” 其二、问题描述为: 在项目打包的时候 npm run …...
使用UiPath和AA构建的解决方案 5. 使用UiPath ReFramework处理采购订单
在本章中,我们将使用UiPath Robotic Enterprise Framework(简称ReFramework)创建自动化。ReFramework是一个快速构建强大的UiPath自动化的模板。它可以作为所有UiPath项目的起点。 模板可以满足您在任何自动化中的大部分核心需求——在配置文件中读取和存储数据,强大的异常…...
SQL基本语法用例大全
文章目录 SQL语法概述简单查询计算列查询条件查询范围查询使用逻辑运算符过滤数据使用IN操作符过滤数据格式化结果集模糊查询行数据过滤数据排序数据统计分析分组总计简单子查询多行子查询多表链接插入数据更新和删除数据使用视图数据库管理数据表管理 SQL语法概述 SQL(Struct…...

MAX17058_MAX17059 STM32 iic 驱动设计
本文采用资源下载链接,含完整工程代码 MAX17058-MAX17059STM32iic驱动设计内含有代码、详细设计过程文档,实际项目中使用代码,稳定可靠资源-CSDN文库 简介 MAX17058/MAX17059 IC是微小的锂离子(Li )在手持和便携式设备的电池电量计。MAX170…...

大数据笔记-大数据处理流程
大家对大数据处理流程大体上认识差不多,具体做起来可能细节各不相同,一幅简单的大数据处理流程图如下: 1)数据采集:数据采集是大数据处理的第一步。 数据采集面对的数据来源是多种多样的,包括各种传感器、社…...

wps演示时图片任意位置拖动
wps演示时图片任意位置拖动 1.wps11.1版本,其他版本的宏插件可以自己下载。2.先确认自己的wps版本是不是11.13.检查是否有图像工具4.检查文件格式和安全5.开发工具--图像6.选中图像控件,右击选择查看代码,将原有代码删除,将下边代…...

NodeJs中使用JSONP和Cors实现跨域
跨域是为了解决浏览器请求域名,协议,端口不同的接口,相同的接口是不需要实现跨域的。 1.使用JSONP格式实现跨域 实现步骤 动态创建一个script标签 src指向接口的地址 定义一个函数和后端调用的函数名一样 实现代码 -- 在nodejs中使用http内…...

Typora for Mac:优雅的Markdown文本编辑器,提升你的写作体验
Typora是一款强大的Markdown文本编辑器,专为Mac用户设计。无论你是写作爱好者,还是专业作家或博客作者,Typora都能为你提供无与伦比的写作体验。 1. 直观的界面设计 Typora的界面简洁明了,让你专注于写作,而不是被复…...

STM32使用HAL库驱动TA6932数码管驱动芯片
TA6932介绍 8段16位,支持共阴共阳LED数码管。 2、STM32CUBEMX配置引脚 推挽配置即可。 3、头文件 /******************************************************************************************** * TA6932:8段16位数码管驱动 *******************…...

day25--JS进阶(递归函数,深浅拷贝,异常处理,改变this指向,防抖及节流)
目录 浅拷贝 1.拷贝对象①Object.assgin() ②展开运算符newObj {...obj}拷贝对象 2.拷贝数组 ①Array.prototype.concat() ② newArr [...arr] 深拷贝 1.通过递归实现深拷贝 2.lodash/cloneDeep实现 3.通过JSON.stringify()实现 异常处理 throw抛异常 try/catch捕获…...

Python爬虫(二十三)_selenium案例:动态模拟页面点击
本篇主要介绍使用selenium模拟点击下一页,更多内容请参考:Python学习指南 #-*- coding:utf-8 -*-import unittest from selenium import webdriver from selenium.webdriver.common.keys import Keys from bs4 import BeautifulSoup import timeclass douyuSelenium…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...

3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...