[Qt5] QJson库进行存储、加载数据

  • 📢博客主页:https://loewen.blog.csdn.net
  • 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
  • 📢本文由 丶布布原创,首发于 CSDN,转载注明出处🙉
  • 📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨

文章预览:

      • 一. QJson库介绍
      • 二. QJson库生成与解析结构体数据
      • 三. QJson库读、存数据的完整代码操作
      • 四. 总结


一. QJson库介绍

利用Boost库作为视觉任务参数的存读时,有一个缺陷就是新增参数进行保存时,会清除掉之前的任务,导致需要重新做视觉任务才使该参数生效,这对项目初期开发阶段而言非常不友好,增大调试时间成本。

所以本文使用QJson库来作为参数的保存与读取,解决上述Boost库存在的缺陷。

JSON(JavaScript对象表示法)是一种轻量级的数据交换格式。它可以表示整数,实数,字符串,值的有序序列以及名称/值对的集合。

关于Qt中对JSON的生成与解析,Qt5以前的版本,可以使用QJson库,需要单独下载、编译,才能使用。到了 Qt5,提供了专门的QJsonDocument及其相关类来读和写JSON文档。

Json类介绍
QJsonDoucument它封装了一个完整的 JSON 文档,并且可以从 UTF-8 编码的基于文本的表示以及 Qt 自己的二进制格式读取和写入该文档
QJsonArrayJSON 数组是一个值列表。可以通过从数组中插入和删除 QJsonValue 来操作该列表
QJsonObjectJSON 对象是键值对的列表,其中键是唯一的字符串,值由 QJsonValue 表示
QJsonValue该类封装了 JSON 支持的数据类型

二. QJson库生成与解析结构体数据

安装环境:本文使用的Qt版本—Qt5.12.10

1、包含头文件:

#include <QJsonDocument>

2、将结构体中的数据序列化成本地Json数据(toJson — 生成数据),

struct MS_EdgeLineFitParam
{
    //初始化结构体内数据
	MS_EdgeLineFitParam()
	{
		m_isAssignCenterEdge = false;
		m_measureWidth = 5;
		m_measureHeight = 0.0;
	}
	bool   m_isAssignCenterEdge;     
	int    m_measureWidth;           
	double m_measureHeight;   
	
	//将结构体中的数据序列化成本地`Json`数据
	QJsonValue toJson()
	{
	    // 定义 { } 对象	
		QJsonObject jObj;	
		// 插入元素,对应键值对
		jObj.insert("m_isAssignCenterEdge", m_isAssignCenterEdge);
		jObj.insert("m_measureWidth", m_measureWidth);
		jObj.insert("m_measureHeight", m_measureHeight);	
		return QJsonValue(jObj);
	}       
};

3、将本地Json数据进行反序列化成结构体中的数据(fromJson — 解析数据),

struct MS_EdgeLineFitParam
{
   //初始化结构体内数据
	MS_EdgeLineFitParam()
	{
		m_isAssignCenterEdge= false;
		m_measureWidth= 5;
		m_dMeasureHeight = 0.0;
	}
	bool   m_isAssignCenterEdge;     
	int    m_measureWidth;           
	double m_measureHeight;   
	
	//将本地`Json`数据进行反序列化成结构体中的数据
	static MS_EdgeLineFitParam fromJson(QJsonValue _json)
	{
		MS_EdgeLineFitParam task;
		//定义空对象
		QJsonObject jObj = _json.toObject();
		//将Json类型数据进行反序列化
		task.m_isAssignCenterEdge= jObj.value("m_isAssignCenterEdge").toBool();
		task.m_measureWidth= jObj.value("m_measureWidth").toInt();
		task.m_measureHeight= jObj.value("m_measureHeight").toDouble();		
		return task;
	}     
};

三. QJson库读、存数据的完整代码操作

1、结构体数据类型的序列化与反序列化

