5

As far as I see, on QgsMapLayerRegistry.instance() there is a method to select layers:

mapLayersByName(Qstring)

and the method

mapLayer(QString)

respectively, wich accesses a layer by its id.

As the name says, mapLayersByName() selects layers by their name in the legend, wich causes scripts or plugins to fail if a user renames a layer/table (i.e. renaming a table '160520_parcels' to 'Parcels').

So is there a way to access a layer by the name of it's origining table in PyQGIS?

update

something like ...

def selectLayerByOriginalName(tablename):
    # return layers whose orininal names start with 'tablename'
    llist = []
    for l in QgsMapLayerRegistry.instance().mapLayers().values():
        if tablename in l.id():
           if l.id().index(tablename) == 0:
               llist.append(lyr)
    return llist

... works, but is there a more convenient approach?

1
  • 2
    There is an OriginalName() method (docs) in QgsMapLayer, but strangely it is altered once the user changes the layer name. I agree that using the id() (extracting the first part of it) seems to be the only way. However, using your code, looking for a "Roads2" layer, a layer called "Roads" would also match and enter the 2 ifs. I'd rather try to remove the timestamp. Commented Jun 1, 2016 at 14:20

1 Answer 1

3

You can do it this way:

def get_layer_by_tablename(self, tablename):
    """ Iterate over all layers and get the one with selected @tablename """

    # Check if we have any layer loaded
    layers = self.iface.legendInterface().layers()
    if len(layers) == 0:
        return None

    # Iterate over all layers
    layer = None
    for cur_layer in layers:
        uri_table = self.get_layer_source_table_name(cur_layer)
        if uri_table is not None and uri_table == tablename:
            layer = cur_layer
            break

    if layer is None:
       print ("Layer not found")

    return layer


def get_layer_source_table_name(self, layer):
    """ Get table or view name of selected layer """

    if layer is None:
        return None

    uri_table = None
    uri = layer.dataProvider().dataSourceUri().lower()
    pos_ini = uri.find('table=')
    pos_end_schema = uri.rfind('.')
    pos_fi = uri.find('" ')
    if pos_ini <> -1 and pos_fi <> -1:
        uri_table = uri[pos_end_schema+2:pos_fi]

    return uri_table  

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.