跳转至

4 访问图层目录树⚓︎

此页面上的代码片段需要导入以下模块:

1
2
3
4
from qgis.core import (
    QgsProject,
    QgsVectorLayer,
)

4.1 QgsProject类⚓︎

可以使用QgsProject检索有关目录和所有已加载图层的信息。

必须创建QgsProject的实例instance,并使用其方法(函数)来获取已加载的图层。

mapLayers方法返回已加载图层的字典:

1
2
3
4
layers = QgsProject.instance().mapLayers()
print(layers)

# {'countries_89ae1b0f_f41b_4f42_bca4_caf55ddbe4b6': <QgsMapLayer: 'countries' (ogr)>}

字典的keys是图层的唯一id,而values是图层的对象。

现在直接去获得有关图层的任何其他信息:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 使用列表表达式获得图层名称
l = [layer.name() for layer in QgsProject.instance().mapLayers().values()]
# 键值对存储图层名称和图层对象
layers_list = {}
for l in QgsProject.instance().mapLayers().values():
  layers_list[l.name()] = l

print(layers_list)

# {'countries': <QgsMapLayer: 'countries' (ogr)>}

还可以使用图层名称查询目录:

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

提示

返回所有匹配图层的列表,因此我们使用索引[0]获取第一个图层。

4.2 QgsLayerTreeGroup类⚓︎

图层树是由节点构建的经典树结构。当前有两种类型的节点:图层组节点(QgsLayerTreeGroup)和图层节点(QgsLayerTreeLayer)。

提示

更多信息请访问Martin Dobias的博客

可以使用QgsProject类的layerLayerRoot()方法轻松访问项目图层树:

1
root = QgsProject.instance().layerTreeRoot()

root是一个图层组节点,具有子节点:

1
root.children()

返回直接子节点列表。子组节点可以从他们自己的直接父级访问。

我们可以检索其中一个子节点:

1
2
3
4
child0 = root.children()[0]
print(child0)

# <qgis._core.QgsLayerTreeLayer object at 0x7f1e1ea54168>

可以使用它们的唯一id来检索:

1
2
3
ids = root.findLayerIds()
#  访问第一个图层
root.findLayer(ids[0])

可以使用图层组名称检索:

1
root.findGroup('Group Name')

QgsLayerTreeGroup还有许多其他有用的方法,可用于获取有关目录树的更多信息:

1
2
3
4
5
# 获得所有已选图层
checked_layers = root.checkedLayers()
print(checked_layers)

# [<QgsMapLayer: 'countries' (ogr)>]

现在,我们把一些图层添加到项目的图层树中,有两种方法可以做到:

  1. 显式添加: 使用addLayer()或者insertLayer()方法:
1
2
3
4
5
6
# 创建临时图层
layer1 = QgsVectorLayer("path_to_layer", "Layer 1", "memory")
# 添加图层到图层树末尾
root.addLayer(layer1)
# 插入图层到指定位置
root.insertLayer(5, layer1)
  1. 隐式添加: 由于项目的图层树已连接到图层注册表,因此可以在图层注册表中添加图层:
1
QgsProject.instance().addMapLayer(layer1)

你可以轻松地在QgsVectorLayerQgsLayerTreeLayer之间切换:

1
2
3
4
5
6
node_layer = root.findLayer(country_layer.id())
print("Layer node:", node_layer)
print("Map layer:", node_layer.layer())

# Layer node: <qgis._core.QgsLayerTreeLayer object at 0x7fecceb46ca8>
# Map layer: <QgsMapLayer: 'countries' (ogr)>

可以使用addGroup()方法添加组。在下面的示例中,前者将在目录树的末尾添加一个组,而后者则可以在现有的组中添加另一个组:

1
2
3
node_group1 = root.addGroup('Simple Group')
# 在图层组中添加子组
node_subgroup1 = node_group1.addGroup("I'm a sub group")

移动节点和组有许多有用的方法。

移动现有节点分三个步骤:

  1. 克隆已存在的节点
  2. 移动克隆的节点到想要的位置
  3. 删除原始节点
1
2
3
4
5
6
# 克隆图层组
cloned_group1 = node_group1.clone()
# 移动图层组(包括子组和图层)到顶层
root.insertChildNode(0, cloned_group1)
# 删除原始图层组节点
root.removeChildNode(node_group1)

移动一个图层要稍微复杂一点:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 获得一个图层
vl = QgsProject.instance().mapLayersByName("countries")[0]
# 从图层树中获取
myvl = root.findLayer(vl.id())
# 克隆
myvlclone = myvl.clone()
# 获取父级,如果图层不在图层组中返回空字符串
parent = myvl.parent()
# 移动图层节点到顶层
parent.insertChildNode(0, myvlclone)
# 删除原有节点
root.removeChildNode(myvl)

或者移动到已存在的图层组中:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 获得一个图层
vl = QgsProject.instance().mapLayersByName("countries")[0]
# 从图层树中获取
myvl = root.findLayer(vl.id())
# 克隆
myvlclone = myvl.clone()
# 创建一个新组
group1 = root.addGroup("Group1")
# 获取父级,如果图层不在图层组中返回空字符串
parent = myvl.parent()
# 移动图层节点到顶层
group1.insertChildNode(0, myvlclone)
# 从原有组中删除
parent.removeChildNode(myvl)

可用于修改组和图层的其他一些方法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
node_group1 = root.findGroup("Group1")
# 修改图层组名称
node_group1.setName("Group X")
node_layer2 = root.findLayer(country_layer.id())
# 修改图层名称
node_layer2.setName("Layer X")
# 改变图层可见状态
node_group1.setItemVisibilityChecked(True)
node_layer2.setItemVisibilityChecked(False)
# 折叠/展开图层组
node_group1.setExpanded(True)
node_group1.setExpanded(False)