本文转载自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 ;
}