Qt/C++ - Lesson 045. SvgReader on the Qt. Loading data from SVG file into QGraphicsScene

QGraphicsScene, Qt, SVG, Svg Reader

In the last article I was considered an example of how to save objects in a graphical scene SVG file, and then we were able to open it in CorelDraw. Now try the same file open and restore the graphics in QGraphicsScene .

Note that we will not use QSvgRenderer class for this, for the reason that it is easily put the contents of SVG files in the graphic scene, but it will be one single graphic, but if you need to have it restored as a separate graphic objects, such as , QGraphicsItem , you will need to parse the SVG file to make of it all graphical objects.

Since SVG file is of XML-format structure, then disassemble it does not present any difficulty using classes QDomDocument family.

Структура проекта

As an example, the draft of the preceding article to be used, but will be diluted with additional class two static methods.

  • SVGExample.pro - the profile of the project;
  • svgreader.h - header parsing SVG file;
  • svgreader.cpp - source SVG file parser;
  • mainwindow.h - header file of the main application window;
  • mainwindow.cpp - file source code of the main application window;
  • mainwindow.ui - file forms the main application window;
  • main.cpp - start file the application source code.

Structure of SVG file

Because we need to parse the file, look at his insides.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="141.111mm" height="141.111mm"
 viewBox="0 0 400 400"
 xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  version="1.2" baseProfile="tiny">
<title>SVG Example</title>
<desc>File created by SVG Example</desc>
<defs>
</defs>
<g fill="none" stroke="black" stroke-width="1" fill-rule="evenodd" stroke-linecap="square" stroke-linejoin="bevel" >

<g fill="#ff0000" fill-opacity="1" stroke="#000000" stroke-opacity="1" stroke-width="2" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,0,0)"
font-family="MS Shell Dlg 2" font-size="8.25" font-weight="400" font-style="normal" 
>
<rect x="10" y="50" width="100" height="50"/>
</g>
</g>

So, we are interested in svg tag, g, rect . The tag contains svg the size of the graphic scenes - it viewBox. The tag contains a rectangle rect size and the tag g, which wrapped rect tag contains the fill color and outline of a rectangle, and the thickness of the outline. They will need and Spars.

mainwindow.ui

This file will be added when the button load, on a signal from which the open file dialog and launch the opening of our SVG file.

SVGExample.pro

I call your attention to the fact that the profile of the project will connect the module xml need.

QT += xml

svgreader.h

#ifndef SVGREADER_H
#define SVGREADER_H

#include <QList>
#include <QGraphicsRectItem>

class SvgReader
{
public:
    SvgReader();
    static QList<QGraphicsRectItem *> getElements(const QString filename);
    static QRectF getSizes(const QString filename);
};

#endif // SVGREADER_H

svgreader.cpp

#include "svgreader.h"
#include <QPen>
#include <QFile>
#include <QMessageBox>
#include <QDomDocument>
#include <QStringList>

SvgReader::SvgReader()
{

}

QList<QGraphicsRectItem *> SvgReader::getElements(const QString filename)
{
    QList<QGraphicsRectItem *> rectList;    // Declare the stack list boxes

    QDomDocument doc;       // document object
    QFile file(filename);   // Open your SVG-file
    // If it is not opened, or have failed to transmit the contents in QDocDocument
    if (!file.open(QIODevice::ReadOnly) || !doc.setContent(&file))
        return rectList;    // the refund list, but empty

    // We are looking for all objects in a document with tag g
    QDomNodeList gList = doc.elementsByTagName("g");
    // Getting them to touch
    for (int i = 0; i < gList.size(); i++) {
        QDomNode gNode = gList.item(i);     // Select from the node list
        QDomElement rectangle = gNode.firstChildElement("rect");    // And we seek in her element c rect tag
        // If the resulting elements are not zero, then
        if (rectangle.isNull()){
            continue;
        } else {
            // We begin to create a rectangle
            QGraphicsRectItem *rect = new QGraphicsRectItem();
            // This flag makes the object moves, the need to test
            rect->setFlag(QGraphicsItem::ItemIsMovable);
            // Taking the dimensions of rect tag
            QDomElement gElement = gNode.toElement();
            rect->setRect(rectangle.attribute("x").toInt(),
                          rectangle.attribute("y").toInt(),
                          rectangle.attribute("width").toInt(),
                          rectangle.attribute("height").toInt());

            /* Take away from the element node gNode color options
             * Yes yes yes ... because of gNode, instead of the rectangle. These parameters are stored in the tag g
             * */
            QColor fillColor(gElement.attribute("fill", "#ffffff"));    
            fillColor.setAlphaF(gElement.attribute("fill-opacity","0").toFloat());
            rect->setBrush(QBrush(fillColor));

            QColor strokeColor(gElement.attribute("stroke", "#000000"));
            strokeColor.setAlphaF(gElement.attribute("stroke-opacity").toFloat());

            rect->setPen(QPen(strokeColor,gElement.attribute("stroke-width", "0").toInt()));
            rectList.append(rect);  
        }
    }
    file.close();
    return rectList;
}

