[SOLVED] SVG visiblity of elements



  • Hi,

    I think I've an understanding problem of the complete QtSvg Module.
    I'm trying to disable/hide some groups/layers of my SVG file, but unfortunately QtSvg isn't doing what I want :-)

    I created a dialog with a QSvgWidget, I'm loading a complete SVG file to that widget.
    Next I try to influence the renderer of the widget, accessing some elements of the file and set the visiblity to false.
    But the elements are still visible.

    @
    ui->svgWidget->load(QString(":/images/state.svg"));
    QSvgRenderer *svgRenderer = ui->svgWidget->renderer();

    if(svgRenderer->elementExists("layer3"))
    {
        QGraphicsSvgItem *graphicItem = new QGraphicsSvgItem();
        graphicItem->setSharedRenderer(svgRenderer);
        graphicItem->setElementId("layer3");
        graphicItem->hide();
        graphicItem->setVisible(false);
    }
    

    @

    What am I doing wrong?
    Is it possible with the framework to achieve my goal?
    Do I have to do it in another way?

    I also tried to get the same results when using the QSvgRenderer directly and building a graphics scene with the single elements.
    But in this case all the original coordinates of the single elements are getting lost and all elements are placed at pos 0,0.

    @
    QSvgRenderer *svgRenderer = new QSvgRenderer(QString(":/images/test.svg"));
    QGraphicsScene *graphicsScene = ui->graphicsView->scene();

    if(svgRenderer->elementExists("LINE_578_"))
    {
        QGraphicsSvgItem *graphicItem = new QGraphicsSvgItem();
        graphicItem->setSharedRenderer(svgRenderer);
        graphicItem->setElementId("LINE_578_");
        graphicItem->setScale(1.0);
        graphicsScene->addItem(graphicItem);
    }
    
    if(svgRenderer->elementExists("LINE_57_"))
    {
        QGraphicsSvgItem *graphicItem = new QGraphicsSvgItem();
        graphicItem->setSharedRenderer(svgRenderer);
        graphicItem->setElementId("LINE_57_");
        graphicItem->setScale(1.0);
        graphicsScene->addItem(graphicItem);
    }
    

    @

    Any help or hint is welcome?

    Thanks a lot!!!



  • QSvgWidget renders the whole svg file. Instead, you should subclass QWidget. Then override the:
    @
    void QWidget::paintEvent ( QPaintEvent * event );
    @
    ... in your custom QWidget and using the QSvgRenderer:

    @
    QSvgRenderer *svgRenderer = new QSvgRenderer(QString(":/images/test.svg"));
    @

    ... render the elements in the svg file one by one using:
    @
    void QSvgRenderer::render ( QPainter * painter, const QString & elementId, const QRectF & bounds = QRectF() );
    @

    This way you could filter out the unnecessary elements.



  • Thanks for the hint, unfortunately the results are the same or similar using the QSvgWidget.

    @
    void SvgWidget::paintEvent ( QPaintEvent * event )
    {
    QPainter painter(this);
    QRectF boundingRect = QRectF(0,0,640,480);
    QSvgRenderer *svgRenderer = new QSvgRenderer(QString(":/images/state.svg"));
    //svgRenderer->render(&painter);
    svgRenderer->render(&painter,QString("layer1"),boundingRect);
    svgRenderer->render(&painter,QString("layer3"),boundingRect);
    event->accept();
    }
    @

    I created my own widget, with an overwritten paintEvent(), but when rendering the single elements, the original positions are getting lost.
    First it is rendering layer1 and overwriting it with layer3.

    Any other ideas?



  • Found the answer myself, I've overseen the
    @
    QRectF QSvgRenderer::boundsOnElement ( const QString & id ) const
    @
    method.

    The code:
    @
    void SvgWidget::paintEvent ( QPaintEvent * event )
    {
    QPainter painter(this);
    QSvgRenderer *svgRenderer = new QSvgRenderer(QString(":/images/state.svg"));
    QRectF boundingRect = svgRenderer->boundsOnElement(QString("layer1"));
    svgRenderer->render(&painter,QString("layer1"),boundingRect);
    boundingRect = svgRenderer->boundsOnElement(QString("layer3"));
    svgRenderer->render(&painter,QString("layer3"),boundingRect);
    event->accept();
    }
    @

    is now doing all what I want.



  • I'm also trying to show one element of an svg file but I don't understand how to.
    The examples I've found explain how to show one file, not one single element.
    Is there a full documentation somewhere ?
    Thanks in advance.

    PS: @AppsPat, why do you create a new QSvgRenderer at every paint event ? it's really expensive !!! (my svg file is 2 MB big).



  • Ok, found the problem: I was just passing a wrong id :-)

    this code shows a single element of a svg file:

    @#include <QtGui/QApplication>
    #include <QtSvg>

    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);
    QGraphicsScene scene;
    QGraphicsView view(&scene);

    QSvgRenderer* svgRend = new QSvgRenderer(QLatin1String(":/images/main.svg"));
    QGraphicsSvgItem* svg = new QGraphicsSvgItem();

    if(svgRend->elementExists("g6084"))
    {
    svg->setSharedRenderer(svgRend);
    svg->setElementId(QLatin1String("g6084"));
    }

    scene.addItem(svg);

    view.show();

    return app.exec();
    }
    @


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.