I have a plugin which finds buffer for list of cities, provided the distance. The state and city names are taken from the attribute table and gets filtered accordingly. What I want is my plugin should identify the layer name or order of the layer in canvas, irrespective of other layers present in the canvas and access the corresponding attributes from that layer.

I am also just curious whether pointing a specific layer name in code would cause any error in iteration though some other layers are present?

Below is my code please tell me where should I make changes and what would be the change?

if dist and centerCity:
    #QMessageBox.information(self.dlg, "info", "both True")
    st = '"name" = \'' + centerCity + '\''
    exp = QgsExpression(st)
    QMessageBox.warning(self.dlg, "Enter the distance","Enter the distance and try again.")        
    return          #terminate the function

layer = self.iface.activeLayer() 
it = layer.getFeatures(QgsFeatureRequest(exp))
feature = it.next()
mbuf = feature.geometry().buffer(dist, 2)       

iterFeat = layer.getFeatures()

for f in iterFeat:
    geom2 = f.geometry()
    valTest = QgsGeometry.within(geom2, mbuf) 

1 Answer 1


For QGIS 3 :

UPDATE: 10.04.2018

Using QGIS 3.x you can use the mapLayersByName method from QgsProject class in this way:

layers = QgsProject.instance().mapLayersByName('my layer name')

Since you can have several layers in QGIS with the same name in the layers panel, the method above gives you a list of matching layers.

Before accessing any element in the layer list, you should check if the list has elements. If so you can access, for instance, its first element (layer) in this way:

if layers: 
    layer = layers[0]

Which would be the common case of having a single layer matching the name you searched for.

For QGIS 2 :

In QGIS 2.x you would just need to make sure your layer has a name you can distinguish from others. Instead of layer = self.iface.activeLayer(), do:

layer = None
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.name() == "YOUR_LAYER_NAME":
        layer = lyr

If you don't trust the layer name (after all, it can be changed by the user at any time), you could try to check the layer source. If your layer is a Shapefile, you could check the path to the Shapefile, this way:

layer = None
for lyr in QgsMapLayerRegistry.instance().mapLayers().values():
    if lyr.source() == "/path/to/shapefile.shp":
        layer = lyr

EDIT: As @Jakob has pointed out in comments, you can write the first block in one line:

layerList = QgsMapLayerRegistry.instance().mapLayersByName("YOUR_LAYER_NAME")


layerList = [lyr for lyr in QgsMapLayerRegistry.instance().mapLayers().values() if lyr.name() == "YOUR_LAYER_NAME"]

Anyway, you would need to check that layerList is not empty before accessing its first element:

if layerList: 
    layer = layerList[0]
  • 3
    print [lyr for lyr in QgsMapLayerRegistry.instance().mapLayers().values() if lyr.name() == "LAND"][0].name()
    – Jakob
    Commented Feb 26, 2015 at 14:08
  • 8
    layer = QgsMapLayerRegistry.instance().mapLayersByName("mylayername")[0]
    – Jakob
    Commented Jun 17, 2015 at 9:09
  • 1
    why are you setting layer = none at the beginning of your code? It seems unnecessary especially if its in a function
    – user32882
    Commented Sep 12, 2018 at 5:02
  • 3
    It's a default value, because there is an if inside the for. If the if is never met, layer won't exist at all after the for. So, just to make sure you can read the layer variable afterwards. Commented Sep 14, 2018 at 1:19

Your Answer

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

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