QRectF SvgReader::getSizes(const QString filename)
{
    QDomDocument doc;       // initialize the stack object QDomDocument
    QFile file(filename);   // Open your SVG-file
    // If it is not opened, or have failed to transmit the contents in QDocDocument
    if (!file.open(QIODevice::ReadOnly) || !doc.setContent(&file))
        return QRectF(0,0,200,200); // the return values for the default scene

    /* Then pick up a list of items with the tag svg.
      * If a list of elements is not empty,
      * take the size of the graphic scenes.
     * */
    QDomNodeList list = doc.elementsByTagName("svg");
    if(list.length() > 0) {
        QDomElement svgElement = list.item(0).toElement();
        QStringList parameters = svgElement.attribute("viewBox").split(" ");
        return QRectF(parameters.at(0).toInt(),
                      parameters.at(1).toInt(),
                      parameters.at(2).toInt(),
                      parameters.at(3).toInt());
    }
    return QRectF(0,0,200,200);
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QSvgGenerator>
#include <QFileDialog>
#include <QPainter>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_saveButton_clicked();
    void on_loadButton_clicked();

private:
    Ui::MainWindow *ui;
    QGraphicsScene *scene;  
    QString path;           // The path to save the file
};

#endif // MAINWINDOW_H

mainwindow.cpp

Here in this file only the contents directly related to the analysis of the SVG file. The pressing processing slot button is selected using a file dialog box, and is broken down into graphical objects.

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "svgreader.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    scene = new QGraphicsScene();
    ui->graphicsView->setScene(scene);
    scene->setSceneRect(0,0,400,400);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_saveButton_clicked()
{
    // The code from the previous tutorial on working with SVG
}

void MainWindow::on_loadButton_clicked()
{
    QString newPath = QFileDialog::getOpenFileName(this, trUtf8("Open SVG"),
                                                   path, tr("SVG files (*.svg)"));
    if (newPath.isEmpty())
        return;

    path = newPath;
    scene->clear();

    scene->setSceneRect(SvgReader::getSizes(path)); 

    // To set a graphic scene objects, received them with a method getElements
    foreach (QGraphicsRectItem *item, SvgReader::getElements(path)) {
        QGraphicsRectItem *rect = item;
        scene->addItem(rect);
    }
}

Result

As a result, you will be able to parse the SVG file you saved to take away from him even rectangles. If you want to take all the other objects, you have pretty sweat, and write a parser for all these other objects similar to the rectangle. The only thing I want to note, do not try to use this code to open a file that was created originally in CorelDraw, the fact that the structure of the SVG file version is also very different. And this code for parsing a file that was created in the previous lesson, and the structure of the generated package CorelDraw files is slightly different and will not be read completely.

A project that brings together both lessons downloaded from the following link: SvgExample

  1. SvgReader on the Qt. Loading data from SVG file into QGraphicsScene

Video

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
Support the author Donate
F
  • #
  • Aug. 12, 2017, 7:24 a.m.

Здравствуйте!