enum ME_EdgeLineFitShape
{
	EDGELINE_LINE = 0,
};
struct MS_IntersectionParam
{
	MS_IntersectionParam()
	{
		m_intersectionEdgeOne = 0;
	}
	int m_intersectionEdgeOne;

	static MS_IntersectionParam fromJson(QJsonValue _json)
	{
		MS_IntersectionParam task;
		QJsonObject jObj = _json.toObject();
		task.m_intersectionEdgeOne = jObj.value("m_intersectionEdgeOne").toInt();
		return task;
	}
	QJsonValue toJson()
	{
		QJsonObject jObj;
		jObj.insert("m_intersectionEdgeOne", m_intersectionEdgeOne);
		return QJsonValue(jObj);
	}
};
struct MS_EdgeLineFitParam
{
   //初始化结构体内数据
	MS_EdgeLineFitParam()
	{
		m_isAssignCenterEdge= false;
		m_measureWidth= 5;
		m_dMeasureHeight = 0.0;
	}
	bool   m_isAssignCenterEdge;     
	int    m_measureWidth;           
	double m_measureHeight; 
	ME_EdgeLineFitShape  m_edgeLineFitShape;  //自定义的枚举   ME_EdgeLineFitShape  
	MS_IntersectionParam m_intersectionParam; //自定义的结构体 MS_IntersectionParam 
   
   	static MS_EdgeLineFitParam fromJson(QJsonValue _json)
	{
		MS_EdgeLineFitParam task;
		QJsonObject jObj = _json.toObject();
		task.m_isAssignCenterEdge = jObj.value("m_isAssignCenterEdge").toBool();
		task.m_measureWidth = jObj.value("m_measureWidth").toInt();
		task.m_measureHeight = jObj.value("m_measureHeight").toDouble();
		//fromJson中自定义的枚举的写法
		task.m_edgeLineFitShape = (ME_EdgeLineFitShape)jObj.value("m_edgeLineFitShape").toInt();
		//fromJson中自定义结构体的写法
		task.m_intersectionParam = MS_IntersectionParam::fromJson(jObj.value("m_intersectionParam"));		
		return task;
	}
	QJsonValue toJson()
	{
		QJsonObject jObj;
		jObj.insert("m_isAssignCenterEdge", m_isAssignCenterEdge);
		jObj.insert("m_measureWidth", m_measureWidth);
		jObj.insert("m_measureHeight", m_measureHeight);
		//toJson中自定义的枚举的写法和常规写法一致
		jObj.insert("m_edgeLineFitShape", m_edgeLineFitShape);
		//toJson中自定义结构体的写法
		jObj.insert("m_intersectionParam", m_intersectionParam.toJson());	
		return QJsonValue(jObj);
	}

};
struct VISIONLIBRARY_API MS_EdgeLineFit
{
    //输出结构体包含的数据类型map,bool
    std::map<int, MS_EdgeLineFitParam>  m_edgeLineFitParam;
    bool m_isAffineContour = true;
    
    //解析、读取保存到的本地数据
    static MS_EdgeLineFit fromJson(QJsonValue _json)
	{
		MS_EdgeLineFit task;
		QJsonObject jObj = _json.toObject();
		task.m_name = QString(jObj.value("m_name").toString().toLocal8Bit());
        //fromJson中自定义map的写法
		QJsonArray edgeLineFitParam = jObj.value("m_edgeLineFitParam").toArray();
		for (auto value : edgeLineFitParam)
		{
			QJsonArray jArr = value.toArray();
			int num = jArr[0].toInt();
			MS_EdgeLineFitParam fitParam = MS_EdgeLineFitParam::fromJson(jArr[1]);
			task.m_edgeLineFitParam.insert(std::map<int, MS_EdgeLineFitParam>::value_type(num, fitParam));
		}
		task.m_isAffineContour = jObj.value("m_isAffineContour").toBool();
		return task;
	}
	
