PedanticHacker asked
Since using
PyQt6, I am getting this strange error:qt.svg: <input>:1:8277: Could not parse node: radialGradientThe
QSvgRenderer(used by theQSvgWidget) can't display radial gradients inPyQt6. This same code, that I have, worked perfectly fine inPyQt5, but now onPyQt6, it does not render radial gradients in SVGs anymore. Is there a workaround or something?
Martin Fitzpatrick
I wonder if there are just some bugs in Qt6 at the moment. Remember the weird glitching effects we saw on the QGraphicsScene while using SVG in Qt6? Still, losing radial gradient support is a bit weird.
Can you share the SVG? Might be worth validating it.
PedanticHacker
Never miss an update
Enjoyed this? Subscribe to get new updates straight in your Inbox.
Well, the code for generating the SVG chessboard is on the python-chess' GitHub site HERE.
The rendering part of the code for the generated python-chess SVG is HERE.
The board() method of the chess.svg module is the one that generates the SVG chessboard, based upon the arguments given to that method. For the check mark that is the check argument. The code passed to the check argument of the chess.svg.board() method is:
if self.board.is_check():
return self.board.king(self.board.turn)
where self.board is a chess.Board() instance.
The error, when there is a check in a chessboard position, is this:
qt.svg: <input>:1:7114: Could not parse node: radialGradient
qt.svg: <input>:1:31331: Could not resolve property: #check_gradient
Martin Fitzpatrick
Below is a small test case which works in PyQt5 (read on for the solution in PyQt6). Here's the radial gradient (saved to a file named "gradient.svg") and the test program.

The svg
<svg width="400" height="150">
<defs>
<radialGradient id="grad1"><stop offset="0%" stop-color="#ff0000" stop-opacity="1.0" /><stop offset="50%" stop-color="#e70000" stop-opacity="1.0" /><stop offset="100%" stop-color="#9e0000" stop-opacity="0.0" /></radialGradient>
</defs>
<ellipse fill="url(#grad1)" cx="200" cy="70" rx="85" ry="55"/>
<text x="150" y="86" fill="green" font-family="Verdana" font-size="45">SVG</text>
</svg>
The test program
import math
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QGraphicsScene, QGraphicsView
from PyQt5.QtSvg import QGraphicsSvgItem
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.scene = QGraphicsScene()
self.viewer = QGraphicsView()
self.setCentralWidget(self.viewer)
svg = QGraphicsSvgItem('gradient.svg')
self.scene.addItem(svg)
self.viewer.setScene(self.scene)
app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec_()
The same code in PyQt6 just needs the import changed to from PyQt6.QtSvgWidgets import QGraphicsSvgItem.
import math
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QGraphicsScene, QGraphicsView
from PyQt6.QtSvgWidgets import QGraphicsSvgItem
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.scene = QGraphicsScene()
self.viewer = QGraphicsView()
self.setCentralWidget(self.viewer)
svg = QGraphicsSvgItem('gradient.svg')
self.scene.addItem(svg)
self.viewer.setScene(self.scene)
app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec()
Switching out the radial gradient for a linear one works, e.g.
<svg width="400" height="150">
<defs>
<linearGradient id="grad1" y1="0%" x1="0%" y2="0%" x2="100%">
<stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1"/>
<stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1"/>
</linearGradient>
</defs>
<ellipse fill="url(#grad1)" cx="200" cy="70" rx="85" ry="55"/>
<text x="150" y="86" fill="green" font-family="Verdana" font-size="45">SVG</text>
</svg>
Looks like the following (in PyQt6)

I looked up some other radial gradients online, and some don't throw the error. By porting back the attributes of the elements that work, I found that adding an r (radius) attribute to the radialGradient means it doesn't throw the error. The value necessary to give the expected gradient is 0.5.
<radialGradient id="grad1" r="0.5">
<stop offset="0%" stop-color="#ff0000" stop-opacity="1.0"/>
<stop offset="50%" stop-color="#e70000" stop-opacity="1.0"/>
<stop offset="100%" stop-color="#9e0000" stop-opacity="0.0"/>
</radialGradient>
It makes some sense, since a radial gradient doesn't really make sense without a radius.
The result with the above

Final SVG code
<svg width="400" height="150">
<defs>
<radialGradient id="grad1" r="0.5">
<stop offset="0%" stop-color="#ff0000" stop-opacity="1.0"/>
<stop offset="50%" stop-color="#e70000" stop-opacity="1.0"/>
<stop offset="100%" stop-color="#9e0000" stop-opacity="0.0"/>
</radialGradient>
</defs>
<ellipse fill="url(#grad1)" cx="200" cy="70" rx="85" ry="55"/>
<text x="150" y="86" fill="green" font-family="Verdana" font-size="45">SVG</text>
</svg>
PedanticHacker
Wow, Martin, you nailed it! I just needed to pass the r attribute with the value 0.5, and now it works perfectly in PyQt6. Thank you!
I reported this "missing r attribute" bug in python-chess, and the issue has already been fixed. However, the python-chess author (Niklas Fiekas) told me that if the r attribute is missing, it should default to 50%, as specified here: If the attribute is not specified, the effect is as if a value of '50%' were specified. I don't know what the folks at Riverbank changed in PyQt6 to break this.