4. Accessing the Table Of Contents (TOC)
Dica
Os <i>snippets</i> de código nesta página precisam das seguintes importações se estiver fora da console pyqgis:
from qgis.core import (
QgsProject,
QgsVectorLayer,
)
You can use different classes to access all the loaded layers in the TOC and use them to retrieve information:
4.1. The QgsProject class
You can use QgsProject
to retrieve information
about the TOC and all the layers loaded.
You have to create an instance
of QgsProject
and use its methods to get the loaded layers.
The main method is mapLayers()
. It will
return a dictionary of the loaded layers:
layers = QgsProject.instance().mapLayers()
print(layers)
{'countries_89ae1b0f_f41b_4f42_bca4_caf55ddbe4b6': <QgsVectorLayer: 'countries' (ogr)>}
The dictionary keys
are the unique layer ids while the values
are the
related objects.
It is now straightforward to obtain any other information about the layers:
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)>}
You can also query the TOC using the name of the layer:
country_layer = QgsProject.instance().mapLayersByName("countries")[0]
Nota
A list with all the matching layers is returned, so we index with
[0]
to get the first layer with this name.
4.2. QgsLayerTreeGroup class
The layer tree is a classical tree structure built of nodes. There are currently
two types of nodes: group nodes (QgsLayerTreeGroup
)
and layer nodes (QgsLayerTreeLayer
).
The project layer tree can be accessed easily with the method layerTreeRoot()
of the QgsProject
class:
root = QgsProject.instance().layerTreeRoot()
root
is a group node and has children:
root.children()
A list of direct children is returned. Sub group children should be accessed from their own direct parent.
We can retrieve one of the children:
child0 = root.children()[0]
print(child0)
<QgsLayerTreeLayer: countries>
Layers can also be retrieved using their (unique) id
:
ids = root.findLayerIds()
# access the first layer of the ids list
root.findLayer(ids[0])
And groups can also be searched using their names:
root.findGroup('Group Name')
QgsLayerTreeGroup
has many other useful
methods that can be used to obtain more information about the TOC:
# list of all the checked layers in the TOC
checked_layers = root.checkedLayers()
print(checked_layers)
[<QgsVectorLayer: 'countries' (ogr)>]
Now let’s add some layers to the project’s layer tree. There are two ways of doing that:
Explicit addition using the
addLayer()
orinsertLayer()
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)
Implicit addition: since the project’s layer tree is connected to the layer registry it is enough to add a layer to the map layer registry:
QgsProject.instance().addMapLayer(layer1)
You can switch between QgsVectorLayer
and
QgsLayerTreeLayer
easily:
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)>
Groups can be added with the addGroup()
method. In the example below, the former will add a group to the end of the TOC
while for the latter you can add another group within an existing one:
node_group1 = root.addGroup('Simple Group')
# add a sub-group to Simple Group
node_subgroup1 = node_group1.addGroup("I'm a sub group")
To moving nodes and groups there are many useful methods.
Moving an existing node is done in three steps:
cloning the existing node
moving the cloned node to the desired position
deleting the original node
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)
It is a little bit more complicated to move a layer around in the legend:
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)
or moving it to an existing group:
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)
Some other methods that can be used to modify the groups and layers:
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)