0

I have a QGraphicsScene where I am drawing a QPainterPath, and I need to be able to save the shape, and redraw it when the app runs again. Here is how I'm drawing the shape, simplified version, and my write method.

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();
}

Currently, my file is never written to when it runs.

But beyond that, is the correct way to serialize this data so that I can rebuild the shape?

I thought I would be able to handle re-drawing, but I'm not understanding the serialization well enough.

Do I serialize the points? The List containing the points?

My thought was if I serialize the points, when I deserialize, I then add them to a list, and I should be able to recreate the shape based on the position of each point in the list; ie point at position 0 would be p1, point at 1 would be p2, etc. But I can't get this far because nothing is being written to the file anyway. Plus I'm not entirely sure what to expect from the serialization of the data in the first place.

Any help on this would be wonderful.

EDIT: based on feedback, I am now trying to this in my write method

QFile file("../path.dat");
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
QDataStream & operator << (QDataStream& file, const QPainterPath& path);
out << path;
file.close();

This compiles fine, even though I'm not entirely sure I'm doing that right, nothing is being written to the file so I assume I'm still off somewhere.

bauervision
  • 847
  • 2
  • 9
  • 25

1 Answers1

3

Qt already provides the operators, necessary to serialize and deserialize the QPainterPath directly:

QDataStream &   operator<<(QDataStream & stream, const QPainterPath & path)
QDataStream &   operator>>(QDataStream & stream, QPainterPath & path)

So there is no need to serialize points, when you can serialize the exact content of the path, including complex multi-component paths.

So you should implement the path as a persistent member variable, so that you can read it from or write it to a file, and in the draw method you simply draw the path.

Currently, my file is never written to when it runs.

My bet is because writePointsToFile() is never invoked. You may also get in the good habit of checking for errors when you try and open files and such. You also don't specify QIODevice::Append so even if you did write to disk, you'd only write one single point, overwriting the previous each time.

Edit: based on your edit, it looks like you are getting ahead of yourself, and still have to learn basic C++ before you rush into using it. Try something like this, and figure where you are going wrong:

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;
dtech
  • 47,916
  • 17
  • 112
  • 190
  • thanks for responding. I do have the path as a member variable in my app. I was checking whether the file.exists(), which was always returning true so I figured it was maybe another issue. Would I use: QFile file("../path.dat"); file.open(QIODevice::WriteOnly); QDataStream & operator<<(QDataStream & stream, const QPainterPath & path) ? – bauervision Apr 17 '17 at 18:35
  • You would use `out << path;` to write and respectively, `in >> path;` to read the path. – dtech Apr 17 '17 at 18:37
  • That the file exists does not imply that you can open it, since you may not have permissions to do that task. – eyllanesc Apr 17 '17 at 18:39