Qt自定义序列化

本文介绍了如何在Qt中使用QDataStream类进行自定义序列化,特别是针对包含复杂数据结构如QMap的情况。通过重载结构体的序列化和反序列化函数,确保序列化顺序与反序列化一致,并在序列化QMap时添加附加信息记录其元素数量,以实现正确地读写二进制数据。
摘要由CSDN通过智能技术生成

本文转载自http://c.360webcache.com/c?m=50ecbbdfdc5c3633e26b54f264753e3c&q=QMap%E5%BA%8F%E5%88%97%E5%8C%96&u=https%3A%2F%2Fwww.cnblogs.com%2Fkanyun%2Fp%2F13093662.html

QDateStream类

在Qt中,提供了QDataStream类为我们的程序提供了读写二进制数据的能力。
QDataStream类实现了序列化C++的基本数据类型的功能,比如char,short,int,char* 等等,不但如此还可以直接序列化 QMap ,QList之类的容器(需要保证容器内的元素是基本类型元素)。但是往往程序中包含了复杂的数据结构,此时就不能直接进行序列化了。因此我们需要将复杂数据类型分解成独立的基本数据类型分别进行序列化。

示例

typedef struct ProjectInfo {
   
	QString projectName;
	QString imgPath;
	QString annotationMeta;
	QString createTime;
	int currentImgIndex;
	QMap<QString,QList<RectMeta>> markCollection;
} Project;
Q_DECLARE_METATYPE(ProjectInfo);
typedef struct RectMetaInfo{
   
	QString text;
	qreal x;
	qreal y;
	qreal w;
	qreal h;
} RectMeta;
Q_DECLARE_METATYPE(RectMetaInfo);

上述代码包含了两个结构体,

其中一个结构体RectMetaInfo中,全部都是基本类型,

而另外一个结构体ProjectInfo,则包含了基本类型和复杂的容器类型

此时我如果直接序列化结构体ProjectInfo,显然是行不通的,因此我们需要逐步分解序列化。

首先结构体ProjectInfo包含了结构体RectMetaInfo,那么先序列化RectMetaInfo

由于RectMetaInfo中都是基本类型,所以序列化比较简单。需要注意的是序列化的顺序要和反序列化的数据的顺序保持一致

//重载序列化
inline QDataStream &operator<<(QDataStream &output , const RectMetaInfo &metaInfo)
{
   
output << metaInfo.text << metaInfo.x << metaInfo.y << metaInfo.w << metaInfo.h;
return output;
}
//重载反序列化
inline QDataStream &operator>>(QDataStream &input , RectMetaInfo &metaInfo)
{
   
input >> metaInfo.text >> metaInfo.x >> metaInfo.y >> metaInfo.w >> metaInfo.h;
return input;
}

重载了结构体RectMetaInfo的序列化和反序列化,接下来就要重载结构体ProjectInfo。

由于ProjectInfo包含了QMap容器元素,因此我们需要一个将QMap的元素个数保存起来(添加附加信息)

//重载序列化
inline QDataStream &operator<<(QDataStream &output , const ProjectInfo &pj)
{
   
output << pj.projectName << pj.imgPath << pj.annotationMeta << pj.createTime << pj.currentImgIndex;
// 附加信息 QMap<int,int> 可以直接被序列化(QMap能否被直接序列化,要看QMap中的类型是否是基本类型,如果是,就可以直接序列化),第一个参数表示第几个key,第二个参数表示该key下存放的数据的数量
QMap<int,int> collectionPreview;
int k_index = 0;
foreach(QString key,pj.markCollection.keys()){
   
collectionPreview[k_index] = pj.markCollection[key].size();
k_index++;
}
// 序列化QMap时需要注意,头文件中需要引入 QDataStream 依赖,否则此处报错
output << collectionPreview;
foreach(QString key,pj.markCollection.keys()){
   
output << key;
QList<RectMetaInfo> rectMetas = pj.markCollection[key];
if (rectMetas.size() == 0) continue;
for(RectMetaInfo rectMetaInfo : rectMetas){
   
output << rectMetaInfo;
};
}
return output ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qfl_sdu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值