	//结构体数据通过toJson转换保存本地
	QJsonValue toJson()
	{
		QJsonObject jObj;
		jObj.insert("task_name", m_name);
		
		std::map<int, MS_EdgeLineFitParam>::iterator fitParamIter;
		QJsonArray fitParamJArr;
		for (fitParamIter = m_edgeLineFitParam.begin(); fitParamIter != m_edgeLineFitParam.end(); fitParamIter++)
		{
			QJsonArray jArr;
			jArr.append(fitParamIter->first);
			jArr.append(fitParamIter->second.toJson());
			fitParamJArr.append(jArr);
		}
		jObj.insert("m_edgeLineFitParam", fitParamJArr);
		jObj.insert("m_isAffineContour", m_isAffineContour);
		return QJsonValue(jObj);
	}
};
Q_DECLARE_METATYPE(MS_EdgeLineFit)

2、读、存QJson生成的.json文件

MS_EdgeLineFit::MS_EdgeLineFit(const QString& _name)
{	
	m_name = _name;
	m_edgeLineFitPath = "./VisionFiles/EdgeLineFit/" + m_name + "/";
	read();
}
bool MS_EdgeLineFit::read()
{
	QDir traDir(m_edgeLineFitPath);
	if (!traDir.exists()) {
		ERROR_VISION("read attachData faild due to no such directory!");
		return true;
	}
	QString fileName = QString(m_edgeLineFitPath + "attachData.json").toStdString().c_str();
	INFO_VISION("read attachData taskPath, %s", fileName.toStdString().c_str());

	QFileInfo cfg_json(fileName);
	if (!cfg_json.exists())
	{
		INFO_VISION("read attachData faild due to no such file!");
		return false;
	}

	QFile file_json(fileName);
	if (!(file_json.open(QIODevice::ReadOnly | QIODevice::Text)))
	{
		INFO_VISION("read attachData faild due to file cannot be opened!");
		return false;
	}

	QByteArray cfgContent = file_json.readAll();
	file_json.close();
	QJsonParseError jsonError;
	QJsonDocument jsonDoc = QJsonDocument::fromJson(cfgContent, &jsonError);
	if (!jsonDoc.isNull() && (jsonError.error == QJsonParseError::NoError) && jsonDoc.isObject())
	{		
		INFO_VISION("read attachData success, %s", fileName.toStdString().c_str());
		QJsonObject jObj = jsonDoc.object();
		MS_EdgeLineFit task = MS_EdgeLineFit::fromJson(jObj.value("Task"));
		m_edgeLineFitParam = task.m_edgeLineFitParam;
		m_isAffineContour = task.m_isAffineContour;
		return true;
	}
	else
	{
		INFO_VISION("read attachData faild due to attachData exception!");
		return false;
	}
}
bool MS_EdgeLineFit::write()
{
	writeGraphic();
	QString fileName = QString(m_edgeLineFitPath + "attachData.json").toStdString().c_str();
	INFO_VISION("write attachData taskPath, %s", fileName.toStdString().c_str());

	QJsonDocument doc;
	QJsonObject jObj;	 
	MS_EdgeLineFit task(m_name);
	task.m_edgeFitHRegion = m_edgeFitHRegion;
	task.m_isAffineContour = m_isAffineContour;
	jObj.insert("Task", task.toJson());
	doc.setObject(jObj);
	QString jsonText = doc.toJson();
	QFile cfgFile(fileName);
	if (!(cfgFile.open(QIODevice::WriteOnly | QIODevice::Text)))
	{
		ERROR_VISION("Error occured in write attachData fail due to file cannot be opened!");
		return false;
	}
	cfgFile.write(jsonText.toStdString().data());
	cfgFile.close();
	return true;
}

四. 总结

本文主要对结构体中数据类型使用QJson库的方式进行读存,数据类型包括boolintdoubleenummap等,以及结构体内嵌套子结构体情况下的处理。


下雨天,最惬意的事莫过于躺在床上静静听雨,雨中入眠,连梦里也长出青苔。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/19305.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

模糊PID(重心法解模糊梯形图FC)