Назрел вопрос насчет данной темы.
Реализовал отрисовку и перемещение объектов на сцене по структуре урока https://evileg.com/post/86/
Но там я в MoveItem.cpp отрисовывал не с drawRect, а с drawEllipse
void MoveItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->setPen(Qt::black);
    painter->setBrush(Qt::cyan);
    //painter->drawRect(-30,-30,60,60);
    painter->drawEllipse(-30,-30,30,30);
    painter->drawEllipse(-25,-25,20,20);
    painter->drawEllipse(-20,-20,10,10);
    Q_UNUSED(option);
    Q_UNUSED(widget);
}
Далее возвращал область также прямоугольную
QRectF MoveItem::boundingRect() const
{
    return QRectF (-30,-30,30,30);
}
После добавления нескольких объектов на сцену
также проделал процесс сохранения в *.svg. При этом создался файл, где тег rect отсутствует
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="176.389mm" height="176.389mm"
viewBox="0 0 500 500"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  version="1.2" baseProfile="tiny">
<title>SVG VKR</title>
<desc>File created by Fidan Gallyamov</desc>
<defs>
</defs>
<g fill="none" stroke="black" stroke-width="1" fill-rule="evenodd" stroke-linecap="square" stroke-linejoin="bevel" >

<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,0,0)"
font-family="MS Shell Dlg 2" font-size="8.25" font-weight="400" font-style="normal"
>
</g>

<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,416,71)"
font-family="MS Shell Dlg 2" font-size="8.25" font-weight="400" font-style="normal"
>
</g>

<g fill="#00ffff" fill-opacity="1" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,416,71)"
font-family="MS Shell Dlg 2" font-size="8.25" font-weight="400" font-style="normal"
>
<path vector-effect="non-scaling-stroke" fill-rule="evenodd" d="M0,-15 C0,-6.71573 -6.71573,0 -15,0 C-23.2843,0 -30,-6.71573 -30,-15 C-30,-23.2843 -23.2843,-30 -15,-30 C-6.71573,-30 0,-23.2843 0,-15 "/>
<path vector-effect="non-scaling-stroke" fill-rule="evenodd" d="M-5,-15 C-5,-9.47715 -9.47715,-5 -15,-5 C-20.5228,-5 -25,-9.47715 -25,-15 C-25,-20.5228 -20.5228,-25 -15,-25 C-9.47715,-25 -5,-20.5228 -5,-15 "/>
<path vector-effect="non-scaling-stroke" fill-rule="evenodd" d="M-10,-15 C-10,-12.2386 -12.2386,-10 -15,-10 C-17.7614,-10 -20,-12.2386 -20,-15 C-20,-17.7614 -17.7614,-20 -15,-20 C-12.2386,-20 -10,-17.7614 -10,-15 "/>
</g>

<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,416,71)"
font-family="MS Shell Dlg 2" font-size="8.25" font-weight="400" font-style="normal"
>
</g>

<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,70,190)"
font-family="MS Shell Dlg 2" font-size="8.25" font-weight="400" font-style="normal"
>
</g>

<g fill="#00ffff" fill-opacity="1" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,70,190)"
font-family="MS Shell Dlg 2" font-size="8.25" font-weight="400" font-style="normal"
>
<path vector-effect="non-scaling-stroke" fill-rule="evenodd" d="M0,-15 C0,-6.71573 -6.71573,0 -15,0 C-23.2843,0 -30,-6.71573 -30,-15 C-30,-23.2843 -23.2843,-30 -15,-30 C-6.71573,-30 0,-23.2843 0,-15 "/>
<path vector-effect="non-scaling-stroke" fill-rule="evenodd" d="M-5,-15 C-5,-9.47715 -9.47715,-5 -15,-5 C-20.5228,-5 -25,-9.47715 -25,-15 C-25,-20.5228 -20.5228,-25 -15,-25 C-9.47715,-25 -5,-20.5228 -5,-15 "/>
<path vector-effect="non-scaling-stroke" fill-rule="evenodd" d="M-10,-15 C-10,-12.2386 -12.2386,-10 -15,-10 C-17.7614,-10 -20,-12.2386 -20,-15 C-20,-17.7614 -17.7614,-20 -15,-20 C-12.2386,-20 -10,-17.7614 -10,-15 "/>
</g>

<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,70,190)"
font-family="MS Shell Dlg 2" font-size="8.25" font-weight="400" font-style="normal"
>
</g>

