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

QSvgWidget, how to update?



  • I am creating a QSvgWidget with the content:

    <svg id="svg" xmlns="http://www.w3.org/2000/svg">
    	<g id="led1" transform="translate(10,10) scale(.1)">
    		<linearGradient id="led1.lg1" x1="0" y1="0" x2="y1" y2="0">
    			<stop id="led1.lg1s1" stop-color="#bfbfbf" offset="0"/>
    			<stop id="led1.lg1s2" stop-color="#404040" offset="1"/>
    		</linearGradient>
    		<linearGradient id="led1.lg2" x1="0" y1="0" x2="1" y2="1" spreadMethod="pad">
    			<stop id="led1.lg2s1" stop-color="#dd0000" stop-opacity="0.992188" offset="0"/>
    			<stop id="led1.lg2s2" stop-color="#820101" stop-opacity="0.988281" offset="1"/>
    		</linearGradient>
    		<linearGradient id="led1.lg3" x1="0" y1="0" x2="1" y2="1" spreadMethod="pad">
    			<stop id="led1.lg3s1" stop-color="#ffffff" stop-opacity="0.996094" offset="0"/>
    			<stop id="led1.lg3s2" stop-color="#d30606" stop-opacity="0.984375" offset="0.703125"/>
    		</linearGradient>
    		<circle id="c1" fill="url(#led1.lg1)" stroke-width="17.5" stroke-linecap="round" 
    			cx="320" cy="240" r="196.125" 
    			fill-opacity="0.77" transform="rotate(90, 320, 240)"/>
    		<circle id="c2" fill="url(#led1.lg1)" stroke-width="17.5" stroke-linecap="round" 
    			fill-opacity="0.64" cx="319.252837" cy="239.999045" 
    			r="160"/>
    		<circle id="c3" fill="url(#led1.lg2)" stroke-width="17.5" 
    			stroke-linecap="round" cx="320.000535" cy="240.001698" r="150"/>
    		<ellipse id="e1" fill="url(#led1.lg3)" stroke-width="17.5" 
    			 stroke-linecap="round" cx="250.179609" cy="170.124194" 
    			 rx="75.675959" ry="44.402987" 
    			 transform="rotate(-47.7626, 250.18, 170.125)"/>
    	</g>
    </svg>
    

    I read in the XML and translate it into a QStringList of attributes for each node. I have a function that processes these nodes and translates the content into a QByteArray:

    QByteArray clsXMLnode::bytArrDocument(clsXMLnode* pobjNode) {
        QByteArray bytArrDoc;
    
        if ( pobjNode == nullptr ) {
        //Start off with the document header
            bytArrDoc.append(QString("<?xml version='1.0'?>").toLocal8Bit());
        //No node passed so use 'this'
            pobjNode = this;
        }
        QString strNode(clsXMLnode::msccTokenOpen), strName(pobjNode->strGetNodeName());
        strNode += strName;
    
        foreach( const prAttr &attrPr, pobjNode->mlstAttrPrs ) {
            strNode += clsXMLnode::msccSpace + attrPr.first
                     + clsXMLnode::msccEquals + clsXMLnode::msccQuoteSingle
                     + attrPr.second + clsXMLnode::msccQuoteSingle;
        }
        if ( pobjNode->blnHasChildren() == true ) {
            strNode += clsXMLnode::msccTokenClose;
            bytArrDoc.append(strNode.toLocal8Bit());        
    
            foreach( clsXMLnode* pobjChild, pobjNode->mlstChildren ) {
                bytArrDoc.append(bytArrDocument(pobjChild));
            }
            strNode = clsXMLnode::mscszXMLcloseToken2 + strName + clsXMLnode::msccTokenClose;
            bytArrDoc.append(strNode.toLocal8Bit());
        } else {
            strNode += clsXMLnode::mscszXMLcloseToken;
            bytArrDoc.append(strNode.toLocal8Bit());
        }
        return bytArrDoc;
    }
    

    I then use this to create an instance of QSvgWidget:

    QByteArray bytArrSVG = pobjNode->bytArrDocument();
    QSvgWidget* pobjSVGwidget = new QSvgWidget(pobjParWidget);
    pobjNode->setWidget(pobjSVGwidget);
    pobjSVGwidget->load(bytArrSVG);
    pobjSVGwidget->show();
    

    So far so good and this results in the SVG being displayed. What I want to do is find out how I can change content in the byte array and get the SVG widget to show the changes, this is what I've tried:

    QSvgWidget* pobjSVGwidget = static_cast<QSvgWidget*>(pobjGUIparent->mpobjWidget);
    
    if ( pobjSVGwidget != nullptr ) {
        QByteArray bytArrSVG = bytArrDocument();
        pobjSVGwidget->load(bytArrSVG);
        pobjSVGwidget->show();
    }
    

    When I change an attribute in any SVG node the content of the byte array will contain the new settings, but calling load and show again does not cause the widget to reflect the changes. What haven't I done?



  • I think I found the problem, when I was re-rendering i wasn't using the parent node.



  • I think I found the problem, when I was re-rendering i wasn't using the parent node.


Log in to reply