7

I am trying to use PyQGIS to convert a Fill Symbol Layer into a geometry generator Symbol Layer in a rule-based renderer with 300 rules.

I am able to iterate over the rules and return each rule's symbol and then the respective (unique) Symbol Layer. I know there's a changeSymbolLayer()

What I am failing to do, is to create a QgsGeometryGeneratorSymbolLayer to overwrite the existing symbol layer. Until now, the code is something like this:

layer = iface.mapCanvas().currentLayer()
rules = layer.renderer().rootRule().children()

for rule in rules:
    label = rule.label()
    symbol_layer = rule.symbol().symbolLayer(0)
    print(symbol_layer)
    color = symbol_layer.color()
    generator = QgsGeometryGeneratorSymbolLayer()
    generator.setFillColor(color)
    generator.setGeometryExpression(expression)
    rule.symbol().changeSymbolLayer(0,generator)

In this case the QgsGeometryGeneratorSymbolLayer() fails by saying that I am not able to instantiate.

I am not understanding how to create the new symbol to apply on each rule.

5
  • It doesn't seem to have a constructor. Can you use .create() or .clone() instead? – Tom Chadwin Jan 19 at 17:35
  • 2
    generator = QgsGeometryGeneratorSymbolLayer.create({}) seems to work – Dror Bogin Jan 19 at 17:37
  • To clone() l need an existing symbol layer already, right? Not sure how to use create. I have seen it in other symbol layers types, but wasn't able to figure out how to apply to geometry generators. – Alexandre Neto Jan 19 at 17:41
  • 1
    Since you are programmatically setting its properties, @DrorBogin's creation of an "empty" generator for you to fill looks good. – Tom Chadwin Jan 19 at 17:50
  • The documentation about the actual create properties is a bit lacking, but it seems you can create an empty one and just set everything later – Dror Bogin Jan 19 at 17:54
11

Seems like the only way to create an empty QgsGeometryGeneratorSymbolLayer is by using:

QgsGeometryGeneratorSymbolLayer.create({})

So changing just that should make the rest of the code work:

layer = iface.mapCanvas().currentLayer()
rules = layer.renderer().rootRule().children()

for rule in rules:
    label = rule.label()
    symbol_layer = rule.symbol().symbolLayer(0)
    print(symbol_layer)
    color = symbol_layer.color()
    generator = QgsGeometryGeneratorSymbolLayer.create({})
    generator.setFillColor(color)
    generator.setGeometryExpression(expression)
    rule.symbol().changeSymbolLayer(0,generator)
1
  • 2
    .create({}) was the missing piece. Worked like a charm! – Alexandre Neto Jan 20 at 1:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.