8

Im having a problem toggling the visibility of map layers in pyqgis (2.4). I have a simple interface, just the map canvas, no legend, and basically a radio button that toggles between two raster layers.

Layers are initialized like this:

lyr = QgsRasterLayer(os.getcwd() + '/data/rasters/dof/dof.vrt', 'Ortophoto')
QgsMapLayerRegistry.instance().addMapLayer(lyr, False)
ml = QgsMapCanvasLayer(lyr)
ml.setVisible(False)

lyr2 = QgsRasterLayer(os.getcwd() + '/data/rasters/chm/chm.vrt', 'Chm')        
QgsMapLayerRegistry.instance().addMapLayer(lyr2, False)
ml2 = QgsMapCanvasLayer(lyr2)
ml2.setVisible(True)

When i want to toggle their visibility i do:

ml.setVisible(True)
ml2.setVisible(False)

But unfortunately, the rendering on the map canvas stays the same.

What am i missing?

3 Answers 3

12

For QGIS 3, you have to use: QgsProject.instance().layerTreeRoot().findLayer(layer_id).setItemVisibilityChecked(False)

or to be safe

node = QgsProject.instance().layerTreeRoot().findLayer(layer_id)
if node:
  node.setItemVisibilityChecked(False)

Reading the documentation, findLayer accepts both the layer itself or the layer ID as a string.

2
  • Is it possible to use a variable instead of the layer name in 'layer.id()' ?
    – Leo
    Feb 4, 2020 at 5:41
  • 1
    yes, I update the code and added a pointer to the documentation. Feb 4, 2020 at 5:53
4

At the moment (QGIS 2.x) (and I know it's a bit gross) but you also have to update the layer set on the canvas to update the layer state change

canvas.setLayerSet([ml2, ml])

This will also control the render order. m1 will reneder first then ml2 on top of it.

1
  • THIS is the correct answer. GIS.SE saves the day once more ;>
    – U2ros
    Oct 22, 2014 at 13:46
1

In QGIS 2, You have to refresh the mapCanvas as well:

 ml.setVisible(True)
 ml2.setVisible(False)

 qgis.utils.iface.mapCanvas().refresh()

After this the map Canvas will redraw and you can see the changes.

Normally you should see changes when you zoom in and out to force a refresh of the mapCanvas manually.

To set the layer visibility you can use this:

 qgis.utils.iface.legendInterface().setLayerVisible(m1, False)
 qgis.utils.iface.legendInterface().setLayerVisible(m12, True)

I think mapCanvas doesn't have a method to set teh layer visibility. A setLayerVisibility can only be found in the QgsLegendInterface:

http://qgis.org/api/classQgsLegendInterface.html#ae77bf61a8c81bee9f861c6f7d7c7d8cf

If this doesn't work you can also change the transparency of a raster layer with QgsRasterTransparency.TransparentSingleValuePixel() like in this post

How do I set layer transparency in QGIS 2.0 with Python?

6
  • Doesn't work.I tried zooming in/out anyway.
    – U2ros
    Oct 22, 2014 at 12:02
  • I refreshed the map canvas instance directly self.ui.map.refresh()
    – U2ros
    Oct 22, 2014 at 12:03
  • 1
    Must be something else in my code then. It is a helpful if i know this is the way to do it ;>
    – U2ros
    Oct 22, 2014 at 12:04
  • Thanks for updating your answer... in 2.4 qgis.utils no longer exists. How do you access iface.legenInterface()?
    – U2ros
    Oct 22, 2014 at 12:44
  • I use Qgis2.4 and i use for example to get the active layer in a plugin layer = qgis.utils.iface.activeLayer() or import qgis.utils
    – Martin
    Oct 22, 2014 at 12:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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