序列化形状以保存和重新绘制
Posted
技术标签:
【中文标题】序列化形状以保存和重新绘制【英文标题】:Serialize shape to save and re-draw 【发布时间】:2017-04-17 18:09:48 【问题描述】:我有一个 QGraphicsScene,我在其中绘制一个 QPainterPath,我需要能够保存形状,并在应用程序再次运行时重新绘制它。下面是我如何绘制形状、简化版本和我的写法。
void drawPath()
QPoint p1 = QPoint(10, 20);
writePointsToFile(p1);
QPoint p2 = QPoint(25, 30);
writePointsToFile(p2);
QPoint p3 = QPoint(40, 60);
writePointsToFile(p3);
QPainterPath path;
path.moveTo(p1.x(), p1.y());
path.lineTo(p2.x(), p2.y());
path.lineTo(p3.x(), p3.y());
void writePointsToFile(QPoint point)
QFile file("../path.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
out << point;
file.close();
目前,我的文件在运行时从未被写入。
但除此之外,序列化这些数据以便我可以重建形状的正确方法是什么?
我以为我能够处理重新绘制,但我对序列化的理解不够好。
我是否对积分进行序列化? 包含点的列表?
我的想法是如果我序列化这些点,当我反序列化时,我将它们添加到一个列表中,我应该能够根据列表中每个点的位置重新创建形状;即位置 0 的点是 p1,点 1 的点是 p2,等等。但我无法做到这一点,因为无论如何都没有将任何内容写入文件。另外,我不完全确定首先对数据序列化有什么期望。
在这方面的任何帮助都会很棒。
编辑:根据反馈,我现在正在我的 write 方法中尝试这样做
QFile file("../path.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
QDataStream & operator << (QDataStream& file, const QPainterPath& path);
out << path;
file.close();
这编译得很好,即使我不完全确定我做对了,没有任何东西被写入文件,所以我假设我还在某个地方。
【问题讨论】:
【参考方案1】:Qt 已经提供了直接序列化和反序列化QPainterPath
所需的运算符:
QDataStream & operator<<(QDataStream & stream, const QPainterPath & path)
QDataStream & operator>>(QDataStream & stream, QPainterPath & path)
所以不需要序列化点,当你可以序列化路径的确切内容时,包括复杂的多组件路径。
所以你应该将路径实现为一个持久的成员变量,这样你就可以从一个文件中读取或写入它,并且在draw方法中你只需绘制路径。
目前,我的文件在运行时从未被写入。
我敢打赌,因为writePointsToFile()
从未被调用过。当您尝试打开文件等时,您可能还会养成检查错误的好习惯。您也没有指定QIODevice::Append
,因此即使您确实写入磁盘,您也只会写入一个点,每次都会覆盖前一个点。
编辑:根据您的编辑,您似乎已经超越了自己,并且在急于使用它之前仍然需要学习基本的 C++。尝试这样的事情,并找出你哪里出错了:
QPoint p1 = QPoint(10, 20);
QPoint p2 = QPoint(25, 30);
QPoint p3 = QPoint(40, 60);
QPainterPath path;
path.moveTo(p1.x(), p1.y());
path.lineTo(p2.x(), p2.y());
path.lineTo(p3.x(), p3.y());
QFile file("../path.dat");
if (!file.open(QIODevice::WriteOnly)) return;
QDataStream out(&file);
out << path;
【讨论】:
感谢您的回复。我确实将路径作为我的应用程序中的成员变量。我正在检查 file.exists() 是否总是返回 true,所以我认为这可能是另一个问题。我会使用:QFile file("../path.dat"); file.open(QIODevice::WriteOnly); QDataStream & operator 您将使用out << path;
写入路径,并分别使用in >> path;
读取路径。
文件存在并不意味着您可以打开它,因为您可能没有执行该任务的权限。以上是关于序列化形状以保存和重新绘制的主要内容,如果未能解决你的问题,请参考以下文章
Delphi字典保存/加载。 TDictionary不可序列化?