I am working on a python plugin for QGIS using a layer containing linestrings, which I would like to have on top at all times. I have added the layer like the following:
QgsMapLayerRegistry.instance().addMapLayer(layer, addToLegend=False)
I don't want the layer to appear in the Layers Panel.
A similar question has been asked here without an accepted and for me meaningful answer.
According to Nathan W I can use the canvas
method setLayerSet
to set the render order on the canvas layers.
In case the current project already contains several layers, I need to know the current rendering order to correctly place my layer on top without disturbing the current order.
In case the user adds a new layer, how do I prevent the new layer from being ontop of mine? Is this handled by listening for some kind of a layer reordered signal on the canvas?
Question: What is the correct approach to handle this issue?
Update with solution notes:
I have implemented the answer provided by dmh126. To follow up on my questions I have determined that, it looks like canvas.layers()
provide the layers in the order last given to the canvas.setLayerSet(...)
. Thus this list of layers can be used to include my layer on top directly:
layers = [my_layer] + canvas.layers()
canvas.setLayerSet([QgsMapCanvasLayer(x) for x in layers if x.id() != my_layer.id()])
# I don't want my layer in the list twice if it was already there due to a previous update.
The canvas
signal layersChanged
can be used to determine a change in the layers (new layer, removed layer, visibility change...), but remember to disconnect the listener when calling `canvas.setLayerSet(...)' because it will fire the signal again, probably causing a never ending call to the method called by the listener:
QObject.disconnect(canvas, SIGNAL('layersChanged()'), my_method)
layers = [my_layer] + canvas.layers()
canvas.setLayerSet([QgsMapCanvasLayer(x) for x in layers if x.id() != my_layer.id()])
QObject.connect(canvas, SIGNAL('layersChanged()'), my_method)
If I need to hide my layer, I can just remove it from the layer set like above:
layers = canvas.layers()
canvas.setLayerSet([QgsMapCanvasLayer(x) for x in layers if x.id() != my_layer.id()])