<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,319,236)"
font-family="MS Shell Dlg 2" font-size="8.25" font-weight="400" font-style="normal"
>
</g>

<g fill="#00ffff" fill-opacity="1" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,319,236)"
font-family="MS Shell Dlg 2" font-size="8.25" font-weight="400" font-style="normal"
>
<path vector-effect="non-scaling-stroke" fill-rule="evenodd" d="M0,-15 C0,-6.71573 -6.71573,0 -15,0 C-23.2843,0 -30,-6.71573 -30,-15 C-30,-23.2843 -23.2843,-30 -15,-30 C-6.71573,-30 0,-23.2843 0,-15 "/>
<path vector-effect="non-scaling-stroke" fill-rule="evenodd" d="M-5,-15 C-5,-9.47715 -9.47715,-5 -15,-5 C-20.5228,-5 -25,-9.47715 -25,-15 C-25,-20.5228 -20.5228,-25 -15,-25 C-9.47715,-25 -5,-20.5228 -5,-15 "/>
<path vector-effect="non-scaling-stroke" fill-rule="evenodd" d="M-10,-15 C-10,-12.2386 -12.2386,-10 -15,-10 C-17.7614,-10 -20,-12.2386 -20,-15 C-20,-17.7614 -17.7614,-20 -15,-20 C-12.2386,-20 -10,-17.7614 -10,-15 "/>
</g>

<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,319,236)"
font-family="MS Shell Dlg 2" font-size="8.25" font-weight="400" font-style="normal"
>
</g>

<g fill="none" stroke="#000000" stroke-opacity="1" stroke-width="1" stroke-linecap="square" stroke-linejoin="bevel" transform="matrix(1,0,0,1,0,0)"
font-family="MS Shell Dlg 2" font-size="8.25" font-weight="400" font-style="normal"
>
</g>
</g>
</svg>
Сразу бросается в глаза отличие
<path vector-effect="non-scaling-stroke">
У вас там просто none
 
Не подскажите как пропарсить данный файл???
Заранее спасибо)).
 
 
 

Там в коде  у меня есть:

gNode.firstChildElement("rect"); 
Вам же стоит использовать просто path в данном случае.
gNode.firstChildElement("path"); 
Аттрибуты забирать аналогично, как они забираются из rect в моём коде. Делайте по аналогии, при возникновении некоторых проблем используйте qDebug() что понять, что идёт не так.
F

Для формирования задал объект QGraphiscPathItem

QGraphicsPathItem *rect = new QGraphicsPathItem();
rect->setFlag(QGraphicsRectItem::ItemIsMovable);
QDomElement gElement = gNode.toElement();
rect->setPath();
у тега path есть атрибут "d". Пытаюсь считать этот атрибут с помощью setPath, который требует параметры типа QPainterPath
Как передать методу данные параметры в требуемом типе и правильно ли я сделал воспользовавшись QGraphicsPathItem?
F

А кажется понял, я должен из атрибутов path сформировать заново элементы Ellipse, просто нужно правильно подобрать эти атрибуты.....


Ну да. Там должны быть координаты, их нужно пропарсить и по ним построить Path, либо преобразовать их в эллипс. Вообще, кое-что кривовато переносится в SVG местами.

c

How can I open another polygon type such as circle(ellipse) ?

The principle will be similar. You need to research content of svg file and make parsing of needed tag.

For Example:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="210mm"
   height="297mm"
   viewBox="0 0 744.09448819 1052.3622047"
   id="svg2"
   version="1.1"
   inkscape:version="0.91 r13725"
   sodipodi:docname="circle.svg">
  <defs
     id="defs4" />
  <sodipodi:namedview
     id="base"
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1.0"
     inkscape:pageopacity="0.0"
     inkscape:pageshadow="2"
     inkscape:zoom="0.49497475"
     inkscape:cx="405.75379"
     inkscape:cy="583.59967"
     inkscape:document-units="px"
     inkscape:current-layer="layer1"
     showgrid="false"
     inkscape:window-width="1366"
     inkscape:window-height="703"
     inkscape:window-x="0"
     inkscape:window-y="0"
     inkscape:window-maximized="1" />
  <metadata
     id="metadata7">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:label="Layer 1"
     inkscape:groupmode="layer"
     id="layer1">
    <rect
       style="fill:#0000ff;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
       id="rect3336"
       width="222.23357"
       height="131.31982"
       x="125.25892"
       y="219.99651" />
    <ellipse
       style="fill:#ff0000;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
       id="path3338"
       cx="287.89346"
       cy="466.47372"
       rx="89.90358"
       ry="74.751289" />
  </g>
</svg>
In this code You can try to get ellipse.
Method for parsing will be same.
QList<QGraphicsEllipseItem*> SvgReader::getEllipses(const QString filename)
{
    QList<QGraphicsEllipseItem *> ellipsesList;

    QDomDocument doc;
    QFile file(filename);

    if (!file.open(QIODevice::ReadOnly) || !doc.setContent(&file))
        return ellipsesList;

    QDomNodeList gList = doc.elementsByTagName("g");
    for (int i = 0; i < gList.size(); i++) {
        QDomNode gNode = gList.item(i);
        QDomElement ellipseElement = gNode.firstChildElement("ellipse");

        if (ellipseElement.isNull()){
            continue;
        } else {
            QGraphicsEllipseItem *ellipseItem = new QGraphicsEllipseItem();
            ellipseItem->setFlag(QGraphicsItem::ItemIsMovable);

            QDomElement gElement = gNode.toElement();
            ellipseItem->setRect(ellipseElement.attribute("cx").toFloat() - ellipseElement.attribute("rx").toFloat(),
                                 ellipseElement.attribute("cy").toFloat() - ellipseElement.attribute("ry").toFloat(),
                                 ellipseElement.attribute("rx").toFloat() * 2,
                                 ellipseElement.attribute("ry").toFloat() * 2);

            QColor fillColor(ellipseElement.attribute("style").split(";").at(0).split(":").at(1));
            ellipseItem->setBrush(QBrush(fillColor));

            QColor strokeColor(gElement.attribute("stroke", "#000000"));
            strokeColor.setAlphaF(gElement.attribute("stroke-opacity").toFloat());

            ellipseItem->setPen(QPen(strokeColor,gElement.attribute("stroke-width", "0").toInt()));
            ellipsesList.append(ellipseItem);
        }
    }
    file.close();
    return ellipsesList;
}
c

Thank You sir, So how can I change this method


QRectF SvgReader::getSizes(const QString filename)
{
    QDomDocument doc;       // initialize the stack object QDomDocument
    QFile file(filename);   // Open your SVG-file
    // If it is not opened, or have failed to transmit the contents in QDocDocument
    if (!file.open(QIODevice::ReadOnly) || !doc.setContent(&file))
        return QRectF(0,0,200,200); // the return values for the default scene
 
    /* Then pick up a list of items with the tag svg.
      * If a list of elements is not empty,
      * take the size of the graphic scenes.
     * */
    QDomNodeList list = doc.elementsByTagName("svg");
    if(list.length() > 0) {
        QDomElement svgElement = list.item(0).toElement();
        QStringList parameters = svgElement.attribute("viewBox").split(" ");
        return QRectF(parameters.at(0).toInt(),
                      parameters.at(1).toInt(),
                      parameters.at(2).toInt(),
                      parameters.at(3).toInt());
    }
    return QRectF(0,0,200,200);
}

which class I need to use instead of QRectF

For what You want to use another class instead of QRectF?

This static method return just size of QGraphicsScene from svg file. QRectF should be enough.
c

Sir,I tried your code for open ellipse item.but my program not open ellipse item.what should I need to do?


here is my code :

readsvg.cpp

