将QGraphicsScene保存到Svg会更改缩放比例 [英] Saving a QGraphicsScene to Svg changes scaling

查看:551
本文介绍了将QGraphicsScene保存到Svg会更改缩放比例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将我的QGraphicsScene中的项目保存到svg,并能够将该svg重新加载到场景中.
我可以做到的...
但是每次将画布保存到svg时,加载时项目都会变大(并且反复保存和加载相同的svg会使它增长).
我找不到原因.

I need to save the items from my QGraphicsScene to an svg, and be able to load that svg back on the scene.
I can do it...
But each time the canvas is saved to svg, upon load the items are somewhat bigger (and repeatedly saving and loading the same svg causes it to grow).
I can't find the cause.

我正在附上示例代码-结果.

I am attaching a sample code - and the result.

test1.pro

test1.pro

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

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();
}

结果:

看看svg本身,我可以看到svg的大小增加了大约1.25 ...我无法解释,也无法确定其他示例是否正确. (似乎)

Looking at the svgs themselves, I can see that the svgs increase in size by approx 1.25... I can't explain, and can't be sure this will be true for other examples. (it seems to)

是什么导致这种增长?我该如何阻止它?

What is causing this growth ? How can I stop it ?

(另外,我注意到顺序是不同的...我刚刚注意到了,这是一个不同的问题...但是由于在我的真实"代码中我也有z顺序,所以我不在乎.)

(Also I notice the ordering is different ... I just noticed and that is a different problem... But since in my "real" code I also have z order I don't care.)

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

Saving I think is fine - the resulting svg has size and view box of expected size.

加载其他svg很好-从外部来源保存svg会创建一个大小相似的svg.

Loading other svgs is fine - saving an svg from outside source creates an svg similar in size.

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

It seems the problem is when I am loading an svg created by the svg generator that it increases in size.

(如果可以肯定的话,我可以尝试在负载下按比例缩小比例,但是每次的比例都不完全是1.25,虽然接近...但是我不知道如何区分两者之间的区别外部svg和生成的svg.

(If I could be sure it is always the case I could try scaling it down on load, but the ratio is not exactly 1.25 each time, close though... and I don't know how to tell the difference between an outside svg and a generated one).

推荐答案

它看起来像是SvgGenerator的错误.您提供给SVG生成器的大小仅用于形成svg的标头. .svg文件的实际大小与标头中写入的大小不同.我发现的唯一解决方法是,将保存的大小简单地减少了25%,类似于:

It looks like a bug of SvgGenerator. The size which you provide to SVG generator is used only to form the header of svg. The actual size of .svg file differs from one written in the header. The only workaround I found is simple 25 percent decrease of size on save similar to:

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));

这篇关于将QGraphicsScene保存到Svg会更改缩放比例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