How to add SVG widget to MainWindow?
-
I have a class derived from QMainWindow, so far I'm adding widgets to the window by simply adding the window as the parent of the widget. I haven't had to implement a paintEvent yet.
How can I use the same technique to render the SVG in the window? This is what I have so far:
- I read the SVG in as part of the XML, the SVG is:
<svg id="svgLED" width="640" height="480" xmlns="http://www.w3.org/2000/svg"> <defs> <linearGradient id="svg_6" x1="0" y1="0" x2="1" y2="0"> <stop stop-color="#bfbfbf" offset="0"/> <stop stop-color="#404040" offset="1"/> </linearGradient> <linearGradient id="svg_11" x1="0" y1="0" x2="1" y2="1" spreadMethod="pad"> <stop stop-color="#dd0000" stop-opacity="0.992188" offset="0"/> <stop stop-color="#820101" stop-opacity="0.988281" offset="1"/> </linearGradient> <linearGradient id="svg_14" x1="0" y1="0" x2="1" y2="1" spreadMethod="pad"> <stop stop-color="#ffffff" stop-opacity="0.996094" offset="0"/> <stop stop-color="#d30606" stop-opacity="0.984375" offset="0.703125"/> </linearGradient> </defs> <g> <circle id="svgLED@[id]_c1" fill="url(#svg_6)" stroke-width="17.5" stroke-linecap="round" cx="320" cy="240" r="196.125" id="svg_3" fill-opacity="0.77" transform="rotate(90, 320, 240)"/> <circle id="svgLED@[id]_c2" fill="url(#svg_6)" stroke-width="17.5" stroke-linecap="round" fill-opacity="0.64" cx="319.252837" cy="239.999045" r="160" id="svg_7"/> <circle id="svgLED@[id]_c3" fill="url(#svg_11)" stroke-width="17.5" stroke-linecap="round" cx="320.000535" cy="240.001698" r="150"/> <ellipse id="svgLED@[id]_e1" fill="url(#svg_14)" stroke-width="17.5" stroke-linecap="round" cx="250.179609" cy="170.124194" rx="75.675959" ry="44.402987" id="svg_20" transform="rotate(-47.7626, 250.18, 170.125)"/> </g> </svg>
Once this is in my application along with the rest of the XML which isn't shown above I then use the following function to recreate a QByteArray containing only the SVG:
/** * @brief clsXMLnode::bytArrDocument * @param pobjNode : Optional, default is nullptr * @return Byte Array containing document */ 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; }
This is what I do so far with the SVG:
if ( pobjNode->strGetNodeName().compare(clsXMLnode::mscszNodeSVGroot) == 0 ) { QString strID = pobjNode->strGetAttribute(clsXMLnode::mscszAttrID); if ( strID.isEmpty() != true ) { clsXMLnode* pobjWinNode = pobjNode->pobjGetWindow(); if ( pobjWinNode != nullptr ) { QWidget* pobjPWidget = pobjWinNode->pobjGetWidget(); if ( pobjPWidget != nullptr ) { QByteArray bytArrSVG = pobjNode->bytArrDocument(); pobjNode->mpobjSVGrender = new QSvgRenderer(bytArrSVG, pobjPWidget); } } } }
I see everything else in my window except the SVG, can you see anything missing?
-
I've edited my source:
if ( pobjNode->strGetNodeName().compare(clsXMLnode::mscszNodeSVGroot) == 0 ) { QString strID = pobjNode->strGetAttribute(clsXMLnode::mscszAttrID); if ( strID.isEmpty() != true ) { clsXMLnode* pobjWinNode = pobjNode->pobjGetWindow(); if ( pobjWinNode != nullptr ) { QWidget* pobjPWidget = pobjWinNode->pobjGetWidget(); if ( pobjPWidget != nullptr ) { QByteArray bytArrSVG = pobjNode->bytArrDocument(); QSvgWidget* pobjSVGwidget = new QSvgWidget(pobjPWidget); pobjSVGwidget->load(bytArrSVG); } } } }
I've single stepped all the way to load, but I don't see anything in the window. I thought I may need to apply a position to the SVG, however I've tried both:
<svg id="svgLED" x="20" y="20" width="640" height="480" xmlns="http://www.w3.org/2000/svg">
No better, then tried:
<g transform="translate(20,20)">
Again, no better.
@SPlatten said in How to add SVG widget to MainWindow?:
QSvgWidget* pobjSVGwidget = new QSvgWidget(pobjPWidget);
pobjSVGwidget->load(bytArrSVG);You never call show() on the widget, so why should it be visible?
-
@Bonnie , thank you, how to I put that together with what I have as the QSvgWidget doesn't take a QByteArray and I cannot see a method to set the renderer?
-
I've edited my source:
if ( pobjNode->strGetNodeName().compare(clsXMLnode::mscszNodeSVGroot) == 0 ) { QString strID = pobjNode->strGetAttribute(clsXMLnode::mscszAttrID); if ( strID.isEmpty() != true ) { clsXMLnode* pobjWinNode = pobjNode->pobjGetWindow(); if ( pobjWinNode != nullptr ) { QWidget* pobjPWidget = pobjWinNode->pobjGetWidget(); if ( pobjPWidget != nullptr ) { QByteArray bytArrSVG = pobjNode->bytArrDocument(); QSvgWidget* pobjSVGwidget = new QSvgWidget(pobjPWidget); pobjSVGwidget->load(bytArrSVG); } } } }
I've single stepped all the way to load, but I don't see anything in the window. I thought I may need to apply a position to the SVG, however I've tried both:
<svg id="svgLED" x="20" y="20" width="640" height="480" xmlns="http://www.w3.org/2000/svg">
No better, then tried:
<g transform="translate(20,20)">
Again, no better.
-
I've edited my source:
if ( pobjNode->strGetNodeName().compare(clsXMLnode::mscszNodeSVGroot) == 0 ) { QString strID = pobjNode->strGetAttribute(clsXMLnode::mscszAttrID); if ( strID.isEmpty() != true ) { clsXMLnode* pobjWinNode = pobjNode->pobjGetWindow(); if ( pobjWinNode != nullptr ) { QWidget* pobjPWidget = pobjWinNode->pobjGetWidget(); if ( pobjPWidget != nullptr ) { QByteArray bytArrSVG = pobjNode->bytArrDocument(); QSvgWidget* pobjSVGwidget = new QSvgWidget(pobjPWidget); pobjSVGwidget->load(bytArrSVG); } } } }
I've single stepped all the way to load, but I don't see anything in the window. I thought I may need to apply a position to the SVG, however I've tried both:
<svg id="svgLED" x="20" y="20" width="640" height="480" xmlns="http://www.w3.org/2000/svg">
No better, then tried:
<g transform="translate(20,20)">
Again, no better.
@SPlatten said in How to add SVG widget to MainWindow?:
QSvgWidget* pobjSVGwidget = new QSvgWidget(pobjPWidget);
pobjSVGwidget->load(bytArrSVG);You never call show() on the widget, so why should it be visible?
-
@SPlatten said in How to add SVG widget to MainWindow?:
QSvgWidget* pobjSVGwidget = new QSvgWidget(pobjPWidget);
pobjSVGwidget->load(bytArrSVG);You never call show() on the widget, so why should it be visible?