The answer is not simple. But, as long as you are completely sure that you only want to use the shape (or mask) of the original SVG, then it is feasible.
The reason for which setting the pen doesn't change the result is that SVG is a vector image format: it usually explicitly tells the colors of anything it wants to draw, so, setting the painter pen is almost useless, unless the SVG content is so simple to not specify it, which is clearly not the case: icons normally define colors of their shapes, and for good reasons.
The problem comes when trying to understand compositing and the possible alternatives that QPainter provides.
To be honest, even after trying to put efforts in understanding the results and associating them with the QPainter.CompositionMode
enums, I still need to testing and checking in order to understand the proper mode I need.
What you probably need is the CompositionMode_SourceIn
, which is cryptically explained in the documentation:
The output is the source, where the alpha is reduced by that of the destination.
As far as I can understand, the source is what is going to be painted, while the destination is what was previously painted (consider the source as a brush painting, and the destination as the canvas on which you paint).
With that in mind, we need to use the original svg as the destination and fill the whole pixmap with the color we want. Since only the alpha of the destination will be used (the visible part of the svg), we will be practically doing some sort of "stencil".
def svg_to_pixmap(svg_filename: str, width: int, height: int, color: QColor) -> QPixmap:
renderer = QSvgRenderer(svg_filename)
pixmap = QPixmap(width, height)
pixmap.fill(Qt.GlobalColor.transparent)
painter = QPainter(pixmap)
renderer.render(painter) # this is the destination, and only its alpha is used!
painter.setCompositionMode(
painter.CompositionMode.CompositionMode_SourceIn)
painter.fillRect(pixmap.rect(), color)
painter.end()
return pixmap
Which seems to give the wanted result:
