PyQGIS QML Issue – Setting Color of Existing Categorized Symbol from .qml Crashes QGIS

pyqgisqgisqml

I have several layers in a project which have existing style files applied.
I want to modify the symbol color attributes using python.
The symbols are QgsFillSymbol objects.

This seems to work fine for layers with a single symbol, using the QgsSingleSymbolRenderer via the code below:

layer = iface.activeLayer()
renderer = layer.renderer()  #QgsSingleSymbolRenderer    
symbol = renderer.symbol()
symbol.setColor(QColor.fromRgb(255,128,0))
layer.triggerRepaint()      
iface.layerTreeView().refreshLayerSymbology(layer.id())

However, QGIS crashes when I attempt to do this for categorised symbols via the QgsCategorizedSymbolRenderer, using the code below:

layer = iface.activeLayer()
renderer = layer.renderer()    #QgsCategorizedSymbolRenderer
symbol = renderer.categories()[0].symbol()  # select first category
symbol.setColor(QColor.fromRgb(255,128,0))  # --CRASHES HERE--

the symbol is a valid qgis._core.QgsFillSymbol object, and renderer.categories() returns the expected layer categories:

[<qgis._core.QgsRendererCategory object at 0x000001E64BD148B0>, <qgis._core.QgsRendererCategory object at 0x000001E64BD14940>, <qgis._core.QgsRendererCategory object at 0x000001E64BD14820>, <qgis._core.QgsRendererCategory object at 0x000001E64BD14A60>]

 

Best Answer

The QgsCategorizedSymbolRenderer class has a method updateCategorySymbol().

So you could create a new QgsFillSymbol object, set its color and pass it to the updateCategorySymbol() method along with your category index.

Try the code snippet below:

layer = iface.activeLayer()
renderer = layer.renderer()    #QgsCategorizedSymbolRenderer
symbol = QgsFillSymbol()
symbol.setColor(QColor.fromRgb(255,128,0))
renderer.updateCategorySymbol(0, symbol)
layer.triggerRepaint()
iface.layerTreeView().refreshLayerSymbology(layer.id())

Link to docs here.

Related Question