模糊PID的模糊化请参看下面的博客文章: 博途PLC模糊PID三角隶属度函数指令(含Matlab仿真)_plc 模糊pid_RXXW_Dor的博客-CSDN博客三角隶属度函数FC,我们采用兼容C99标准的函数返回值写法,在FB里调用会更加直观,下面给大家具体讲解代码。常规写法的隶属度函数FC可以参看下…

使用auto-gpt来写一篇技术文章(如何部署autogpt+遇到的问题+如何使用)

文章目录 前言一、autogpt本地部署1.clone代码2.启动虚拟环境3.运行项目 二、使用aotogpt生成文章1.人设描述2.设置目标3.文章的生成过程4.文章的生成内容 总结 前言 最近AI技术的发展非常迅猛&#xff0c;尤其是和GPT相关的技术&#xff0c;备受瞩目。近日&#xff0c;Autogp…

IPv6有哪些优势?

现有的互联网是在IPv4协议的基础上运行的。IPv6是下一版本的互联网协议&#xff0c;也可以说是下一代互联网的协议&#xff0c;它的提出最初是因为随着互联网的迅速发展&#xff0c;IPv4定义的有限地址空间将被耗尽&#xff0c;而地址空间的不足必将妨碍互联网的进一步发展。 为…

视频创作教程-蜜蜂剪辑软件

视频创作教程-蜜蜂剪辑软件 作者介绍 一、视频剪辑软件二、蜜蜂剪辑软件使用1.视频比例选择2.添加视频素材3.视频分割4.添加文字5.转场滤镜6.其它 三、创作实例四、软件分享 作者介绍 熊文博&#xff0c;男&#xff0c;西安工程大学电子信息学院&#xff0c;2020级硕士研究生&…

Vue3 基础语法

文章目录 1.创建Vue项目1.1创建项目1.2 初始项目 2.vue3 语法2.1 复杂写法2.2 简易写法2.3 reactive&#xff08;对象类型&#xff09;2.4 ref&#xff08;简单类型&#xff09;2.5 computed(计算属性)2.6 watch&#xff08;监听&#xff09; 3.vue3 生命周期4.vue3 组件通信4.…

RabbitMQ (HelloWord 消息应答 持久化 不公平分发 预取值)

文章目录 HelloWord工作队列工作线程代码启动两个工作线程工作队列&#xff08;生产者代码&#xff09;工作队列&#xff08;结果成功&#xff09; 消息应答自动应答手动消息应答multiple的解释消息自动重新入队手动应答代码消息手动应答&#xff08;生产者&#xff09;消息手动…

分布式系统概念和设计——命名服务设计和落地经验

分布式系统概念和设计 通过命名服务&#xff0c;客户进程可以根据名字获取资源或对象的地址等属性。 被命名的实体可以是多种类型&#xff0c;并且可由不同的服务管理。 命名服务 命名是一个分布式系统中的非常基础的问题&#xff0c;名字在分布式系统中代表了广泛的资源&#…

企业官方网站怎么申请?

在数字化时代&#xff0c;企业官方网站是展示企业形象、宣传产品和服务的重要窗口。那么&#xff0c;企业官方网站怎么申请呢&#xff1f;下面是一些简单的步骤。 1、选择合适的网站建设平台 目前市面上有许多网站建设平台&#xff0c;企业需要根据自己的需求和预算选择适合自…

公司新来个卷王,让人崩溃...

最近内卷严重&#xff0c;各种跳槽裁员&#xff0c;相信很多小伙伴也在准备今年的面试计划。 在此展示一套学习笔记 / 面试手册&#xff0c;年后跳槽的朋友可以好好刷一刷&#xff0c;还是挺有必要的&#xff0c;它几乎涵盖了所有的软件测试技术栈&#xff0c;非常珍贵&#x…

电力系统储能调峰、调频模型研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

算法修炼之练气篇——练气二十一层

