6

I have loaded two layers in canvas and would like to move the layers using the following code in TOC, but it is not moving the layers to the position based on the index given.

from PyQt4.QtCore import *
from PyQt4.QtGui import *

from qgis.core import *
from qgis.gui import *
import qgis.utils

canvas = qgis.utils.iface.mapCanvas()
layers = canvas.layers()

for i in layers:
  if i.name() == "Layer2":
    alayer = i
  elif i.name() == "Layer1":
    blayer = i

qgis.utils.iface.legendInterface().moveLayer(alayer, 0)
qgis.utils.iface.legendInterface().moveLayer(blayer, 1)
canvas.refresh()

How can I do that?

  • I would like to move the layers based on the index given. I am able to refresh the canvas but where as the layer TOC is not getting updated... – Pugazh Feb 13 '15 at 11:35
11

With the new (since QGIS v.2.4) Layer tree by Martin Dobias, you can do this:

alayer = QgsMapLayerRegistry.instance().mapLayersByName("Layer2")[0]
blayer = QgsMapLayerRegistry.instance().mapLayersByName("Layer1")[0]

root = QgsProject.instance().layerTreeRoot()

# Move alayer
myalayer = root.findLayer(alayer.id())
myClone = myalayer.clone()
parent = myalayer.parent()
parent.insertChildNode(0, myClone)
parent.removeChildNode(myalayer)

# Move blayer
myblayer = root.findLayer(blayer.id())
myClone = myblayer.clone()
parent = myblayer.parent()
parent.insertChildNode(1, myClone)
parent.removeChildNode(myblayer)

As you see, to move the layer alayer you first clone it, insert the clone at the desired position*, and remove the original.

You can see more on Layer tree handling here and here.

Note that if your original layer is at the position 0 and you want to move it to 1, you would need to insert it at the position 2 (instead of 1), because when the clone is inserted, the original layer is still there, so its index must be taken into account.

  • 1
    PyQGIS is pretty powerful with its capabilities but it can't do something simple as moving a layer in TOC? Couldn't the index of the layer's position automatically change to the next index if a new layer takes over its position? Or is nothing like this implemented yet? I'm just curious, oh and +1 :) – Joseph Feb 13 '15 at 12:02
  • 1
    @Joseph Yes, I agree that's not the neatest way to expose such functionality, but believe me, it is better than with the previous legend (ToC). I hope someone has the opportunity to wrap all this into a moveLayer(layer, position) function directly in the QGIS API. – Germán Carrillo Feb 13 '15 at 12:08
  • Thanks for clarifying! Yes, hopefully that functionality can get implemented. – Joseph Feb 13 '15 at 12:09
  • 1
    @Joseph open a ticket for it with your ideas, or if you have the skills you are more then welcome to add it yourself. – Nathan W Feb 13 '15 at 12:29
  • 1
    @NathanW - Thanks, opened a ticket here, (I wish I had the skills to add it!). – Joseph Feb 13 '15 at 12:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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