Evgenii Legotckoi
Evgenii LegotckoiApril 1, 2016, 12:51 p.m.

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

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.

Do you like it? Share on social networks!

F
  • Aug. 12, 2017, 8: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
 
Не подскажите как пропарсить данный файл???
Заранее спасибо)).
 
 
 
Evgenii Legotckoi
  • Aug. 13, 2017, 3:56 a.m.

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

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

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

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

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


Evgenii Legotckoi
  • Aug. 15, 2017, 5:04 a.m.

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

c
  • Oct. 15, 2017, 10:27 a.m.

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

Evgenii Legotckoi
  • Oct. 15, 2017, 2:52 p.m.

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
  • Oct. 16, 2017, 9:53 a.m.

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
Evgenii Legotckoi
  • Oct. 16, 2017, 11:25 a.m.

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
  • Oct. 16, 2017, 4:09 p.m.

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


}
Evgenii Legotckoi
  • Oct. 17, 2017, 1:44 a.m.

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
  • Oct. 17, 2017, 5:29 a.m.

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

Михаиллл
  • June 10, 2019, 11:43 a.m.
  • (edited)

Скажите пожалуйста, как пользоваться 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

Михаиллл
  • June 11, 2019, 2:41 a.m.

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

    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
AD

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

  • Result:50points,
  • Rating points-4
m

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

  • Result:80points,
  • Rating points4
m

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

  • Result:20points,
  • Rating points-10
Last comments
Evgenii Legotckoi
Evgenii LegotckoiNov. 1, 2024, 12:37 a.m.
Django - Lesson 064. How to write a Python Markdown extension Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZEOct. 19, 2024, 6:19 p.m.
Fb3 file reader on Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь МаксимовOct. 5, 2024, 5:51 p.m.
Django - Lesson 064. How to write a Python Markdown extension Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas5July 5, 2024, 9:02 p.m.
QML - Lesson 016. SQLite database and the working with it in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssrFeb. 9, 2024, 5:43 a.m.
Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Now discuss on the forum
Evgenii Legotckoi
Evgenii LegotckoiJune 25, 2024, 1:11 a.m.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey1Nov. 15, 2024, 5:04 p.m.
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProjectJune 4, 2022, 1:49 p.m.
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9AnonimOct. 25, 2024, 7:10 p.m.
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Follow us in social networks