30

I'm having trouble figuring out how to iterate over map layers. I can access the currently highlighted layer in the table of contents via iface.activeLayer() but I want my code to operate on all layers.

I don't see anything in the API that provides easy access to this functionality and couldn't find a good online example but maybe I missed something?

  • I don't see how you guys are using QgsMapLayerRegistry or QgsProject. In QGIS 3.0.2 this does not work. However, iface.mapCanvas().layers() does. Well, kind of. It only seems to give you the active layers (the ones you have checked in the Layers pane). Does anyone know how to get a list of all Layers, even those unchecked in the Layers pane? Also, if using Plugin Builder, it creates the shell of your plugin for you. The run function has a "self" parameter, which is needed to use iface. i.e. self.iface.mapCanvas().layers(), just fyi. – ajpieri Oct 12 '18 at 13:11
24

Try...

# substitute 'self' with 'qgis.utils.iface' when run from Python console
# 'self.iface = iface' would usually precede this command in your class 
layers = self.iface.legendInterface().layers()

for layer in layers:
    layerType = layer.type()
    if layerType == QgsMapLayer.VectorLayer:
        # do some stuff here

Culled from consolidatethread.py from QConsolidate plugin.

Description of QgsLegendInterface object returned from legendInterface().

Edit: added info on 'self' above.

  • Thanks! That did the trick. I guess I'm too used to the ESRI world where legend is the object in the map layout and table of contents refers to the list of layers. – spencerrecneps May 26 '12 at 23:53
  • 2
    Note that there is a difference in what is returned between this and the mapCanvas() technique Nathan mentions. The legendInterface() object will return all layers, even if they are not shown in the map canvas, while mapCanvas() returns only those shown on the canvas. Using mapCanvas() is a nice, quick way to get a reference to visible layers. – dakcarto May 27 '12 at 2:00
  • 1
    On another note, the latest versions of QGIS (>= 1.8) allow the user to define a rendering order of layers separately from the order listed in the legend (very nice!). The legendInterface() and mapCanvas() methods return the layer order for each respectively. – dakcarto May 27 '12 at 2:07
19

There are also two other ways:

layers = self.iface.mapCanvas().layers()

will give you a list of layers

or

layers = QgsMapLayerRegistry.instance().mapLayers()

for name, layer in layers.iteritems():
     print name, layer.type()
  • This answer doesn't seem to work in 2.16 and above – raphael Dec 28 '16 at 21:27
10

For QGIS 2.6 here is the code to identify each layer and group them:

#make the desired groups for layers
toc = self.iface.legendInterface()
root = QgsProject.instance().layerTreeRoot()
group1 = root.insertGroup(0, "Group Point")
group2 = root.insertGroup(1, "Group Line")
group3 = root.insertGroup(2, "Group Polygon")
#get the list of layers  from registry
layers = QgsMapLayerRegistry.instance().mapLayers()
#segregate layers into groups 
for name, layer in layers.iteritems():
    # check the layer geometry type 
    if layer.geometryType() == QGis.Point:
        toc.moveLayer(layer, 0)

    if layer.geometryType() == QGis.Line:
        toc.moveLayer(layer, 1)

    if layer.geometryType() == QGis.Polygon:
        toc.moveLayer(layer, 2)

Note: After grouping I have to remove the duplicate layer so I used root.removeLayer(lyr).

9

For QGIS 3, QgsMapLayerRegistry's functionality has been moved to QgsProject.

So, for iterating over map layers, you should use that structure:

layers = QgsProject.instance().mapLayers()

.mapLayers() returns a dictionary structured as {layer_x_id: layer_x, layer_y_id: layer_y, ....}. Then you can iterate over layers like:

for layer_id, layer in layers.items():
    print(layer.name())

Because .mapLayers() returns a dictionary (dict), you can also use .values() method of dictionary which returns just a list which contains layers in that case. Then you can iterate over layers like:

layers = QgsProject.instance().mapLayers().values()

for layer in layers:
    print(layer.name())

If you prefer, you can iterate in this way:

layers = QgsProject.instance().mapLayers() # dictionary

for layer in layers.values():
    print(layer.name())
  • Hi! Thanks for sharing it. To print the names of the layers works fine... but I can't print the keys of the dictionary. Can you help me with that? – caio villaca Jun 18 at 18:39
  • 1
    for layer in layers: print(layer) You can use the script to print the keys. Or just use print(layers.keys()) without for loop. – Kadir Şahbaz Jun 18 at 21:01

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.