Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to change the color of an svg with QGraphicsItem/QGraphicsSvgItem?



  • Hello,

    how do I change the Color of my QGraphicsSvgItem?

    i have different svg-items which are drawn with a black color. In one case i want my svg on a black background and the svg itself should be drawn white. how can i achieve this codewise?

    here is my function inside the mainwindow.cpp to draw the images inside a QGraphicsView.

    void MainWindow::updateSvgInView(QString svgId, QGraphicsView* viewItem, QGraphicsSvgItem& svgItem, QColor backColor) {
        m_DomElement = getDomElement(svgId);
        m_ChildId = getChildId(m_DomElement);
        svgItem.setElementId(m_ChildId);
        auto yPos = viewItem->width()/2 - svgItem.boundingRect().width()/2;
        auto xPos = viewItem->height()/2 - svgItem.boundingRect().height()/2;
        svgItem.setPos(xPos, yPos);
        viewItem->fitInView(&svgItem, Qt::AspectRatioMode::KeepAspectRatio);
        viewItem->setBackgroundBrush(QBrush(backColor));
        if (backColor == QColor(Qt::black)) {
            // want to draw svg white! but how? :/
        }
    }
    




  • is there no other way then manipulating the QDomElement? I already found those solutions but was wondering if there is another way. like that i could just change the fill property in my <path> inside my svg



  • @gewitt
    I wouldn't recommend it, but if you mean alter the actual path statement then https://stackoverflow.com/a/15130097/489865 in one of those links reminds you that you can always pursue:

    Since the SVG format is XML based, and XML is just ASCII text... you could load the SVG resource in to a QString, call QString::replace(""#000000"", ""#ffffff""), and then pass the modified QString in to your QSVGRenderer

    On a different note, I thought some of those answers said for your particular case it could be done via QGraphicsColorizeEffect.



  • i tried it with the QGraphicsColorizeEffect but it doesnt change anything somehow...

      if (backColor == QColor(Qt::black)) {
            qDebug() << "inside black";
            QGraphicsColorizeEffect *effect = new QGraphicsColorizeEffect();
            effect->setColor(Qt::white);
            viewItem->setGraphicsEffect(effect);
        }
        viewItem->fitInView(&svgItem, Qt::AspectRatioMode::KeepAspectRatio);
        viewItem->setBackgroundBrush(QBrush(backColor));
    
    


  • Hi,
    it's me again.

    I did try to manipulate the svg XML itself.

    Now the strange thing is: some elements are now rendered correctly but some are not....

    here is my Code:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QDomDocument>
    #include <QFile>
    #include <QDebug>
    #include <QPaintEngine>
    #include "function.h"
    #include <QGraphicsEffect>
    
    QDomElement MainWindow::getChildElement(QDomElement symbolElement) {
        auto childList = symbolElement.childNodes();
        if (childList.size() == 1) {
            qDebug() << qPrintable(childList.item(0).toElement().attributeNode("id").value() + "Found") << endl;
            return childList.item(0).toElement();
        }else {
            return childList.item(0).toElement();
            qDebug() << qPrintable(childList.item(0).toElement().attributeNode("id").value() + "Found") << endl;
        }
        return QDomElement();
    
    }
    
    QDomElement MainWindow::getDomElement(QString elementID) {
        auto docElem = doc.documentElement();
    
        auto n = docElem.firstChild();
        while(!n.isNull()) {
            auto e = n.toElement(); // try to convert the node to an element.
            if(!e.isNull()) {
               auto id = e.attributeNode("id");
               if (id.value().compare(elementID) == 0){
                   qDebug() << qPrintable(id.value() + "Found");
                   return e;
               }
            }
            n = n.nextSibling();
        }
        return QDomElement();
    }
    
    void MainWindow::updateSvgInView(QString svgId, QGraphicsView* viewItem, QGraphicsSvgItem& svgItem, QColor backColor, QColor fill) {
        auto m_DomElement = getDomElement(svgId);
        auto m_ChildElement = getChildElement(m_DomElement);
        qDebug() << fill.name() << endl;
        m_ChildElement.setAttribute("fill", fill.name().toUpper());
        renderer.load(doc.toByteArray());
        svgItem.setElementId(m_ChildElement.attributeNode("id").value());
        auto yPos = viewItem->width()/2 - svgItem.boundingRect().width()/2;
        auto xPos = viewItem->height()/2 - svgItem.boundingRect().height()/2;
        svgItem.setPos(xPos, yPos);
        viewItem->fitInView(&svgItem, Qt::AspectRatioMode::KeepAspectRatio);
        viewItem->setBackgroundBrush(QBrush(backColor));
    }
    
    MainWindow::MainWindow(CanMessageHandler& handler, MainController& mCtrl, QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
        , file(QStringLiteral(":/assets/Icons_original.svg"))
        , doc(QStringLiteral(":/assets/Icons_original.svg"))
        , _handler(handler)
        , _mController(mCtrl)
        , renderer(QStringLiteral(":/assets/Icons_original.svg"))
    
    {
        ui->setupUi(this);
    
        _handler.Register([this] () {
            UpdateComponents();
        });
    
        if (!file.open(QIODevice::ReadOnly))
            return;
        if (!doc.setContent(&file)) {
            file.close();
            return;
        }
        file.close();
    
    
    
    
        f1.setSharedRenderer(&renderer);
        f2.setSharedRenderer(&renderer);
        f3.setSharedRenderer(&renderer);
        f4.setSharedRenderer(&renderer);
        f5.setSharedRenderer(&renderer);
        f6.setSharedRenderer(&renderer);
    
    
        scene1.addItem(&f1);
        scene2.addItem(&f2);
        scene3.addItem(&f3);
        scene4.addItem(&f4);
        scene5.addItem(&f5);
        scene6.addItem(&f6);
    
        scene1.setSceneRect(0,0,90,90);
        scene2.setSceneRect(0,0,90,90);
        scene3.setSceneRect(0,0,90,90);
        scene4.setSceneRect(0,0,90,90);
        scene5.setSceneRect(0,0,90,90);
        scene6.setSceneRect(0,0,90,90);
    
        ui->function1->setScene(&scene1);
        ui->function2->setScene(&scene2);
        ui->function3->setScene(&scene3);
        ui->function4->setScene(&scene4);
        ui->function5->setScene(&scene5);
        ui->function6->setScene(&scene6);
    
        ui->function1->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->function2->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->function3->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->function4->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->function5->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->function6->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->function1->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->function2->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->function3->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->function4->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->function5->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->function6->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        ui->function1->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
        ui->function2->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
        ui->function3->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
        ui->function4->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
        ui->function5->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
        ui->function6->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
        ui->function1->setBaseSize(90, 90);
        ui->function2->setBaseSize(90, 90);
        ui->function3->setBaseSize(90, 90);
        ui->function4->setBaseSize(90, 90);
        ui->function5->setBaseSize(90, 90);
        ui->function6->setBaseSize(90, 90);
    
    
    }
    
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::UpdateComponents() {
    
        QMetaObject::invokeMethod(qApp, [this]{
    
            auto funcButtonSymbols = _handler.GetFuncButtonSymbols();
    
            updateSvgInView(_mController.GetModeSvgById(funcButtonSymbols.f1Symbol), ui->function1, f1, _mController.GetBackColorByModeId(funcButtonSymbols.f1Symbol), _mController.GetFillColorByModeId(funcButtonSymbols.f1Symbol));
            updateSvgInView(_mController.GetModeSvgById(funcButtonSymbols.f2Symbol), ui->function2, f2, _mController.GetBackColorByModeId(funcButtonSymbols.f2Symbol), _mController.GetFillColorByModeId(funcButtonSymbols.f2Symbol));
            updateSvgInView(_mController.GetModeSvgById(funcButtonSymbols.f3Symbol), ui->function3, f3, _mController.GetBackColorByModeId(funcButtonSymbols.f3Symbol), _mController.GetFillColorByModeId(funcButtonSymbols.f3Symbol));
            updateSvgInView(_mController.GetModeSvgById(funcButtonSymbols.f4Symbol), ui->function4, f4, _mController.GetBackColorByModeId(funcButtonSymbols.f4Symbol), _mController.GetFillColorByModeId(funcButtonSymbols.f4Symbol));
            updateSvgInView(_mController.GetModeSvgById(funcButtonSymbols.f5Symbol), ui->function5, f5, _mController.GetBackColorByModeId(funcButtonSymbols.f5Symbol), _mController.GetFillColorByModeId(funcButtonSymbols.f5Symbol));
            updateSvgInView(_mController.GetModeSvgById(funcButtonSymbols.f6Symbol), ui->function6, f6, _mController.GetBackColorByModeId(funcButtonSymbols.f6Symbol), _mController.GetFillColorByModeId(funcButtonSymbols.f6Symbol));
        });
    }
    
    

    It is a realy strange behavior....

    halp plox :)


  • Lifetime Qt Champion

    Hi
    I would save the modified SVG to file and open it in Inkscape and see if that will render it ok.



  • well i fixed the problem....the svg i had had multiple entries with the same id. though it dindt select the correct one when rendering.

    anyways thx for the reply :D


Log in to reply