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();
		});
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值