If you want to save the QGraphicsXXXItems in a file you must save the main properties that define them, in the following code I show how to save the main properties of the following items:
- QGraphicsLineItem
- QGraphicsSimpleTextItem
- QGraphicsRectItem
- QGraphicsPolygonItem
- QGraphicsPathItem
- QGraphicsPixmapItem
this answer does not cover the relationship of parents and children or the QGraphicsObject
.
utils.h
#ifndef UTILS_H
#define UTILS_H
#include <QDataStream>
#include <QFont>
#include <QGraphicsLineItem>
#include <QPen>
QDataStream &operator<<(QDataStream & out, QGraphicsItem * item){
out << item->pos()
<< item->scale()
<< item->rotation()
<< item->transform()
<< item->transformOriginPoint()
<< item->flags()
<< item->isEnabled()
<< item->isSelected()
<< item->zValue();
return out;
}
QDataStream &operator>>(QDataStream & in, QGraphicsItem* & item){
QPointF pos;
qreal scale;
qreal rotation;
QTransform transform;
QPointF transformOriginPoint;
QGraphicsItem::GraphicsItemFlags flags;
bool isEnabled;
bool isSelected;
qreal zValue;
in >> pos
>> scale
>> rotation
>> transform
>> transformOriginPoint
>> flags
>> isEnabled
>> isSelected
>> zValue;
item->setPos(pos);
item->setScale(scale);
item->setRotation(rotation);
item->setTransform(transform);
item->setTransformOriginPoint(transformOriginPoint);
item->setFlags(flags);
item->setEnabled(isEnabled);
item->setSelected(isSelected);
item->setZValue(zValue);
return in;
}
QDataStream &operator<<(QDataStream & out, QAbstractGraphicsShapeItem * item){
out << dynamic_cast<QGraphicsItem *>(item);
out << item->pen() << item->brush();
return out;
}
QDataStream &operator>>(QDataStream & in, QAbstractGraphicsShapeItem* & item){
QGraphicsItem *tmp = dynamic_cast<QGraphicsItem *>(item);
in >> tmp;
QPen pen;
QBrush brush;
in >> pen >> brush;
item->setBrush(brush);
item->setPen(pen);
return in;
}
QDataStream &operator<<(QDataStream & out, QGraphicsEllipseItem * item){
out << dynamic_cast<QAbstractGraphicsShapeItem *>(item);
out << item->rect() << item->startAngle() << item->spanAngle();
return out;
}
QDataStream &operator>>(QDataStream & in, QGraphicsEllipseItem* & item){
QAbstractGraphicsShapeItem *tmp = dynamic_cast<QAbstractGraphicsShapeItem *>(item);
in >> tmp;
QRectF rect;
int startAngle;
int spanAngle;
in >> rect >> startAngle >> spanAngle;
item->setRect(rect);
item->setStartAngle(startAngle);
item->setSpanAngle(spanAngle);
return in;
}
QDataStream &operator<<(QDataStream & out, QGraphicsPathItem * item){
out << dynamic_cast<QAbstractGraphicsShapeItem *>(item);
out << item->path();
return out;
}
QDataStream &operator>>(QDataStream & in, QGraphicsPathItem* & item){
QAbstractGraphicsShapeItem *tmp = dynamic_cast<QAbstractGraphicsShapeItem *>(item);
in >> tmp;
QPainterPath path;
in >> path;
item->setPath(path);
return in;
}
QDataStream &operator<<(QDataStream & out, QGraphicsPolygonItem * item){
out << dynamic_cast<QAbstractGraphicsShapeItem *>(item);
out << item->polygon()<< item->fillRule();
return out;
}
QDataStream &operator>>(QDataStream & in, QGraphicsPolygonItem* & item){
QAbstractGraphicsShapeItem *tmp = dynamic_cast<QAbstractGraphicsShapeItem *>(item);
in >> tmp;
QPolygonF polygon;
int rule;
in >> polygon>>rule;
item->setPolygon(polygon);
item->setFillRule(Qt::FillRule(rule));
return in;
}
QDataStream &operator<<(QDataStream & out, QGraphicsRectItem * item){
out << dynamic_cast<QAbstractGraphicsShapeItem *>(item);
out << item->rect();
return out;
}
QDataStream &operator>>(QDataStream & in, QGraphicsRectItem* & item){
QAbstractGraphicsShapeItem *tmp = dynamic_cast<QAbstractGraphicsShapeItem *>(item);
in >> tmp;
QRectF rect;
in >> rect;
item->setRect(rect);
return in;
}
QDataStream &operator<<(QDataStream & out, QGraphicsSimpleTextItem * item){
out << dynamic_cast<QAbstractGraphicsShapeItem *>(item);
out << item->text()<<item->font();
return out;
}
QDataStream &operator>>(QDataStream & in, QGraphicsSimpleTextItem* & item){
QAbstractGraphicsShapeItem *tmp = dynamic_cast<QAbstractGraphicsShapeItem *>(item);
in >> tmp;
QString text;
QFont font;
in >> text >> font;
item->setText(text);
item->setFont(font);
return in;
}
QDataStream &operator<<(QDataStream & out, QGraphicsLineItem * item){
out << dynamic_cast<QGraphicsItem *>(item);
out << item->pen()<<item->line();
return out;
}
QDataStream &operator>>(QDataStream & in, QGraphicsLineItem* & item){
QGraphicsItem *tmp = dynamic_cast<QGraphicsItem *>(item);
in >> tmp;
QPen pen;
QLineF line;
in >> pen >> line;
item->setPen(pen);
item->setLine(line);
return in;
}
QDataStream &operator<<(QDataStream & out, QGraphicsPixmapItem * item){
out << dynamic_cast<QGraphicsItem *>(item);
out << item->pixmap()<<item->offset()<<item->transformationMode()<<item->shapeMode();
return out;
}
QDataStream &operator>>(QDataStream & in, QGraphicsPixmapItem* & item){
QGraphicsItem *tmp = dynamic_cast<QGraphicsItem *>(item);
in >> tmp;
QPixmap pixmap;
QPointF offset;
int transformationMode;
int shapeMode;
in >> pixmap>> offset>> shapeMode >> transformationMode;
item->setPixmap(pixmap);
item->setOffset(offset);
item->setTransformationMode(Qt::TransformationMode(transformationMode));
item->setShapeMode(QGraphicsPixmapItem::ShapeMode(shapeMode));
return in;
}
static void saveItems(QList<QGraphicsItem *> items, QDataStream & out){
for(QGraphicsItem *item : items){
out << item->type();
switch (item->type()) {
case QGraphicsLineItem::Type:
out << dynamic_cast<QGraphicsLineItem *>(item);
break;
case QGraphicsSimpleTextItem::Type:
out << dynamic_cast<QGraphicsSimpleTextItem *>(item);
break;
case QGraphicsRectItem::Type:
out << dynamic_cast<QGraphicsRectItem *>(item);
break;
case QGraphicsPolygonItem::Type:
out << dynamic_cast<QGraphicsPolygonItem *>(item);
break;
case QGraphicsPathItem::Type:
out << dynamic_cast<QGraphicsPathItem *>(item);
break;
case QGraphicsPixmapItem::Type:
out << dynamic_cast<QGraphicsPixmapItem *>(item);
break;
}
}
}
static QList<QGraphicsItem *> readItems(QDataStream & in){
QList<QGraphicsItem *> items;
int type;
while (!in.atEnd()) {
in >> type;
switch (type) {
case QGraphicsLineItem::Type: {
QGraphicsLineItem *item = new QGraphicsLineItem;
in >> item;
items << item;
break;
}
case QGraphicsSimpleTextItem::Type:{
QGraphicsSimpleTextItem *item = new QGraphicsSimpleTextItem;
in >> item;
items << item;
break;
}
case QGraphicsRectItem::Type:{
QGraphicsRectItem *item = new QGraphicsRectItem;
in >> item;
items << item;
break;
}
case QGraphicsPolygonItem::Type:{
QGraphicsPolygonItem *item = new QGraphicsPolygonItem;
in >> item;
items << item;
break;
}
case QGraphicsPathItem::Type:{
QGraphicsPathItem *item = new QGraphicsPathItem;
in >> item;
items << item;
break;
}
case QGraphicsPixmapItem::Type:{
QGraphicsPixmapItem *item = new QGraphicsPixmapItem;
in >> item;
items << item;
break;
}
}
}
return items;
}
#endif // UTILS_H
Example:
main.cpp
#include "utils.h"
#include <QApplication>
#include <QFile>
#include <QGraphicsLineItem>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QTimer>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QGraphicsView view(new QGraphicsScene);
QGraphicsEllipseItem *eitem = view.scene()->addEllipse(QRect(10, 10, 80, 50), QPen(Qt::green), QBrush(Qt::black));
eitem->setPos(100, 10);
eitem->setRotation(60);
QGraphicsLineItem *litem = view.scene()->addLine(QLineF(0, 0, 100, 100), QPen(Qt::red));
litem->setPos(10, 10);
litem->setRotation(100);
QGraphicsRectItem *ritem = view.scene()->addRect(QRect(10, 0, 100, 100), QPen(Qt::blue), QBrush(Qt::red));
ritem->setPos(10, 100);
ritem->setRotation(10);
QPainterPath path;
path.moveTo(100, 100);
path.lineTo(10, 0);
path.addRect(QRect(0, 0, 100, 22));
QGraphicsPathItem *pitem = view.scene()->addPath(path, QPen(Qt::green), QBrush(Qt::black));
pitem->setPos(100, 22);
pitem->setRotation(120);
QGraphicsPixmapItem *pixmapitem = new QGraphicsPixmapItem;
pixmapitem->setPixmap(QPixmap(":/image.png"));
view.scene()->addItem(pixmapitem);
QGraphicsItem::GraphicsItemFlags flags = QGraphicsItem::ItemIsMovable
| QGraphicsItem::ItemIsSelectable
| QGraphicsItem::ItemIsFocusable
| QGraphicsItem::ItemClipsToShape
| QGraphicsItem::ItemClipsChildrenToShape;
for(QGraphicsItem *it : view.scene()->items()){
it->setFlags(flags);
}
QTimer::singleShot(4000, [&view](){
qDebug()<< "writing ...";
QFile fileOut("file.txt");
if(fileOut.open(QIODevice::WriteOnly)){
QDataStream out(&fileOut);
saveItems(view.scene()->items(), out);
fileOut.close();
qDebug()<<"clear items";
view.scene()->clear();
}
});
QTimer::singleShot(5000, [&view](){
qDebug()<< "reading ...";
QFile fileIn("file.txt");
if(fileIn.open(QIODevice::ReadOnly)){
QDataStream in(&fileIn);
QList<QGraphicsItem *> items = readItems(in);
for(QGraphicsItem *item : items){
view.scene()->addItem(item);
}
}
});
view.show();
return a.exec();
}
In the following link you can find the complete example.
QSetting
to save your geometries points. – PropellerQSetting
already knows how to read/writeQPoint
s and otherQVariant
types. – Propeller