4. 目次(TOC)へのアクセス

ヒント

pyqgisコンソールの外部にいる場合、このページのコードスニペットでは以下のインポートが必要になります:

from qgis.core import (
    QgsProject,
    QgsVectorLayer,
)

さまざまなクラスを使用して、TOCにロードされているすべてのレイヤーにアクセスし、それらを使用して情報を取得できます:

4.1. QgsProject クラス

QgsProject を使うと、TOCとロードされた全てのレイヤに関する情報を取得することができます。

QgsProject の「インスタンス」を作成し、そのメソッドを使用してロードされたレイヤを取得する必要があります。

メインメソッドは mapLayers() です。ロードされたレイヤの辞書を返します:

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

また、レイヤの名前でTOCを照会することも可能です:

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

注釈

一致するすべてのレイヤを含んだリストが返されるため、 [0] でインデックスを作成して、この名前の最初のレイヤを取得します。

4.2. QgsLayerTreeGroup クラス

レイヤツリーは、ノードで構築された古典的なツリー構造です。現在、ノードには2つのタイプがあります:グループノード( QgsLayerTreeGroup )とレイヤノード( QgsLayerTreeLayer )。

注釈

詳細については、MartinDobiasのこれらのブログ投稿を読むことができます: Part 1 Part 2 Part 3

プロジェクトのレイヤツリーには QgsProject クラスの layerTreeRoot() メソッドで容易にアクセスすることができます:

root = QgsProject.instance().layerTreeRoot()

root はグループノードであり、 を持っています:

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 はTOCに関するより多くの情報を得るために使用できる多くの便利なメソッドを備えています:

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

では、プロジェクトのレイヤツリーにいくつかのレイヤを追加してみましょう。これには2つの方法があります:

  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() メソッドで追加できます。以下の例では、前者はTOCの最後にグループを追加し、後者の場合は既存のグループ内に別のグループを追加できます:

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

ノードとグループを移動するには、多くの便利な方法があります。

既存のノードの移動は、次の3つのステップで実行されます:

  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)