QGIS 3 – Move Layer to Group

python 3qgis-3table of contents

In the layer tree, I want to move a few layers at root level to a group also at root level.
From what I have gathered so far, I have to clone the layer first, add it to the group and then delete the original layer.

https://docs.qgis.org/3.4/en/docs/pyqgis_developer_cookbook/cheat_sheet.html#advanced-toc

So I am trying to fill the variables with the group and layers I want to work with.
The for-loop finds the group, but for some reason, I am getting None for the value of LyrOne.

from qgis.core import QgsLayerTreeGroup, QgsLayerTreeLayer
root = QgsProject.instance().layerTreeRoot()

for child in root.children():
    if isinstance(child, QgsLayerTreeGroup):
        print ("- group: " + child.name())
    elif isinstance(child, QgsLayerTreeLayer):
        print ("- layer: " + child.name())

grpQS = root.findGroup("QS")
LyrOne = root.findLayer("One")
print(QS_group)
print(LyrOne)

The results of the for-loop and the print statements are:

- layer: One
- group: QS
<qgis._core.QgsLayerTreeGroup object at 0x0000000008032A68>
None

Why can I get a reference to the group, but not for the layer?

EDIT:
I managed to create a dictionary with the names of the layers as keys

dictLayer = {}
for child in root.children():
    if isinstance(child, QgsLayerTreeLayer):
        lyrName = child.name()
        lyrID = child.layerId()
        dictLayer[lyrName] = lyrID

LyrOne = dictLayer["One"]

Unfortunately, this solution
Add layer to a QGIS group using Python

toc = self.iface.legendInterface()
groups = toc.groups()
groupIndex = groups.index(u'myGroup')
toc.moveLayer(newLayer, groupIndex)

doesn't work in QGIS3.
How can I move a layer to a group in QGIS 3?

Best Answer

If you look at the API, the findGroup() method need a String "name value" but findLayer() need a Layer Id not the name.

Then to make it work you need this:

from qgis.core import QgsLayerTreeGroup, QgsLayerTreeLayer
root = QgsProject.instance().layerTreeRoot()

for child in root.children():
    if isinstance(child, QgsLayerTreeGroup):
        print ("- group: " + child.name())
    elif isinstance(child, QgsLayerTreeLayer):
        print ("- layer: " + child.layerId())

Move Loaded layer:

layer = QgsProject.instance().mapLayersByName(<layer_name>)[0]
root = QgsProject.instance().layerTreeRoot()

mylayer = root.findLayer(layer.id())
myClone = mylayer.clone()
parent = mylayer.parent()

group = root.findGroup(<group_name>)
group.insertChildNode(0, myClone)

parent.removeChildNode(mylayer)

Load layer in a specific group

layer = QgsVectorLayer(<layer_path>, "airports", "ogr")

QgsProject.instance().addMapLayer(layer, False)

root = QgsProject.instance().layerTreeRoot()
g = root.findGroup(<group_name>)
g.insertChildNode(0, QgsLayerTreeLayer(layer))
Related Question