4. Accedere alla Legenda (o Table Of Contents - TOC)

Suggerimento

I frammenti di codice di questa pagina necessitano delle seguenti importazioni se si è fuori dalla console pyqgis:

from qgis.core import (
    QgsProject,
    QgsVectorLayer,
)

Puoi usare diverse classi per accedere a tutti i layer caricati nella legenda e usarli per recuperare informazioni:

4.1. La classe QgsProject

Puoi usare QgsProject per recuperare informazioni sulla legenda e su tutti i layer caricati.

Devi creare un”instanza di QgsProject e utilizzare i suoi metodi per ottenere i layer caricati.

Il metodo principale è mapLayers(). Restituisce un dizionario dei layer caricati:

layers = QgsProject.instance().mapLayers()
print(layers)
{'countries_89ae1b0f_f41b_4f42_bca4_caf55ddbe4b6': <QgsVectorLayer: 'countries' (ogr)>}

Le ``chiavi”” del dizionario sono gli id univoci dei layer, mentre i ``valori”” sono gli oggetti correlati.

A questo punto è facile ottenere qualsiasi altra informazione sui layer:

1# list of layer names using list comprehension
2l = [layer.name() for layer in QgsProject.instance().mapLayers().values()]
3# dictionary with key = layer name and value = layer object
4layers_list = {}
5for l in QgsProject.instance().mapLayers().values():
6  layers_list[l.name()] = l
7
8print(layers_list)
{'countries': <QgsVectorLayer: 'countries' (ogr)>}

Puoi anche interrogare la legenda utilizzando il nome del layer:

country_layer = QgsProject.instance().mapLayersByName("countries")[0]

Nota

Viene restituito un elenco con tutti i layer corrispondenti, quindi si indicizza con [0] per ottenere il primo layer con questo nome.

4.2. Classe QgsLayerTreeGroup

L’albero dei layer è una classica struttura ad albero composta da nodi. Attualmente esistono due tipi di nodi: nodi di gruppo (QgsLayerTreeGroup) e nodi di layer (QgsLayerTreeLayer).

Nota

Per ulteriori informazioni puoi leggere questi post del blog di Martin Dobias: Part 1 Part 2 Part 3

L’albero dei layer del progetto è facilmente accessibile con il metodo layerTreeRoot() della classe QgsProject:

root = QgsProject.instance().layerTreeRoot()

root è un nodo di gruppo e ha children:

root.children()

Viene restituito un elenco di figli diretti. I figli del sottogruppo devono essere accessibili dal proprio genitore diretto.

Possiamo recuperare uno dei figli:

child0 = root.children()[0]
print(child0)
<QgsLayerTreeLayer: countries>

I layer possono anche essere recuperati usando il loro ``id”” (univoco):

ids = root.findLayerIds()
# access the first layer of the ids list
root.findLayer(ids[0])

E anche I gruppi possono essere cercati utilizzando i loro nomi:

root.findGroup('Group Name')

QgsLayerTreeGroup ha molti altri metodi utili che possono essere usati per ottenere ulteriori informazioni sulla TOC:

# list of all the checked layers in the TOC
checked_layers = root.checkedLayers()
print(checked_layers)
[<QgsVectorLayer: 'countries' (ogr)>]

Ora aggiungiamo alcuni layer all’albero dei layer del progetto. Ci sono due modi per farlo:

  1. Explicit addition usando il addLayer() o insertLayer() functions:

    1# create a temporary layer
    2layer1 = QgsVectorLayer("path_to_layer", "Layer 1", "memory")
    3# add the layer to the legend, last position
    4root.addLayer(layer1)
    5# add the layer at given position
    6root.insertLayer(5, layer1)
    
  2. Aggiunta implicita: poiché l’albero dei layer del progetto è collegato al registro dei layer, è sufficiente aggiungere un layer al registro dei layer della mappa:

    QgsProject.instance().addMapLayer(layer1)
    

Puoi passare facilmente da QgsVectorLayer a QgsLayerTreeLayer:

node_layer = root.findLayer(country_layer.id())
print("Layer node:", node_layer)
print("Map layer:", node_layer.layer())
Layer node: <QgsLayerTreeLayer: countries>
Map layer: <QgsVectorLayer: 'countries' (ogr)>

I gruppi possono essere aggiunti con il metodo addGroup(). Nell’esempio che segue, il primo aggiungerà un gruppo alla fine della legenda, mentre il secondo può aggiungere un altro gruppo all’interno di uno esistente:

node_group1 = root.addGroup('Simple Group')
# add a sub-group to Simple Group
node_subgroup1 = node_group1.addGroup("I'm a sub group")

Per spostare nodi e gruppi esistono molti metodi validi.

Lo spostamento di un nodo esistente avviene in tre passi:

  1. clonazione del nodo esistente

  2. spostamento del nodo clonato nella posizione desiderata

  3. eliminazione del nodo originale

1# clone the group
2cloned_group1 = node_group1.clone()
3# move the node (along with sub-groups and layers) to the top
4root.insertChildNode(0, cloned_group1)
5# remove the original node
6root.removeChildNode(node_group1)

È un po” più complicato spostare un layer nella legenda:

 1# get a QgsVectorLayer
 2vl = QgsProject.instance().mapLayersByName("countries")[0]
 3# create a QgsLayerTreeLayer object from vl by its id
 4myvl = root.findLayer(vl.id())
 5# clone the myvl QgsLayerTreeLayer object
 6myvlclone = myvl.clone()
 7# get the parent. If None (layer is not in group) returns ''
 8parent = myvl.parent()
 9# move the cloned layer to the top (0)
10parent.insertChildNode(0, myvlclone)
11# remove the original myvl
12root.removeChildNode(myvl)

o spostarlo in un gruppo esistente:

 1# get a QgsVectorLayer
 2vl = QgsProject.instance().mapLayersByName("countries")[0]
 3# create a QgsLayerTreeLayer object from vl by its id
 4myvl = root.findLayer(vl.id())
 5# clone the myvl QgsLayerTreeLayer object
 6myvlclone = myvl.clone()
 7# create a new group
 8group1 = root.addGroup("Group1")
 9# get the parent. If None (layer is not in group) returns ''
10parent = myvl.parent()
11# move the cloned layer to the top (0)
12group1.insertChildNode(0, myvlclone)
13# remove the QgsLayerTreeLayer from its parent
14parent.removeChildNode(myvl)

Alcuni altri metodi che possono essere utilizzati per modificare gruppi e layer:

 1node_group1 = root.findGroup("Group1")
 2# change the name of the group
 3node_group1.setName("Group X")
 4node_layer2 = root.findLayer(country_layer.id())
 5# change the name of the layer
 6node_layer2.setName("Layer X")
 7# change the visibility of a layer
 8node_group1.setItemVisibilityChecked(True)
 9node_layer2.setItemVisibilityChecked(False)
10# expand/collapse the group view
11node_group1.setExpanded(True)
12node_group1.setExpanded(False)