QList<QGraphicsEllipseItem*> ReadSVG::getEllipses(const QString filename)
{
    QList<QGraphicsEllipseItem *> ellipsesList;

    QDomDocument doc;
    QFile file(filename);

    if (!file.open(QIODevice::ReadOnly) || !doc.setContent(&file))
        return ellipsesList;

    QDomNodeList gList = doc.elementsByTagName("g");
    for (int i = 0; i < gList.size(); i++) {
        QDomNode gNode = gList.item(i);
        QDomElement ellipseElement = gNode.firstChildElement("ellipse");

        if (ellipseElement.isNull()){
            continue;
        } else {
            QGraphicsEllipseItem *ellipseItem = new QGraphicsEllipseItem();
            ellipseItem->setFlag(QGraphicsItem::ItemIsMovable);

            QDomElement gElement = gNode.toElement();
            ellipseItem->setRect(ellipseElement.attribute("cx").toFloat() - ellipseElement.attribute("rx").toFloat(),
                                 ellipseElement.attribute("cy").toFloat() - ellipseElement.attribute("ry").toFloat(),
                                 ellipseElement.attribute("rx").toFloat() * 2,
                                 ellipseElement.attribute("ry").toFloat() * 2);

            QColor fillColor(ellipseElement.attribute("style").split(";").at(0).split(":").at(1));
            ellipseItem->setBrush(QBrush(fillColor));

            QColor strokeColor(gElement.attribute("stroke", "#000000"));
            strokeColor.setAlphaF(gElement.attribute("stroke-opacity").toFloat());

            ellipseItem->setPen(QPen(strokeColor,gElement.attribute("stroke-width", "0").toInt()));
            ellipsesList.append(ellipseItem);
        }
    }
    file.close();
    return ellipsesList;
}


QRectF ReadSVG::getSizes(const QString filename)
{
    QDomDocument doc;       // initialize the QDomDocument object on the stack
    QFile file(filename);   // Open our SVG file
    // If it did not open or could not transfer content to QDocDocument
    if (!file.open(QIODevice::ReadOnly) || !doc.setContent(&file))
        return QRectF(0,0,200,200); // then return the values ​​for the default scene
    QDomNodeList list = doc.elementsByTagName("svg");
    if(list.length() > 0) {
        QDomElement svgElement = list.item(0).toElement();
        QStringList parameters = svgElement.attribute("viewBox").split(" ");
        return QRectF(parameters.at(0).toInt(),
                      parameters.at(1).toInt(),
                      parameters.at(2).toInt(),
                      parameters.at(3).toInt());
    }
    return QRectF(0,0,200,200);
}
widget.cpp

void Widget::on_btnOpen_clicked()
{
    QString newPath = QFileDialog::getOpenFileName(this, trUtf8("Open SVG"),
                                                   path, tr("SVG files (*.svg)"));
    if (newPath.isEmpty())
        return;

    path = newPath;
    scene->clear();

    scene->setSceneRect(ReadSVG::getSizes(path));
    foreach (QGraphicsEllipseItem *itemE, ReadSVG::getEllipses(path)) {
        QGraphicsEllipseItem *elips = itemE;
        scene->addItem(elips);
    }


}

I think You have another version of SVG file. First, need to see content of SVG file. It is simple XML-format, therefore just need to research content.

Do You want just open SVG file or make special graphics object (from QGraphicsItem etc.), which you will change it on QGraphicsScene?
If You want just open SVG file without changes, You can use QSvgWidget for it.
Otherwise, I suggest You create topic on forum of this site , where You can attach svg file, and we continue discuss about this issue.
c

Sir I post is as a topic,please help me to solve this problem

Скажите пожалуйста, как пользоваться QSvgRenderer и загружать целиком в QGraphicsScene ? Если делаю так, то получаю белый экран:

    QString newPath = QFileDialog::getOpenFileName(this, trUtf8("Open SVG"),
                                                   path, tr("SVG files (*.svg)"));

    if (newPath.isEmpty())
            return;

        path = newPath;
        scene->clear();

        QSvgRenderer w;
        w.load(path);
        scene->setSceneRect(w.viewBoxF());

А если делаю с помощью вашего класса, то тоже получаю белый экрак. Рисую на сцене так: Qt/C++ - Урок 021. Рисование мышью в Qt

Вот так целиком добавлять можно

    QString newPath = QFileDialog::getOpenFileName(this, trUtf8("Open SVG"),
                                                   path, tr("SVG files (*.svg)"));

    if (newPath.isEmpty())
            return;

        path = newPath;
        scene->clear();

        //QSvgRenderer myRenderer;
        QSvgRenderer* myRenderer = new QSvgRenderer();
        myRenderer->load(path);
        //scene->setSceneRect(myRenderer->viewBoxF());
        QGraphicsSvgItem *myItem = new QGraphicsSvgItem();
        myItem->setSharedRenderer(myRenderer);
        scene->addItem(myItem);

