Название: сохранение элементов QGraphicsScene в файл
Отправлено: serega-5508 от Май 07, 2011, 12:12
как сделать сохранение элементов сцены(прямоугольник, эллипс, квадрат и т.д.) не в формате jpg, а в каком-то своём, который можно было бы открывать. пример, по принципу которого хотел бы организовать сохранение выложен здесь: http://turbobit.net/ayo9anetum35/qdiagram_0v1.rar.html
Название: Re: сохранение элементов QGraphicsScene в файл
Отправлено: ufna от Май 07, 2011, 12:21
Да как везде :)
прогоняешь по нужным айтемам, сохраняешь их к примеру в тот же .ini как набор уникальных свойств. Потом так же загружаешь - на основании этих свойств.
Название: Re: сохранение элементов QGraphicsScene в файл
Отправлено: serega-5508 от Май 07, 2011, 14:06
пример какой-нибудь подкинуть можете, чтобы было наглядно понятно, а то в том примере, что-то я не до конца понял???
Название: Re: сохранение элементов QGraphicsScene в файл
Отправлено: alexman от Май 07, 2011, 15:19
Сохраняй, например, в xml: для айтема сохраняй тип и "внутренности". При загрузке по типу создаешь нужный айтем и грузишь "внутренности".
Название: Re: сохранение элементов QGraphicsScene в файл
Отправлено: ufna от Май 07, 2011, 20:56
а в чем сложность?
что такое сцена? Набор айтемов. У айтемов есть набор свойств (положение, вращение, масштаб, картинка, форма и т.п., конкретно для каждого свое). Берешь, сохраняешь это как набор свойст. Загружаешь точно так же - читаешь, и на основании свойств добавляешь айтемы на сцену и саму сцену настраиваешь.
Название: Re: сохранение элементов QGraphicsScene в файл
Отправлено: Fregloin от Май 08, 2011, 17:26
при этом проще добавить в наследники итемов методы загруски и сохранения. как я делал: для базового класса, который наследуется от graphicsITem добавил 2 виртуальных метода loadFromStream и saveToStream, которые отвеяают за загрузку и сохранение item в поток(но я на самом деле храню в XML-дереве). такой подход позволяет расширять возможности загрузки/сохранения в наследниках. вот пример базового класса для элементов (для виджетов на сцене у меня свой класс, но суть таже) class QRailItem : public QObject, public QGraphicsItem { Q_OBJECT Q_INTERFACES (QGraphicsItem) public: virtual void loadFromStream(QDomDocument * doc,QDomElement * node); virtual void saveToStream(QDomDocument * doc,QDomElement * node); };
вот реализация void QRailItem::loadFromStream(QDomDocument * /*doc*/, QDomElement * node) { QDomElement railItemNode = node->firstChildElement("RailItemData"); //нода класса QRailItem if(!railItemNode.isNull()) { bool ok; QPointF pos; id = railItemNode.attribute("ObjectID","0").toLong(&ok); setRotation(railItemNode.attribute("Angle").toFloat(&ok)); pos.setX(railItemNode.attribute("PosX").toFloat(&ok)); pos.setY(railItemNode.attribute("PosY").toFloat(&ok)); this->setPos(pos); setZValue(railItemNode.attribute("ZValue","0").toFloat(&ok)); } }
void QRailItem::saveToStream(QDomDocument * doc, QDomElement * node) { QDomElement railItemNode = doc->createElement("RailItemData"); //создаю ноду класса QRailItem railItemNode.setAttribute("ObjectID",id); railItemNode.setAttribute("PosX",pos().x()); railItemNode.setAttribute("PosY",pos().y()); railItemNode.setAttribute("Angle",rotation()); railItemNode.setAttribute("ZValue",zValue()); node->appendChild(railItemNode); }
теперь пример наследника class QSection: public QRailItem { Q_OBJECT public: void loadFromStream(QDomDocument * doc,QDomElement * node); void saveToStream(QDomDocument * doc,QDomElement * node); };
сохраняем наследника void QSection::loadFromStream(QDomDocument * doc,QDomElement * node) { QRailItem::loadFromStream(doc,node); //загрузка части предка QDomElement sectionNode = node->firstChildElement("SimpleSectionData"); //находим часть этого класса if(!sectionNode.isNull()) //далее все грузится все что касается этого класса, так как размер, позицию и прочее мы узнали при загрузке базового класса { QDomElement anchorsNode = sectionNode.firstChildElement("Anchors"); if(!anchorsNode.isNull()) for(QDomNode anchorNode = anchorsNode.firstChildElement("Anchor");!anchorNode.isNull();anchorNode = anchorNode.nextSibling()) { QDomElement anchorElement = anchorNode.toElement(); if(!anchorElement.isNull()) { bool ok; QPointF currentAnchor; currentAnchor.setX(anchorElement.attribute("PosX").toFloat(&ok)); currentAnchor.setY(anchorElement.attribute("PosY").toFloat(&ok)); fpolygon.addPoint(currentAnchor); } } } }
void QSection::saveToStream(QDomDocument * doc,QDomElement * node) { QRailItem::saveToStream(doc,node); //сохраняем часть базового класса
QDomElement sectionNode = doc->createElement("SimpleSectionData"); //теперь все что связано с этим классом
//получаем список опорных точек полигона секции QList<QPointF>* anchors_list = fpolygon.anchors(); QPointF current_acnchor;
QDomElement anchors = doc->createElement("Anchors");
for(QList<QPointF>::iterator current_anchor_it=anchors_list->begin();current_anchor_it!=anchors_list->end();current_anchor_it++) { current_acnchor = *current_anchor_it; QDomElement anchor = doc->createElement("Anchor"); anchor.setAttribute("PosX",current_acnchor.x()); anchor.setAttribute("PosY",current_acnchor.y()); anchors.appendChild(anchor); }
sectionNode.appendChild(anchors); node->appendChild(sectionNode); }
а вот кусок как грузить сцену: //находим секцию с эелементами поля QDomElement fieldObjects = root.firstChildElement("FieldObjects"); if(fieldObjects.isNull()) return false;
scene()->setLastId(fieldObjects.attribute("LastId","0").toLong(&ok));
for(QDomNode fieldNode = fieldObjects.firstChildElement("FieldObject");!fieldNode.isNull();fieldNode = fieldNode.nextSibling()) { QDomElement fieldObject = fieldNode.toElement(); if(fieldObject.isNull()) continue;
object_type = fieldObject.attribute("ObjectType"); //тут грузятся много разных объектов разных классов //**** //находим наш объект if(object_type=="Section") { QSection * section = new QSection(false); //создаем объект section->loadFromStream(&doc,&fieldObject); //грузим ноду объекта section->recalculate(); //внутренние пересчеты fscene->addSection(section); //добавляем на сцену continue; //дальше нет смысла идти, ищем следующий объект ... } //*** }
пример сохранения //теперь сохраняем данные о графических объектах QDomElement fieldObjects = doc.createElement("FieldObjects"); fieldObjects.setAttribute("LastId",scene()->lastId()); root.appendChild(fieldObjects);
for(QList<QGraphicsItem*>::iterator items_it = fitems.begin();items_it!=fitems.end();items_it++) //проходимся по всей сцене { gi = *items_it; if((item = dynamic_cast<QRailItem*>(gi))==NULL) continue; //если не наследник от QRailItem проходим далее //пишем новую секцию <FieldObject>
object_type = item->type();
switch(object_type) { case otRailItem: param = "RailItem"; break; //**** case otSection: param = "Section"; break; //**** default: //остальные игнорируем continue; }
QDomElement fieldObject = doc.createElement("FieldObject"); //создаем ноду объекта сцены fieldObject.setAttribute("ObjectType",param); //пишем тип объекта
switch(object_type) { //*** case otSection: { if((section = dynamic_cast<QSection*>(item))!=NULL) section->saveToStream(&doc,&fieldObject); } break;
//**** default: break; } //завершаем секцию <FiledObject> fieldObjects.appendChild(fieldObject); }
надеюсь идею поняли. по сути это можно грубо назвать сериализацией, но более примитивная и сохраняю/гружу только выбранные поля объектов.
Название: Re: сохранение элементов QGraphicsScene в файл
Отправлено: serega-5508 от Май 09, 2011, 01:46
спасибо большое всем! буду стараться разобраться! :)
|