Russian Qt Forum
Ноябрь 25, 2024, 08:12 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: сохранение элементов QGraphicsScene в файл  (Прочитано 6435 раз)
serega-5508
Гость
« : Май 07, 2011, 12:12 »

как сделать сохранение элементов сцены(прямоугольник, эллипс, квадрат и т.д.) не в формате jpg, а в каком-то своём, который можно было бы открывать. пример, по принципу которого хотел бы организовать сохранение выложен здесь:
http://turbobit.net/ayo9anetum35/qdiagram_0v1.rar.html

Записан
ufna
Гость
« Ответ #1 : Май 07, 2011, 12:21 »

Да как везде Улыбающийся

прогоняешь по нужным айтемам, сохраняешь их к примеру в тот же .ini как набор уникальных свойств. Потом так же загружаешь - на основании этих свойств.
Записан
serega-5508
Гость
« Ответ #2 : Май 07, 2011, 14:06 »

пример какой-нибудь подкинуть можете, чтобы было наглядно понятно, а то в том примере, что-то я не до конца понял???
Записан
alexman
Гость
« Ответ #3 : Май 07, 2011, 15:19 »

Сохраняй, например, в xml: для айтема сохраняй тип и "внутренности". При загрузке по типу создаешь нужный айтем и грузишь "внутренности".
Записан
ufna
Гость
« Ответ #4 : Май 07, 2011, 20:56 »

а в чем сложность?

что такое сцена? Набор айтемов. У айтемов есть набор свойств (положение, вращение, масштаб, картинка, форма и т.п., конкретно для каждого свое). Берешь, сохраняешь это как набор свойст. Загружаешь точно так же - читаешь, и на основании свойств добавляешь айтемы на сцену и саму сцену настраиваешь.
Записан
Fregloin
Супер
******
Offline Offline

Сообщений: 1025


Просмотр профиля
« Ответ #5 : Май 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);
        }

надеюсь идею поняли. по сути это можно грубо назвать сериализацией, но более примитивная и сохраняю/гружу только выбранные поля объектов.
Записан
serega-5508
Гость
« Ответ #6 : Май 09, 2011, 01:46 »

спасибо большое всем! буду стараться разобраться!  Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.047 секунд. Запросов: 22.