将QGraphicsScene保存到Svg会更改缩放比例

时间:2015-12-09 16:30:47

标签: qt svg qgraphicsscene

我需要将项目从QGraphicsScene保存到svg,然后才能将svg加载到场景中。
我能做到...... 但是每次将画布保存到svg时,加载时项目会更大(反复保存和加载相同的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 ......我无法解释,也无法确定其他例子是否正确。 (似乎)

导致这种增长的原因是什么?我怎么能阻止它?

(另外我注意到排序不同......我只是注意到了,这是一个不同的问题......但是因为在我的“真实”代码中我也有z命令我不在乎。)

保存我认为很好 - 生成的svg具有预期大小的大小和视图框。

加载其他svgs很好 - 从外部源保存svg会创建一个类似的svg。

似乎问题是当我加载由svg生成器创建的svg时,它的大小会增加。

(如果我可以肯定总是如此,我可以尝试在负载下缩小它,但是这个比率不是每次都是1.25,虽然接近......而且我不知道如何分辨它们之间的区别外部svg和生成的svg。)

1 个答案:

答案 0 :(得分:1)

它看起来像是SvgGenerator的一个bug。您为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));