중요

번역은 여러분이 참여할 수 있는 커뮤니티 활동입니다. 이 페이지는 현재 100.00% 번역되었습니다.

4. TOC(Table Of Contents)에 접근하기

힌트

PyQGIS 콘솔을 사용하지 않는 경우 이 페이지에 있는 코드 조각들을 다음과 같이 가져와야 합니다:

from qgis.core import (
    QgsProject,
    QgsVectorLayer,
)

서로 다른 클래스들을 사용해서 차례(Table Of Contents)에 불러온 모든 레이어에 접근할 수 있으며, 다음 클래스들을 통해 정보를 검색할 수 있습니다:

4.1. QgsProject 클래스

QgsProject 클래스를 사용하면 차례 및 불러온 모든 레이어에 대한 정보를 검색할 수 있습니다.

불러온 레이어들을 가져오려면 QgsProject 클래스의 instance 를 생성하고 이 클래스의 메소드를 사용해야 합니다.

주 메소드는 mapLayers() 입니다. 이 메소드가 불러온 레이어들의 목록(dictionary)을 반환할 것입니다:

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

이 목록의 keys 는 유일한 레이어 ID이고 values 는 관련 객체입니다.

이제 레이어에 대한 다른 모든 정보를 간단하게 얻을 수 있습니다:

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)>}

레이어의 이름을 사용해서 차례도 쿼리할 수 있습니다:

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

참고

이름이 일치하는 모든 레이어들의 목록을 반환하기 때문에, 이 이름을 가진 첫 번째 레이어를 가져오기 위해 [0] 인덱스를 사용합니다.

4.2. QgsLayerTreeGroup 클래스

레이어 트리는 노드(node)들로 구성된 전통적인 트리 구조입니다. 현재 두 가지 노드 유형이 존재합니다: 그룹 노드(QgsLayerTreeGroup)와 레이어 노드(QgsLayerTreeLayer)입니다.

참고

더 자세한 정보를 알고 싶다면 마르틴 도비아시(Martin Dobiáš)의 블로그 포스트를 읽어보세요: 1편 , 2편 , 3편

QgsProject 클래스의 layerTreeRoot() 메소드를 사용하면 프로젝트 레이어 트리에 쉽게 접근할 수 있습니다:

root = QgsProject.instance().layerTreeRoot()

root 는 그룹 노드이며 하위(children) 노드를 가지고 있습니다:

root.children()

직계 하위 노드 목록을 반환합니다. 하위 그룹 노드는 그 직계 상위 노드로부터 접근해야 합니다.

하위 노드 가운데 하나를 검색할 수 있습니다:

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

레이어의 (유일) id 를 사용해서도 레이어를 검색할 수 있습니다:

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

그리고 그룹의 이름을 사용해서도 그룹을 검색할 수 있습니다:

root.findGroup('Group Name')

QgsLayerTreeGroup 클래스는 차례에 대한 더 많은 정보를 가져오는 데 사용할 수 있는 유용한 다른 메소드들을 다수 가지고 있습니다:

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

이제 프로젝트의 레이어 트리에 레이어를 몇 개 추가해봅시다. 두 가지 방법이 있습니다:

  1. 명시적 추가addLayer() 또는 insertLayer() 함수를 사용합니다:

    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. 암시적 추가 — 프로젝트의 레이어 트리가 레이어 레지스트리와 연결돼 있기 때문에 맵 레이어 레지스트리에 레이어를 추가해주는 것으로 충분합니다:

    QgsProject.instance().addMapLayer(layer1)
    

QgsVectorLayerQgsLayerTreeLayer 클래스를 쉽게 전환할 수 있습니다:

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)>

addGroup() 메소드를 사용하면 그룹을 쉽게 추가할 수 있습니다. 다음 예시에서, 전자는 차례의 마지막에 그룹을 추가할 것이지만 후자의 경우 기존 그룹 안에 또다른 그룹을 추가할 수 있습니다:

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

노드 및 그룹을 이동시키고 싶다면, 유용한 메소드들이 많이 있습니다.

기존 노드의 이동은 세 단계로 이루어집니다:

  1. 기존 노드 복제

  2. 복제한 노드를 원하는 위치로 이동

  3. 원본 노드 삭제

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)

범례에서 레이어를 이동시키는 작업은 좀 더 복잡합니다:

 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)

또는 기존 그룹으로 이동시키는 작업도 그렇죠:

 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)

몇몇 다른 메소드들을 사용해서 그룹과 레이어를 수정할 수 있습니다:

 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)