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

文章预览:

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

一. Boost库介绍

利用Boost库对视觉任务参数的存读时,有一个缺陷就是如果UI界面新增参数时,在界面初始化的时候会读取不到这个新增的参数,导致原任务设置好的的参数会被清掉进而变成默认参数,需要重新做任务保存参数。这对项目初期开发阶段而言非常不友好,增大调试时间成本。

一般需要增加版本号来解决上述的问题:

namespace boost

{

namespace serialization

{

template

void serialize(Archive & ar, MS_CreateModelSingle_Params & d, const unsigned int version)

{

//VISION_LOG_INFO("%d", version);查看版本号

ar & BOOST_SERIALIZATION_NVP(d.m_isPreventReverse);//是否启用防反

ar & BOOST_SERIALIZATION_NVP(d.m_threshLow); //阈值下限

ar & BOOST_SERIALIZATION_NVP(d.m_threshHigh); //阈值上限

ar & BOOST_SERIALIZATION_NVP(d.m_area); //面积

if(version == 2) //只有 version = 新版本号才读取新参数

{

ar & BOOST_SERIALIZATION_NVP(d.m_areaRatio); //面积占比

}

}

}

}

BOOST_CLASS_VERSION(MS_CreateModelSingle_Params, 2);//当前新版本号,重新保存任务版本号将会更新

这样的话,在初始化的时候就不会读取到新增的参数,也就不会崩溃了。只有在重新保存参数的时候,才会将新增的参数保存到任务文件中。

二. QJson库介绍

本文使用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

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 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::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::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库的方式进行读存,数据类型包括bool、int、double、enum、map等,以及结构体内嵌套子结构体情况下的处理。

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

文章来源

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。