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:
Explicit addition usando il
addLayer()
oinsertLayer()
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)
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:
clonazione del nodo esistente
spostamento del nodo clonato nella posizione desiderata
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)