[GIS] Getting list of layers names using PyQGIS

layer-namelayerslistpyqgis

To get the list of TOC layer names I used the approach suggested here:

for layer in QgsMapLayerRegistry.instance().mapLayers().values():
    print layer.name()

But this method is not reliable due to it is able to catch "phantom" layers that are created when the preview option in DB Manager plugin is used (see this ticket) and were never added to TOC by user. Here is what happens:

>>>def laylist():
>>>  l=[]
>>>  for layer in QgsMapLayerRegistry.instance().mapLayers().values():
>>>    item = layer.name()
>>>    l.append(item)
>>>  print l
# There is only one layer 'buf' (a shp-file) in QGIS TOC. Check the TOC
>>>laylist()
[u'buf']
# Now open DM Manager, connect to the PostGIS DB and preview one of the spatially enabled tables ('park_kvartal3_utm') without adding them to TOC
# Check TOC again:
>>>laylist()
[u'park_kvartal3_utm', u'buf']
# Now in DB Manager select another spatial table ('itog_region_utm') and preview it without adding it to TOC
>>>laylist()
[u'park_kvartal3_utm', u'itog_region_utm', u'buf']
# Close DB Manager and catch exception. 
Exception RuntimeError: 'wrapped C/C++ object of type PGVectorTable has been deleted' in <bound method PGTableDataModel.__del__ of <db_manager.db_plugins.postgis.data_model.PGTableDataModel object at 0x7f17550dedf8>> ignored
# Check TOC content again after the DB Manager is closed. Notice: no layer was added to TOC by user during DB Manager session. The names of table remains:
>>>laylist()
[u'park_kvartal3_utm', u'itog_region_utm', u'buf']

However scripts from the Processing Toolbox displays only valid user-added layers in corresponding comboboxes, which indicates that there is another method for fetching layer names (or filtering valid ones) is implemented.

How to get only layers that are displayed at TOC?

Best Answer

Visible layers

You could use this function to get layer names printed:

def get_layers():
    # List visible layers (warning: only spatial ones)
    layer_list = []
    for layer in iface.mapCanvas().layers():
        item = layer.name()
        layer_list.append(item)
    print(layer_list)
    
get_layers()

Layers in TOC (layers panel / legend / layer tree)

In case that you need all layers in the TOC (not only those that are visible/checked, as mapCanvas().layers() returns), you can use this function:

def get_toc_layers(group):
    # List all layers in a group
    for child in group.children():
        if isinstance(child, QgsLayerTreeLayer):
            print(child.layer().name())
        else:
            get_toc_layers(child)

root = QgsProject.instance().layerTreeRoot()
get_toc_layers(root)

All registered layers

QGIS can use layers that are part of the QGIS project but are not shown in the TOC. If you want to get those layers listed as well, do this:

def get_all_layers():
    # List register layers (even if they aren't in the TOC)
    layer_list = []
    for k, layer in QgsProject.instance().mapLayers().items():
        layer_list.append(layer.name())
    
    print(layer_list)
    
get_all_layers()
Related Question