2

I've got a layer (difflayer) that has been created in memory. Basically, all the layers I've got in this project are in memory and the layer creation/manipulation is all being handled via a plugin.

Now, from looking around it seems the best way to move a layer around is to clone() it, use insertChildNode to add the clone, and then delete the original. Which I'd have no problem doing, except that layers in memory don't support clone().

Does anyone have any ideas? I've also tried to duplicate the layer using the below code but get the following error:

feats = [feat for feat in difflayer.getFeatures()]
mem_layer = QgsVectorLayer("Polygon?crs=EPSG:4283&field=ID:integer", "dup layer", "memory")
mem_layer_data = mem_layer.dataProvider()
attr = difflayer.dataProvider().fields().toList()
mem_layer_data.addAttributes(attr)
mem_layer.updateFields()
mem_layer_data.addFeatures(feats)
root = QgsProject.instance().layerTreeRoot()
root.insertChildNode(2,mem_layer)

TypeError: QgsLayerTreeGroup.insertChildNode(int, QgsLayerTreeNode): argument 2 has unexpected type 'QgsVectorLayer'

2
  • Is your question "why does this code snippet doesn't work" ? Did you correct the syntax error of the last line ? Did you check the difference between QgsLayerTreeNode and QgsVectorLayer in the API ?
    – Snaileater
    Commented Sep 20, 2019 at 10:38
  • You need to use 'insertLayer' method of QgsLayerTreeGroup instead 'insertChildNode' method.
    – xunilk
    Commented Sep 20, 2019 at 13:10

1 Answer 1

4

The TypeError is correct: argument 2 has unexpected type 'QgsVectorLayer'. It can be easily corroborated with help(QgsLayerTreeGroup.insertChildNode).

So, I used following code for creating a memory layer:

point = QgsPointXY(395065.34243502904, 4443021.813507973)

epsg = 32612

uri = "Point?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           'point',
                           'memory')

prov = mem_layer.dataProvider()

feat = QgsFeature()

feat.setAttributes([0])
feat.setGeometry(QgsGeometry.fromPointXY(point))

prov.addFeature(feat)

registry = QgsProject.instance()

registry.addMapLayer(mem_layer)

and I loaded three additional layers to Map View of QGIS. Group looks as follows; where point is a memory layer.

enter image description here

Following code pretends to 'clone' point memory layer (layers[0]) between polygon8 and random layers. However, 'insertLayer' method of QgsLayerTreeGroup is used instead 'insertChildNode' (because in the first case argument 2 can be of type 'QgsVectorLayer').

registry = QgsProject.instance()

layers = list(registry.mapLayers().values())

root = registry.layerTreeRoot()

root.insertLayer(3, layers[0])

After running above code, result was as expected; as it can be corroborated in following image. So, memory does support methods of QgsLayerTreeGroup.

enter image description here

1
  • This works, though I neglected to mention I was using QGIS 2.18. So layers = list(registry.mapLayers().values()) becomes layers = iface.legendInterface().layers()
    – user25730
    Commented Sep 23, 2019 at 1:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.