博主&#xff1a;命运之光 专栏&#xff1a;算法修炼之练气篇 前言&#xff1a;每天练习五道题&#xff0c;炼气篇大概会练习200道题左右&#xff0c;题目有C语言网上的题&#xff0c;也有洛谷上面的题&#xff0c;题目简单适合新手入门。&#xff08;代码都是命运之光自己写的…

程序员面试金典16.*

文章目录 16.01 交换数字16.02单词频率16.03交点16.04 井字游戏16.05 阶乘尾数16.06 最小差16.07 最大数值16.08 整数的英文表示16.09 运算16.10 生存人数16.11 跳水板16.13 平分正方形16.14 最佳直线&#xff08;待定&#xff09;16.15珠玑妙算16.16部分排序16.17连续数列16.1…

10:00面试,10:04就出来了 ,问的实在是太...

从外包出来&#xff0c;没想到竟然死在了另一家厂子 自从加入这家公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以我也就忍了。没想到12月一纸通知&#xff0c;所有人都不许加班&#xff0c;薪资直降30%&#xff0c;顿时有吃不起饭的赶脚。 好在有个…

OpenPCDet系列 | 6.PointPillars模型分类、回归、角度损失的构建

文章目录 模型损失计算1. 分类损失构建1.1 分类损失函数&#xff1a;SigmoidFocalClassificationLoss 2. 回归损失构建2.1 回归损失函数&#xff1a;WeightedSmoothL1Loss 3. 角度损失构建3.1 角度损失函数&#xff1a;WeightedCrossEntropyLoss 4. 总结 模型损失计算 在进行a…

如何判断CRM软件的好坏?2023年CRM系统排行榜前三名是什么?

CRM客户管理系统经过20余年的发展&#xff0c;收获了越来越多企业的认可&#xff0c;成为企业数字化转型必不可少的一环。很多企业都有上线CRM软件的计划&#xff0c;但精准的找到一款适合自身的产品十分不易&#xff0c;今天我们就来盘点2023年CRM软件排行榜。 一、CRM的含义…

【跟着陈七一起学C语言】今天总结:初识C语言

友情链接&#xff1a;专栏地址 知识总结顺序参考C Primer Plus&#xff08;第六版&#xff09;和谭浩强老师的C程序设计&#xff08;第五版&#xff09;等&#xff0c;内容以书中为标准&#xff0c;同时参考其它各类书籍以及优质文章&#xff0c;以至减少知识点上的错误&#x…

Speech and Language Processing之word2vec

1、介绍 事实证明&#xff0c;在每一个NLP任务中&#xff0c;密集向量都比稀疏向量工作得更好。虽然我们不能完全理解其中的所有原因&#xff0c;但我们有一些直觉。首先&#xff0c;密集向量可以更成功地作为特征包含在机器学习系统中;例如&#xff0c;如果我们使用100维…

如何高清视频录制?您只需要这样操作!

案例&#xff1a;如何录制画质高清的视频&#xff1f; 【我录制了一个视频课程&#xff0c;上传到网上&#xff0c;但是我录制的视频画质不好&#xff0c;影响观感。有没有支持高清录制的录屏工具&#xff1f;有没有小伙伴可以推荐一下&#xff01;在线等&#xff01;】 无论…

BM61-矩阵最长递增路径

题目 给定一个 n 行 m 列矩阵 matrix &#xff0c;矩阵内所有数均为非负整数。 你需要在矩阵中找到一条最长路径&#xff0c;使这条路径上的元素是递增的。并输出这条最长路径的长度。 这个路径必须满足以下条件&#xff1a; 对于每个单元格&#xff0c;你可以往上&#xff…

数组的应用

数组的应用 一、数组的定义二、切片替换删除数值元素 二、数组追加元素三、数组与函数相结合 一、数组的定义 相当于一串数据的集合&#xff0c;以空格相间隔的字符串列表&#xff0c;两边用括号括起来 echo ${shuzu[]}中的代表着显示所有的下标内容&#xff0c;当然&#…