[GIS] Adding new rule by using QgsRuleBasedRenderer to existing one in PyQGIS

pyqgisqgis-3rule-based

I want to add new rules for a layer. However when I add them previous one(s) are deleted. Here is my code:

layer = iface.activeLayer()
symbol = QgsSymbol.defaultSymbol(layer.geometryType())
renderer = QgsRuleBasedRenderer(symbol)

# get the root rule
root_rule = renderer.rootRule()

# create clone of the default rule
rule = root_rule.children()[0].clone()

# set the label, expression and color
rule.setLabel("Akarsu Kutlesi")
rule.setFilterExpression(""""Subbasin" IN (2,4,6)""")
rule.symbol().setColor(QColor("orange"))

# append the rule to the list of rules
root_rule.appendtChild(rule)
# apply the renderer
layer.setRenderer(renderer)

Here is existing rules of layer:

enter image description here

enter image description here

Best Answer

Your code works fine. When you want to add a new rule, do not repeat the first 3 lines of code as this creates a new symbol renderer. Just start from

root_rule = renderer.rootRule()
...

And create your new rule.


I find it easier to use a function like the following:

layer = iface.activeLayer()
symbol = QgsSymbol.defaultSymbol(layer.geometryType())
renderer = QgsRuleBasedRenderer(symbol)

def rule_based_style(layer, symbol, renderer, label, expression, color):
    root_rule = renderer.rootRule()
    rule = root_rule.children()[0].clone()
    rule.setLabel(label)
    rule.setFilterExpression(expression)
    rule.symbol().setColor(QColor(color))
    root_rule.appendChild(rule)
    layer.setRenderer(renderer)
    layer.triggerRepaint()
    iface.layerTreeView().refreshLayerSymbology(layer.id())

Then you can apply new rules:

rule_based_style(layer, symbol, renderer, 'Akarsu Kutlesi', ' \"Subbasin\" IN (2,4,6) ', 'orange')
rule_based_style(layer, symbol, renderer, 'Something else', ' \"Subbasin\" IN (3,5,7) ', 'red')

Example

Related Question