2015-12-09 4 views
1

Мне нужно сохранить элементы из моего QGraphicsScene в svg и получить возможность загрузить этот svg на сцену.
Я могу это сделать ...
Но каждый раз, когда холст сохраняется в svg, при загрузке элементы несколько больше (и многократно сохраняя и загружая один и тот же svg, заставляет его расти).
Я не могу найти причину.Сохранение масштабирования QGraphicsScene to Svg

У меня есть образец кода - и результат.

test1.pro

QT  += gui svg 
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets core 
TARGET = test1 
TEMPLATE = app 
SOURCES += \ 
    svggenerator.cpp 

svggenerator.cpp

#include <QApplication> 
#include <QGraphicsView> 
#include <QGraphicsEllipseItem> 
#include <QGraphicsSvgItem> 
#include <QSvgGenerator> 
#include <QSvgRenderer> 
#include <QFile> 
#include <QByteArray> 
#include <QMessageBox> 

void saveSceneToSvg(QGraphicsScene* s, const QString &filename) { 
    QRectF newSceneRect; 
    QGraphicsScene *tempScene = new QGraphicsScene(s->sceneRect()); 
    tempScene->setBackgroundBrush(QBrush(Qt::transparent)); 
    tempScene->setItemIndexMethod(QGraphicsScene::BspTreeIndex); 
    foreach(QGraphicsItem* item, s->items()) { 
     newSceneRect |= item->mapToScene(item->boundingRect()).boundingRect(); 
     tempScene->addItem(item); 
    } 
    tempScene->setSceneRect(newSceneRect); 
    tempScene->clearSelection(); 
    QSize sceneSize = newSceneRect.size().toSize(); 

    QSvgGenerator generator; 
    generator.setFileName(filename); 
    generator.setSize(sceneSize); 
    generator.setViewBox(QRect(0, 0, sceneSize.width(), sceneSize.height())); 
    generator.setDescription(QObject::tr("My canvas exported to Svg")); 
    generator.setTitle(filename); 
    QPainter painter; 
    painter.begin(&generator); 
    tempScene->render(&painter); 
    painter.end(); 

    tempScene->clear(); 
    delete tempScene; 
} 

void loadSvg(QGraphicsScene* s, const QString &filename, const QPointF& p) { 
    QGraphicsSvgItem* item = new QGraphicsSvgItem(); 
    QFile file(filename); 
    file.open(QFile::ReadOnly); 
    QByteArray contents = file.readAll(); 
    item->setSharedRenderer(new QSvgRenderer(contents)); 
    file.close(); 
    item->setPos(p); 
    s->addItem(item); 
} 

void processScene(QGraphicsScene* s) { 
    QGraphicsEllipseItem* eli = new QGraphicsEllipseItem(); 
    eli->setRect(QRectF(0, 0, 100, 100)); 
    eli->setPen(Qt::NoPen); 
    eli->setBrush(Qt::red); 
    eli->setPos(100, 300); 
    s->addItem(eli); 

    QGraphicsEllipseItem* eli1 = new QGraphicsEllipseItem(); 
    eli1->setRect(QRectF(0, 0, 100, 100)); 
    eli1->setPen(Qt::NoPen); 
    eli1->setBrush(Qt::yellow); 
    eli1->setPos(150, 300); 
    s->addItem(eli1); 

    QMessageBox::information(NULL, "hi", "click"); 

    saveSceneToSvg(s, "abcd.svg"); 
    loadSvg(s, "abcd.svg", QPointF(100,300)); 

    QMessageBox::information(NULL, "hi", "click"); 

    saveSceneToSvg(s, "abcd1.svg"); // saved with a dif name so I can see 
    loadSvg(s, "abcd1.svg", QPointF(100,300)); 

    QMessageBox::information(NULL, "hi", "click"); 

    saveSceneToSvg(s, "abcd2.svg"); 
    loadSvg(s, "abcd2.svg", QPointF(100,300)); 

    // .... each time i call them they grow larger 
} 

int main(int argc, char *argv[]) { 
    QApplication app(argc, argv); 
    QGraphicsScene s; 
    s.setSceneRect(50, 0, 1000, 800); 
    QGraphicsView view(&s); 
    view.show(); 
    processScene(&s); 
    return app.exec(); 
} 

Результат:

enter image description here

Посмотрев на сами svgs, я вижу, что размер svgs увеличивается примерно на 1,25 ... Я не могу объяснить и не могу быть уверенным, что это будет верно для других примеров. (кажется)

Что вызывает этот рост? Как я могу остановить его?

(Также я заметил упорядочение разные ... Я просто заметил, и это другая проблема ... Но так как в моем «реальном» коде, который я также г заказа я не заботиться.)

Сохранение Я думаю, что это нормально - в результате svg имеет размер и поле зрения ожидаемого размера.

Загрузка других svgs в порядке - сохранение svg из-за пределов источника создает SVG аналогичного размера.

Похоже, что проблема заключается в загрузке svg, созданного генератором svg, который увеличивается в размере.

(Если бы я мог быть уверен, что это всегда так, я мог бы попытаться масштабировать его при загрузке, но соотношение не совсем равно 1,25 каждый раз, закрытие, хотя ... и я не знаю, как сказать разницу между внешним svg и сгенерированным).

+0

Подобно тому, как guess..can это будет связано с вашей scenRect s.setSceneRect (50, 0, 1000, 800) ;? Можете ли вы изменить его и проверить, изменилось ли соотношение? –

+0

@ Александр Тяпков - Это не так. Я играл с ним, чтобы сделать свой образец довольно :-), но я испытал то же самое в «реальной» программе с полными различными типами и размерами объектов. Загрузка другого svg также прекрасна. Единственное, что плохо, это загрузка самогенерируемого SVG. – Thalia

+0

ОК. Я попытаюсь воспроизвести ошибку прямо сейчас –

ответ

1

Это похоже на ошибку SvgGenerator. Размер, который вы предоставляете генератору SVG, используется только для формирования заголовка svg. Фактический размер файла .svg отличается от указанного в заголовке. Единственный способ решения проблемы я нашел простой 25-процентное уменьшение размера при сохранении похожие на:

int width = qCeil(qreal(sceneSize.width()/1.25)); 
int height = qCeil(qreal(sceneSize.height()/1.25)); 

generator.setSize(QSize(width, height)); 
generator.setViewBox(QRect(0, 0, width, height)); 
+0

Спасибо ... Я хочу, чтобы был лучший (и более точный) способ. Если я сохраню размер элемента 100x100 и умножу на 0,8, я получаю svg размером 99x99. Я должен создать svg, затем отредактировать файл ... – Thalia

+0

Также в Qt4 каждый раз, когда я загружаю сохраненный svg, все элементы - и сам svg - получают черный ход. – Thalia

+0

Вы забыли qCeil после умножения на 0.8. Если вы это сделаете, размер будет равен 100 на 100 для всех svg. Вероятно, это также решит ошибку с ударом. Я использую qt.5.5 и не вижу никаких ударов по выходным изображениям. –

Смежные вопросы