Comments

Only authorized users can post comments.
Please, Log in or Sign up
How to become an author?

Contribute to the evolution of the EVILEG community.

Learn how to become a site author.

Learn it
Donate

Good day, Dear Users!!!

I am Evgenii Legotckoi, developer of EVILEG. And it is my hobby project, which helps to learn programming another programmers and developers

If the site helped you, and you want also support the development of the site, than you can donate by following ways

PayPalYandex.Money
Timeweb

Let me recommend you the excellent hosting on which EVILEG is located.

For many years, Timeweb has been proving his stability.

For projects on Django I recommend VDS hosting

View Hosting Timeweb
MN
May 25, 2020, 11:33 a.m.
Mitja Nagibin

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:50points,
  • Rating points-4
f
May 25, 2020, 5:05 a.m.
falcon

C++ - Test 001. The first program and data types

  • Result:66points,
  • Rating points-1
jm
May 25, 2020, 3:30 a.m.
just maks

C ++ - Test 004. Pointers, Arrays and Loops

  • Result:80points,
  • Rating points4
Last comments
May 26, 2020, 6:51 a.m.
Evgenij Legotskoj

Qt/C++ - Lesson 004. QSqlTableModel – How to present the table from database?

У вас база данных не открылась Исправьте путь к базе данных на свой корректный в следующих методах void DataBase::connectToDataBase() bool DataBase::openDataBase()
T1
T1
May 26, 2020, 6:22 a.m.
Tima 1

Qt/C++ - Lesson 004. QSqlTableModel – How to present the table from database?

полностью повторил структору проекта. В форму дабавил tableView. Но при запуске получаю форму только с пустым tableView. Можете подсказать в чем пробелма?
May 26, 2020, 6:02 a.m.
Evgenij Legotskoj

Qt/C++ - Lesson 004. QSqlTableModel – How to present the table from database?

Потому что это файл который нужно создать, а не библиотека. В статье есть содержание этого файла. Добавляйте в проект. Копируйте содержимое из статьи.
T1
May 26, 2020, 6 a.m.
Tima 1

Qt/C++ - Lesson 004. QSqlTableModel – How to present the table from database?

не удается подключиить библеотеку include "database.h" выдает ошибку. Можете помочь?
Now discuss on the forum
May 26, 2020, 8:26 a.m.
Vladislav Melenchuk

Templatetags из GenericForeign

Всем привет, не подскажете как сделать templatetags на вывод последних комментариев в сайдбаре для постов? Именно для постов. @register.simple_tag()def get_last_comments(): return Commen…
May 26, 2020, 5:16 a.m.
BlinCT

Отсутствие драйвера SQLite в пакете Qt 4 на Linux

Вот честно непонимаю почему до сих пор используют qt4, там же столько всего отсутствует, много фишек и возможностей нету там. То есть используя такое старье приходится много писать самому а не и…
DK
May 26, 2020, 2:24 a.m.
Dzhon Kofi

Disable autoscroll

такие естественные решения все перепробовал. Получилось вчера так: const int maximumScroll = ui->_samples->verticalScrollBar()->maximum();const int sliderPos = ui->_samp…
May 26, 2020, 12:43 a.m.
Ruslan Polupan

Посоветуйте новичку (базы данных и Qt, что учить)

Без БД сейчас практически никуда. Поэтому SQL надо знать. SQLite самы простой вариант, но имхо лучще начать с бд клиент-сервер. Настроить сервер. Подключаться клиентом. Просто это помогает понят…
EJ
May 25, 2020, 2:42 p.m.
Esteban José María

Компиляция пустого проекта Qt Android

qt 5.12.8 BUILD SUCCESSFUL in 42s 28 actionable tasks: 28 executed Android package built successfully in 68.251 ms. Ну, буду разбираться по-тихоньку. :)
About
Services
© EVILEG 2015-2020
Recommend hosting TIMEWEB