4

When I run the next code at the Python Console of QGIS with a line vector layer:

symbol1 = QgsLineSymbolV2.createSimple({'penstyle':'solid',
                                        'color':'black',
                                        'width':'3'
                                        })

symbol2 = QgsLineSymbolV2.createSimple({'penstyle':'dash',
                                        'color':'white',
                                        'width':'0',
                                        'customdash':'8;4',
                                        'use_custom_dash': '1'
                                        })


route = iface.activeLayer()
renderer = route.rendererV2()

type1 = symbol1.type()
type2 = symbol2.type()

print "Is Symbol Layer Compatible?", symbol1.isSymbolLayerCompatible(type2)

#Create Symbol Layers
symbol_layer1 = symbol1.symbolLayer(0)
symbol_layer2 = symbol2.symbolLayer(0)

#Append Symbol Layer 2 to symbol1 (now with two Symbol Layers)
symbol1.appendSymbolLayer(symbol_layer2)

renderer.setSymbol(symbol1)

route.triggerRepaint()
iface.legendInterface().refreshLayerSymbology(route)

I got the following result:

enter image description here

indicating that the symbol2 (QgsLineSymbolV2 class), as Symbol Layer (symbol_layer2 belongs to QgsLineSymbolLayerV2 class), it was correctly appending to symbol1. However, when this code is ran again, QGIS crashes and it closes all windows. This behavior doesn't appear if the symbol has only one Symbol Layer; when it is commented, at the first execution time, the line with this instruction:

symbol1.appendSymbolLayer(symbol_layer2)).

How can I prevent the second time QGIS crash when I am using a symbol with 2 or more Symbol Layers?

  • I don't know the answer to the question, but if you report it as a reproduceable bug to the tracker, the devs will hopefully fix it. hub.qgis.org/projects/quantum-gis/issues – GIS-Jonathan Jul 23 '15 at 10:20
  • Thanks for your answer. It suggest to me the idea of also run the code with Qgis Wien in Windows (I am working now with Qgis Pisa in Debian Linux). – xunilk Jul 23 '15 at 10:40
4

Reason

When you create a symbol it has ownership of its layers. When you add a layer to an existing symbol, it takes ownership of the added layer. Ownership means it is free to delete it whenever it wants.

In your example both symbols assume ownership of symbol_layer2 (symbol2 because it created symbol_layer2, symbol1 because symbol_layer2 was added to it).

Now when you run the code a second time, symbol2 gets replaced by a new one, so python deletes symbol2 and symbol2 deletes symbol_layer2 because it has the ownership.

When you later set a new symbol on the renderer it deletes the old symbol (which you set in the first time the code was run) because it is no longer in use. The (old) symbol1 is deleted and with it symbol_layer2 of which symbol1 also assumes ownership. But - bad luck - this has already been deleted by symbol2. And deleting the same thing twice results in a crash...

Solution

Clone the symbol layer so both have their own copy to work on

symbol1.appendSymbolLayer(symbol_layer2.clone())

Or take the symbollayer away from symbol2

symbol_layer2 = symbol2.takeSymbolLayer(0)

Or directly create a symbol layer instead of borrowing one constructed by a symbol.

Is this a bug?

No, this is expected behavior.

There are several possibilities to cause crashes with python code. However there is room for improvement in the API docs. This will be changed soon.

  • 1
    Thanks for your answer. This instruction symbol1.appendSymbolLayer(symbol_layer2.clone()) works perfectly (by the way, in your answer has a parenthesis in excess). – xunilk Jul 23 '15 at 10:50
  • Oops, corrected – Matthias Kuhn Jul 23 '15 at 10:52

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.