添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

Since using PyQt6 , I am getting this strange error: qt.svg: <input>:1:8277: Could not parse node: radialGradient

The QSvgRenderer (used by the QSvgWidget ) can't display radial gradients in PyQt6 . This same code, that I have, worked perfectly fine in PyQt5 , but now on PyQt6 , 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 I saw on the QGraphicsScene while using SVG in Qt6? Though losing radial gradient support is a bit weird.

Can you share the SVG? Might be worth validating it.

PedanticHacker

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 given to the check argument of chess.svg.board() method is:

python
if self.board.is_check():
    return self.board.king(self.board.turn)

where self.board is chess.Board() instance.

The error, when there is check in a chessboard position, is this:

python
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 example 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">
    <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>

The test program

python
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, which just needs to change the import for from PyQt6.QtSvgWidgets import QGraphicsSvgItem

python
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, it works, e.g.

<svg width="400" height="150">
  <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>

Looks like the following (in PyQt6)

I looked up some other radial gradients online, and some don't throw the error. Porting back the attributes of the elements that work I found that adding an r (radius) attribute to the radialGradient will mean 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, in that a radial gradient doesn't really make sense without a radius.

The result with the above

Final SVG code

<svg width="400" height="150">
  <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>

PedanticHacker

Wow, Martin, you nailed it! I just needed to pass the r attribute with the value of 0.5 and now it works perfectly in PyQt6. Thank you, thank you, thank you, you are truly a master hacker! :+1:

I have 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, saying If the attribute is not specified, the effect is as if a value of '50%' were specified.. I don't know what guys at Riverbank changed in PyQt6 to break this. :thinking:

Over 10,000 developers have bought Create GUI Applications with Python & Qt!
[[ discount.discount_pc ]]% OFF for the next [[ discount.duration ]] [[discount.description ]] with the code [[ discount.coupon_code ]]

Purchasing Power Parity

Developers in [[ country ]] get [[ discount.discount_pc ]]% OFF on all books & courses with code [[ discount.coupon_code ]] Martin Fitzpatrick has been developing Python/Qt apps for 8 years. Building desktop applications to make data-analysis tools more user-friendly, Python was the obvious choice. Starting with Tk, later moving to wxWidgets and finally adopting PyQt. Strange error in PyQt6 (not rendering radial gradients) was published in faq on (updated ) . Feedback & Corrections welcome in our public issue tracker.