最近的项目里面要用到将QCustomPlot的数据保存到文件里面,于是我想到了将数据进行序列化和反序列化进行保存。
我做了个小测试
自定义了一个结构体
struct GraphData
{
QString Name;
QString Unit;
std::vector<double> XData;
std::vector<double> YData;
// 序列化运算符
friend QDataStream& operator<<(QDataStream& stream, const GraphData& data)
{
stream << data.Name;
stream << data.Unit;
stream << static_cast<quint32>(data.XData.size()); // 写入 XData 的大小
for (const double& value : data.XData)
{
stream << value; // 依次写入 XData 的元素
}
stream << static_cast<quint32>(data.YData.size()); // 写入 YData 的大小
for (const double& value : data.YData)
{
stream << value; // 依次写入 YData 的元素
}
return stream;
}
// 反序列化运算符
friend QDataStream& operator>>(QDataStream& stream, GraphData& data)
{
stream >> data.Name;
stream >> data.Unit;
quint32 xSize;
stream >> xSize; // 读取 XData 的大小
data.XData.reserve(xSize);
double value;
for (quint32 i = 0; i < xSize; ++i)
{
stream >> value;
data.XData.emplace_back(value);
}
quint32 ySize;
stream >> ySize; // 读取 YData 的大小
data.YData.reserve(ySize);
for (quint32 i = 0; i < ySize; ++i)
{
stream >> value;
data.YData.emplace_back(value);
}
return stream;
}
};
##定义一个结构体,并对其中的两个运算符进行重载。
- 写入数据并序列化后保存到文件里面
void SaveToFile()
{ GraphData data;
data.Name = "发动机转速";
data.Unit = "rpm";
// 创建随机数生成器
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<double> dis(0.0, 1.0);
data.XData.reserve(1000);
data.YData.reserve(10000);
// 填充XData和YData向量
for (int i = 0; i < 1000; ++i) {
double randomValue = dis(gen);
data.XData.emplace_back(randomValue);
randomValue = dis(gen);
data.YData.emplace_back(randomValue);
}
QString fileName = QFileDialog::getSaveFileName(nullptr, tr("Save custom menus to file"), "", "dat (*.data)");
if (!fileName.isEmpty())
{
QFile file(fileName);
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate))//这里务必要一定是二进制形式保存,否则在反序列化读取文件时会导致读出的内容为空
{
QDataStream in(&file);
in.setVersion(QDataStream::Qt_5_0); // 设置数据流版本,版本必须跟反序列化的版本一致
in << data;
file.close();
}
}
}
- 读取文件并赋值在data
void ReadData()
{
GraphData data;
QString fileName = QFileDialog::getOpenFileName(nullptr, tr("load custom from file"), "", "dat (*.data)");
if (!fileName.isEmpty())
{
QFile file(fileName);
if (file.open(QIODevice::ReadOnly))
{
QDataStream in(&file);
in.setVersion(QDataStream::Qt_5_0); // 设置数据流版本
in >> data;
file.close();
}
}
}