QT中json与数据转换
一、json简介
json是以键值对形式存储数据信息的文本格式,key是字符串,value可以使基础数据类型、数组、对象等;主要应用于前后端的数据传输、项目配置文件;轻量级的文本格式相比于xml更加简洁,但是缺陷是不能有注释。
二、json文件的写入与解析
1、简单的json对象
需要写入如下的简单的json对象:
{
"Cross Platform": true,
"From": 1991,
"Name": "Qt"
}
写入:
// 构建 JSON 对象
QJsonObject json;
json.insert("Name", "Qt");
json.insert("From", 1991);
json.insert("Cross Platform", true);
// 构建 JSON 文档
QJsonDocument document;
document.setObject(json);
QByteArray byteArray = document.toJson(QJsonDocument::Compact);
QString strJson(byteArray);
qDebug() << strJson;
解析:
QJsonParseError jsonError;
QJsonDocument doucment = QJsonDocument::fromJson(byteArray, &jsonError); // 转化为 JSON 文档
if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) { // 解析未发生错误
if (doucment.isObject()) { // JSON 文档为对象
QJsonObject object = doucment.object(); // 转化为对象
if (object.contains("Name")) { // 包含指定的 key
QJsonValue value = object.value("Name"); // 获取指定 key 对应的 value
if (value.isString()) { // 判断 value 是否为字符串
QString strName = value.toString(); // 将 value 转化为字符串
qDebug() << "Name : " << strName;
}
}
if (object.contains("From")) {
QJsonValue value = object.value("From");
if (value.isDouble()) {
int nFrom = value.toVariant().toInt();
qDebug() << "From : " << nFrom;
}
}
if (object.contains("Cross Platform")) {
QJsonValue value = object.value("Cross Platform");
if (value.isBool()) {
bool bCrossPlatform = value.toBool();
qDebug() << "CrossPlatform : " << bCrossPlatform;
}
}
}
}
2、json数组
构建如下数组:
[
"Qt",
5.7,
true
]
写入:
// 构建 JSON 数组
QJsonArray json;
json.append("Qt");
json.append(5.7);
json.append(true);
// 构建 JSON 文档
QJsonDocument document;
document.setArray(json);
QByteArray byteArray = document.toJson(QJsonDocument::Compact);
QString strJson(byteArray);
qDebug() << strJson;
解析:
QJsonParseError jsonError;
QJsonDocument doucment = QJsonDocument::fromJson(byteArray, &jsonError); // 转化为 JSON 文档
if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) { // 解析未发生错误
if (doucment.isArray()) { // JSON 文档为数组
QJsonArray array = doucment.array(); // 转化为数组
int nSize = array.size(); // 获取数组大小
for (int i = 0; i < nSize; ++i) { // 遍历数组
QJsonValue value = array.at(i);
if (value.type() == QJsonValue::String) {
QString strName = value.toString();
qDebug() << strName;
}
if (value.type() == QJsonValue::Double) {
double dVersion = value.toDouble();
qDebug() << dVersion;
}
if (value.type() == QJsonValue::Bool) {
bool bCrossPlatform = value.toBool();
qDebug() << bCrossPlatform;
}
}
}
}
3、复杂的json对象
构建如下复杂的数据结构:
{
"Company": "Digia",
"From": 1991,
"Name": "Qt",
"Page": {
"Developers": "https://www.qt.io/developers/",
"Download": "https://www.qt.io/download/",
"Home": "https://www.qt.io/"
},
"Version": [
4.8,
5.2,
5.7
]
}
写入:
// 构建 Json 数组 - Version
QJsonArray versionArray;
versionArray.append(4.8);
versionArray.append(5.2);
versionArray.append(5.7);
// 构建 Json 对象 - Page
QJsonObject pageObject;
pageObject.insert("Home", "https://www.qt.io/");
pageObject.insert("Download", "https://www.qt.io/download/");
pageObject.insert("Developers", "https://www.qt.io/developers/");
// 构建 Json 对象
QJsonObject json;
json.insert("Name", "Qt");
json.insert("Company", "Digia");
json.insert("From", 1991);
json.insert("Version", QJsonValue(versionArray));
json.insert("Page", QJsonValue(pageObject));
// 构建 Json 文档
QJsonDocument document;
document.setObject(json);
QByteArray byteArray = document.toJson(QJsonDocument::Compact);
QString strJson(byteArray);
qDebug() << strJson;
解析:
QJsonParseError jsonError;
QJsonDocument doucment = QJsonDocument::fromJson(byteArray, &jsonError); // 转化为 JSON 文档
if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) { // 解析未发生错误
if (doucment.isObject()) { // JSON 文档为对象
QJsonObject object = doucment.object(); // 转化为对象
if (object.contains("Name")) {
QJsonValue value = object.value("Name");
if (value.isString()) {
QString strName = value.toString();
qDebug() << "Name : " << strName;
}
}
if (object.contains("Company")) {
QJsonValue value = object.value("Company");
if (value.isString()) {
QString strCompany = value.toString();
qDebug() << "Company : " << strCompany;
}
}
if (object.contains("From")) {
QJsonValue value = object.value("From");
if (value.isDouble()) {
int nFrom = value.toVariant().toInt();
qDebug() << "From : " << nFrom;
}
}
if (object.contains("Version")) {
QJsonValue value = object.value("Version");
if (value.isArray()) { // Version 的 value 是数组
QJsonArray array = value.toArray();
int nSize = array.size();
for (int i = 0; i < nSize; ++i) {
QJsonValue value = array.at(i);
if (value.isDouble()) {
double dVersion = value.toDouble();
qDebug() << "Version : " << dVersion;
}
}
}
}
if (object.contains("Page")) {
QJsonValue value = object.value("Page");
if (value.isObject()) { // Page 的 value 是对象
QJsonObject obj = value.toObject();
if (obj.contains("Home")) {
QJsonValue value = obj.value("Home");
if (value.isString()) {
QString strHome = value.toString();
qDebug() << "Home : " << strHome;
}
}
if (obj.contains("Download")) {
QJsonValue value = obj.value("Download");
if (value.isString()) {
QString strDownload = value.toString();
qDebug() << "Download : " << strDownload;
}
}
if (obj.contains("Developers")) {
QJsonValue value = obj.value("Developers");
if (value.isString()) {
QString strDevelopers = value.toString();
qDebug() << "Developers : " << strDevelopers;
}
}
}
}
}
}
三、QT中配置文件应用json实现
1、需求
工程模块需要实现新建工程、打开工程、保存工程三大功能:
2、打开工程
void MasterWindow::openEnginSlot()
{
QMessageBox* msg = new QMessageBox(QMessageBox::Question, tr("请选择"), tr("是否保存当前工程?"), QMessageBox::Yes | QMessageBox::No);
msg->button(QMessageBox::Yes)->setText("保存");
msg->button(QMessageBox::No)->setText("不保存");
msg->setWindowIcon(QIcon(":Image/winIcon2.ico"));
int ret = msg->exec();
if (ret == QMessageBox::Yes)
{
saveEnginSlot();
}
QFileDialog* fileDialog = new QFileDialog(this);
fileDialog->setWindowTitle(tr("打开工程"));
QIcon icon(QStringLiteral(":/Image/winIcon2.ico"));
fileDialog->setWindowIcon(icon);
fileDialog->setDirectory("/");
fileDialog->setNameFilter(tr("text(*.json)"));
fileDialog->setFileMode(QFileDialog::ExistingFiles);
fileDialog->setViewMode(QFileDialog::Detail);
QStringList fileNames;
if (fileDialog->exec())
{
fileNames = fileDialog->selectedFiles();
}
if (fileNames.length() > 0) {
QString project_path = fileNames[0];
QDir dir(project_path);
if (_projectPath == project_path)
{
return;
}
_projectPath = project_path;
QFile file(_projectPath);
QFileInfo info(file);
QString filenameNoSuff = info.baseName();
ui->labelEngin->setText(filenameNoSuff);
QFile file_r(_projectPath);
if (file_r.open(QIODevice::ReadOnly | QIODevice::Text))
{
QString jsonfile = file_r.readAll();
file_r.close();
QJsonParseError jsonParseError;
QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonfile.toUtf8(), &jsonParseError);
if (!(jsonParseError.error == QJsonParseError::NoError))
{
QMessageBox::about(NULL, "提示", "项目配置文件错误");
return;
}
QJsonObject jsonObj = jsonDoc.object();
_materialPathList.clear();
_playingMaterialPathList.clear();
_playingMaterialInfoList.clear();
for (int i = 0; i < jsonObj["materialNum"].toInt(); i++)
{
_materialPathList.push_front(jsonObj["material" + QString::number(i)].toString());
}
if (jsonObj.contains("playingMaterialPathArray"))
{
QJsonValue value = jsonObj.value("playingMaterialPathArray");
if (value.isArray()) {
QJsonArray array = value.toArray();
int nSize = array.size();
for (int i = 0; i < nSize; ++i) {
QJsonValue value = array.at(i);
if (value.isString()) {
_playingMaterialPathList.push_front(value.toString());
}
}
}
}
if (jsonObj.contains("playingMaterialInfoArray"))
{
QJsonValue value = jsonObj.value("playingMaterialInfoArray");
if (value.isArray()) {
QJsonArray array = value.toArray();
int nSize = array.size();
for (int i = 0; i < nSize; ++i) {
QJsonValue value = array.at(i);
if (value.isObject()) {
QJsonObject jsonObj = value.toObject();
int isize = jsonObj.size();
materialInfo *info = new materialInfo;
for (int i = 0; i < isize; i++)
{
QFileInfo fileInfo(jsonObj["path"].toString());
info->materialName = fileInfo.fileName();
info->path = jsonObj["path"].toString();
info->xPoint = jsonObj["xPoint"].toInt();
info->yPoint = jsonObj["yPoint"].toInt();
info->width = jsonObj["width"].toInt();
info->heigh = jsonObj["heigh"].toInt();
}
_playingMaterialInfoList.push_front(info);
}
}
}
}
emit initPlayList();
emit initMaterialSignal(_materialPathList);
emit initViewFormSignal(_playingMaterialPathList, _playingMaterialInfoList);
}
else {
file_r.close();
}
}
}
3、保存工程
void MasterWindow::saveEnginSlot()
{
//判断_projectPath是否为空,如果为空,说明是读取临时工程。否则读取系统文件中保存的上次打开的工程
if (_projectPath == "") {
EnginSet* enginSet = new EnginSet();
enginSet->setWindowModality(Qt::ApplicationModal);
enginSet->setWindowTitle("项目");
enginSet->setEnginMode("保存工程");
enginSet->setWindowIcon(QIcon(":/Image/winIcon2.ico"));
enginSet->show();
connect(enginSet, &EnginSet::savePathSignal, this, [this](QString path) {
_projectPath = path;
qDebug() << "保存工程的路径生成了" << _projectPath;
QFile file(_projectPath);
QFileInfo info(file);
QString filenameNoSuff = info.baseName();
ui->labelEngin->setText(filenameNoSuff);
//以读写方式打开临时工程文件
if (file.open(QIODevice::ReadWrite))
{
QJsonDocument jsonDoc;
QJsonObject jsonObj;
QJsonArray playingMaterialPathArray;
QJsonArray playingMaterialInfoArray;
QString mat="material";
jsonObj.insert("path", _projectPath);
if (_materialPathList.count() != 0)
{
int i = 0;
for (; i < _materialPathList.count(); i++)
{
jsonObj.insert(mat+QString::number(i), _materialPathList[i]);
}
jsonObj.insert("materialNum",i);
}
if (_playingMaterialPathList.count() != 0)
{
int i = 0;
for (; i < _playingMaterialPathList.count(); i++)
{
playingMaterialPathArray.append(_playingMaterialPathList[i]);
}
jsonObj.insert("playingMaterialPathArray", QJsonValue(playingMaterialPathArray));
}
if (_playingMaterialInfoList.count() != 0)
{
int i = 0;
for (; i < _playingMaterialInfoList.count(); i++)
{
QJsonObject jsonObj1;
jsonObj1.insert("materialName", _playingMaterialInfoList[i]->materialName);
jsonObj1.insert("path", _playingMaterialInfoList[i]->path);
jsonObj1.insert("xPoint", _playingMaterialInfoList[i]->xPoint);
jsonObj1.insert("yPoint", _playingMaterialInfoList[i]->yPoint);
jsonObj1.insert("width", _playingMaterialInfoList[i]->width);
jsonObj1.insert("heigh", _playingMaterialInfoList[i]->heigh);
playingMaterialInfoArray.append(jsonObj1);
}
jsonObj.insert("playingMaterialInfoArray", QJsonValue(playingMaterialInfoArray));
}
jsonDoc.setObject(jsonObj);
file.resize(0);
//写入json文件
file.write(jsonDoc.toJson());
file.close();
qDebug() << _projectPath + "open ok";
}
else {
qDebug() << _projectPath + " open error!";
file.close();
}
QMessageBox::about(NULL, "提示", "项目保存成功");
});
}
else
{
qDebug() << "G_Project_path不为空";
QFile file(_projectPath);
if (file.open(QIODevice::ReadWrite | QIODevice::Text))
{
QJsonDocument jsonDoc;
QJsonObject jsonObj;
QJsonArray playingMaterialPathArray;
QJsonArray playingMaterialInfoArray;
jsonDoc.setObject(jsonObj);
file.resize(0);//清空文件
file.write(jsonDoc.toJson());
file.close();
qDebug() << _projectPath + "open ok";
QString mat = "material";
//改变系统配置json文件的项目路径
QFile sys_file(_projectPath);
sys_file.open(QIODevice::ReadWrite);
QString jsonfile = sys_file.readAll();
QJsonParseError jsonParseError;
QJsonDocument sys_doc = QJsonDocument::fromJson(jsonfile.toUtf8(), &jsonParseError);
if (!(jsonParseError.error == QJsonParseError::NoError))
{
QMessageBox::about(NULL, "提示", "系统配置文件错误");
return;
}
QJsonObject sys_json = sys_doc.object();
sys_json["path"] = _projectPath;
if (_materialPathList.count() != 0)
{
int i = 0;
for (; i < _materialPathList.count(); i++)
{
sys_json.insert(mat + QString::number(i), _materialPathList[i]);
}
sys_json.insert("materialNum", i);
}
if (_playingMaterialPathList.count() != 0)
{
int i = 0;
for (; i < _playingMaterialPathList.count(); i++)
{
playingMaterialPathArray.append(_playingMaterialPathList[i]);
}
sys_json.insert("playingMaterialPathArray", QJsonValue(playingMaterialPathArray));
}
if (_playingMaterialInfoList.count() != 0)
{
int i = 0;
for (; i < _playingMaterialInfoList.count(); i++)
{
QJsonObject jsonObj1;
jsonObj1.insert("materialName", _playingMaterialInfoList[i]->materialName);
jsonObj1.insert("path", _playingMaterialInfoList[i]->path);
jsonObj1.insert("xPoint", _playingMaterialInfoList[i]->xPoint);
jsonObj1.insert("yPoint", _playingMaterialInfoList[i]->yPoint);
jsonObj1.insert("width", _playingMaterialInfoList[i]->width);
jsonObj1.insert("heigh", _playingMaterialInfoList[i]->heigh);
playingMaterialInfoArray.append(jsonObj1);
}
sys_json.insert("playingMaterialInfoArray", QJsonValue(playingMaterialInfoArray));
}
sys_doc.setObject(sys_json);
sys_file.resize(0);//清空文件
sys_file.write(sys_doc.toJson());
sys_file.close();
qDebug() << "系统配置json文件的项目路径更改成功";
}
else
{
file.close();
qDebug() << _projectPath + " open error!";
}
QMessageBox::about(NULL, "提示", "项目保存成功");
}
}
4、新建工程
void MasterWindow::newEnginSlot()
{
QMessageBox* msg = new QMessageBox(QMessageBox::Question, "提示", "是否保存当前工程?", QMessageBox::Yes | QMessageBox::No);
msg->setWindowIcon(QIcon(":Image/winIcon2.ico"));
msg->button(QMessageBox::Yes)->setText("保存");
msg->button(QMessageBox::No)->setText("不保存");
int ret = msg->exec();
if (ret == QMessageBox::Yes)
{
saveEnginSlot();
}
EnginSet* enginSet = new EnginSet();
enginSet->setWindowTitle("项目");
enginSet->setWindowModality(Qt::ApplicationModal);
enginSet->setEnginMode("新建工程");
enginSet->setWindowIcon(QIcon(":/Image/winIcon2.ico"));
enginSet->show();
connect(enginSet, &EnginSet::savePathSignal, this, [this](QString path) {
_projectPath = path;
QFile file(_projectPath);
QFileInfo info(file);
QString filenameNoSuff = info.baseName();
ui->labelEngin->setText(filenameNoSuff);
_materialPathList.clear();
_playingMaterialPathList.clear();
_playingMaterialInfoList.clear();
emit initPlayList();
emit initMaterialSignal(_materialPathList);
emit initViewFormSignal(_playingMaterialPathList, _playingMaterialInfoList);
saveEnginSlot();
});
}