I've edited your code a bit to contain a couple of functions to call these instead of repeating similar lines of code for each layer. I only tested the functions which loads the style and reorders the layers which seems to work. Assume this code is untested but hopefully this will help avoid the error:
##Select_MasterMap_Folder=folder
import os,sys
from qgis.core import*
from PyQt4.QtCore import*
from qgis.utils import*
from qgis.gui import *
import qgis
source_dir=(Select_MasterMap_Folder)
for files in os.listdir(source_dir):
# load only the shapefiles
if files.endswith("Area.shp"):
vlayer = QgsVectorLayer(source_dir + "/" + files, files[0:11]+" "+files[11:15], "ogr")
# add layer to the registry
QgsMapLayerRegistry.instance().addMapLayer(vlayer)
if files.endswith("cLine.shp"):
vlayer = QgsVectorLayer(source_dir + "/" + files, files[0:11]+" "+files[11:15], "ogr")
QgsMapLayerRegistry.instance().addMapLayer(vlayer)
if files.endswith("Point.shp"):
vlayer = QgsVectorLayer(source_dir + "/" + files, files[0:11]+" "+files[11:16], "ogr")
QgsMapLayerRegistry.instance().addMapLayer(vlayer)
if files.endswith("Text.shp"):
vlayer = QgsVectorLayer(source_dir + "/" + files, files[0:12]+" "+files[12:16], "ogr")
QgsMapLayerRegistry.instance().addMapLayer(vlayer)
vl = QgsMapLayerRegistry.instance().mapLayersByName('Topographic Line')[0]
iface.setActiveLayer(vl)
iface = qgis.utils.iface; vl = iface.activeLayer(); iface.addVectorLayer(vl.source(), vl.name() + " copy", vl.providerType())
vl = QgsMapLayerRegistry.instance().mapLayersByName('Topographic Area')[0]
iface.setActiveLayer(vl)
iface = qgis.utils.iface; vl = iface.activeLayer(); iface.addVectorLayer(vl.source(), vl.name() + " copy", vl.providerType())
qgis.utils.iface.mapCanvas().refresh()
root = QgsProject.instance().layerTreeRoot()
layers = QgsMapLayerRegistry.instance().mapLayers().values()
style_path = 'P:/Office Admin/GIS/Templates/MasterMap styles for QGIS/Emapsite NEW MasterMap styles/'
def load_style(layer, qml):
layer.loadNamedStyle(style_path + qml)
def reorder_layers(layer, node):
myalayer = root.findLayer(layer.id())
myClone = myalayer.clone()
parent = myalayer.parent()
parent.insertChildNode(node, myClone)
parent.removeChildNode(myalayer)
for i in layers:
if i.name() == "Topographic Point":
load_style(i, '1TopographicPoint.qml')
reorder_layers(i, 0)
if i.name() == "Cartographic Text":
load_style(i, '2CartographicText.qml')
reorder_layers(i, 1)
if i.name() == "Topographic Line":
load_style(i, '3TopographicLine.qml')
reorder_layers(i, 2)
if i.name() == "Topographic Line copy":
load_style(i, '4TopographicLineCopy.qml')
reorder_layers(i, 3)
if i.name() == "Topographic Area":
load_style(i, '5TopographicArea.qml')
reorder_layers(i, 4)
if i.name() == "Topographic Area copy":
load_style(i, '6TopographicAreaCopy.qml')
reorder_layers(i, 5)
else:
pass
qgis.utils.iface.mapCanvas().refresh()
You could use the following to sort all loaded layers alphabetically:
from collections import OrderedDict
root = QgsProject.instance().layerTreeRoot()
LayerNamesEnumDict=lambda listCh:{listCh[q[0]].name()+str(q[0]):q[1]
for q in enumerate(listCh)}
mLNED = LayerNamesEnumDict(root.children())
mLNEDkeys = OrderedDict(sorted(LayerNamesEnumDict(root.children()).items())).keys()
mLNEDsorted = [mLNED[k].clone() for k in mLNEDkeys]
root.insertChildNodes(0,mLNEDsorted)
for n in mLNED.values():
root.removeChildNode(n)
Credit to @MikhailMinin with his Sort Layers plugin in which the above code is based.
Best Answer
With the new (since QGIS v.2.4) Layer tree by Martin Dobias, you can do this:
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.