PyQGIS – How to Retrieve the Name of Group Containing a Layer in PyQGIS

group-layerpyqgis

I've been using the "Layer List" plugin (https://plugins.qgis.org/plugins/layerList/) that does a great job of creating a text file with all the layer in a qgs project file.

I want to extend it to get the group and subgroup that the layer is in.

The desired result will be

Provider,Group,Subgroup,Name, Path, Filename.ext

ogr,Administration, Land,CL_TENURE_POLYGON_DC,D:/GIS/Data/DSE/Vicmap/VMCLTENURE/,CL_TENURE_POLYGON_DC.tab

I assume the change would be

def loadActiveLayers(self): 
self.dlgCreate.listWidget.clear() # Clear the list widget before it is filled again
canvas = iface.mapCanvas()
activeLayers = canvas.layers() # Create list with all active layers
layers = u"# Layer List - QGIS Plugin by Klas Karlsson\n" # Create list header and "test" line in a text string
for layer in reversed(activeLayers): # Repeat for all layers in the list
    layerType = layer.type() # Is it Vector or Raster?
    layerSource = layer.publicSource() # path or command for the layer source
    provider = layer.providerType() # Example org, gdal, wms, wfs, postgres, etc
    if layerType == QgsMapLayer.VectorLayer:
    layers = layers + (u"%s,%s,%s\n" % (provider, layer.name(), layerSource))

after layerSource add something for group and subgroup (maybe .layerTreeRoot() from https://qgis.org/api/classQgsLayerTreeGroup.html)

    self.dlgCreate.listWidget.addItem(layer.name()) # Add the layer name to the list

self.dlgCreate.listWidget.addItem(layer.?

 if layerType == QgsMapLayer.RasterLayer:
    layers = layers + (u"%s,%s,%s\n" % (provider, layer.name(), layerSource))
    self.dlgCreate.listWidget.addItem(layer.name()) # Add the layer name to the list
return layers   # Send back all the layers in a text string ready to be saved to a file

Would other changes be required?

Best Answer

Instead of using the layers from the QgsMapCanvas you could better iterate the root of the layer tree view (QgsProject.instance().layerTreeRoot().children()) like I show in How to create a text file containing layer names in QGIS?. In this way you could have direct access to layer tree view groups and layers. Having a QgsLayerTreeLayer you can easily go to the QgsMapLayer by calling my_tree_layer.layer().

However, if you want to stick to the way you're iterating layers, then you can still access the group a layer is in:

my_layer = iface.activeLayer() # Just for you to test

root = QgsProject.instance().layerTreeRoot()
tree_layer = root.findLayer(my_layer.id())
if tree_layer:
    layer_parent = tree_layer.parent()

    if layer_parent: 
        print("Layer parent: {}".format(layer_parent.name() or 'root'))
        group_parent = layer_parent.parent() # If you want to go up another level

        if group_parent: 
            print("Group parent: {}".format(group_parent.name() or 'root'))

Since you would use this repeatedly, based on the code snippet above you could create a function that gets a map layer and gives you group and subgroup.