10 votos

¿Cómo mover las capas en el Panel de Ordenación de Capas utilizando PyQGIS?

Relacionado con la siguiente pregunta pero buscando un método de PyQGIS:

Panel de orden de capas de QGIS - añadir capas en la parte superior del orden de capas


A continuación se muestra una configuración sencilla que contiene un grupo con tres capas.

Simple setup

El código que utilizo añade una nueva capa en el fin de este grupo :

root = QgsProject.instance().layerTreeRoot()
group = root.findGroup('Main group')

vlayer = QgsVectorLayer('LineString?crs=epsg:27700', 'vlayer', 'memory')
QgsMapLayerRegistry.instance().addMapLayer(vlayer, False)
group.insertChildNode(-1, QgsLayerTreeLayer(vlayer))  

New layer added at end of group

En el Panel de orden de capas La capa recién añadida está al final.

Layer Order Panel


¿Es posible mover esto a la parte superior sin mover la capa en el Panel de capas ?

8voto

Elliott Maynard Puntos 11

Puede establecer el orden de las capas en el Layer Order Panel " manualmente " utilizando QgsLayerTreeCanvasBridge.setCustomLayerOrder() que recibe una lista ordenada de identificadores de capas. Por ejemplo (suponiendo que acaba de cargar vlayer ):

bridge = iface.layerTreeCanvasBridge() 
order = bridge.customLayerOrder()
order.insert( 0, order.pop( order.index( vlayer.id() ) ) ) # vlayer to the top
bridge.setCustomLayerOrder( order )

A automáticamente mover las capas recién añadidas a la parte superior de Layer Order Panel , podría utilizar el legendLayersAdded SIGNAL (esta señal es apropiada porque se emite después del Layer Order Panel obtiene la nueva capa) de QgsMapLayerRegistry y reordenar las capas de esta manera:

def rearrange( layers ):
    order = iface.layerTreeCanvasBridge().customLayerOrder()
    for layer in layers: # How many layers we need to move
        order.insert( 0, order.pop() ) # Last layer to first position
    iface.layerTreeCanvasBridge().setCustomLayerOrder( order )

QgsMapLayerRegistry.instance().legendLayersAdded.connect( rearrange )

NOTA: Dado que está cargando su vlayer llamando a QgsMapLayerRegistry.instance().addMapLayer(vlayer, False) que False impide que el legendLayersAdded SEÑAL de ser emitida. Por lo tanto, el enfoque automático no funcionará en su caso y tendrá que reorganizar las capas manualmente (primer enfoque de esta respuesta).

0 votos

Soy inexperto en el uso de Python en QGIS- ¿Dónde se introduce este texto script? ¿Se guarda en el archivo específico del proyecto QGIS?

0 votos

Está pensado para ser ejecutado en la consola de QGIS Python. Si necesitas que sea más duradero, consulta esta respuesta para ver cómo se puede ejecutar un fragmento de código cada vez que se abra QGIS o cada vez que se abra un proyecto QGIS en particular: gis.stackexchange.com/questions/194055/

8voto

Jurgen Puntos 116

Hola, siento no poder comentar, pero el método "bridge.customLayerOrder()" no existe en QGis 3.x

He encontrado tal vez un comando sustituto:

bridge = iface.layerTreeCanvasBridge() 
bridge.rootGroup().customLayerOrder()

Desde https://qgis.org/api/classQgsLayerTree.html#aab7a55f2e61f0ff1dbea6ceb89e8b366 :

El orden en el que las capas se renderizarán en el lienzo. Sólo se utilizará si la propiedad hasCustomLayerOrder es verdadera. Si necesitas el orden actual de las capas que están activas, prefiere usar layerOrder().

Espero que sea útil para los demás.

Riccardo

2voto

Houska Puntos 121

Basado en esta (vieja) pregunta y algunas otras investigaciones, he añadido con éxito un controlador a mi proyecto QGIS 3.10 para mover todas las capas recién añadidas a la parte superior del orden de capas personalizado. Aquí está el código de la macro del proyecto relevante con referencias a objetos v3.

from qgis.core import QgsProject
from qgis.utils import iface

def openProject():
    global layersToTopHandler # keep so can disconnect() it in closeProject()
    def layersToTopHandler( layers ):
        # moves last len(layers) layers to top of custom layer order
        # note pays no attention to what is in the list given, always moves bottom layers
        # intended as a legendLayersAdded signal handler so the new layers have just been put at bottom! 
        rg = iface.layerTreeCanvasBridge().rootGroup()
        if rg.hasCustomLayerOrder():
            # Only do anything if custom layer order is turned on
            order = rg.customLayerOrder()
            for layer in layers: # How many layers we need to move
                order.insert( 0, order.pop() ) # Last layer to first position
            rg.setCustomLayerOrder( order )
    QgsProject.instance().legendLayersAdded.connect( layersToTopHandler )

def saveProject():
    pass

def closeProject():
    QgsProject.instance().legendLayersAdded.disconnect(layersToTopHandler)
    # needed since otherwise signal would go to slot even when change projects 

Editar : Mi respuesta originalmente no tenía la global línea y sólo un disconnect() en closeProject() . Esto falló sutilmente en 3.10.2 (imposibilitando la adición de capas en un proyecto abierto posteriormente) ya que el argumento disconnect() también se desprendería de algunas ranuras del núcleo en esta señal. Puede haber formas más elegantes de mantener un seguimiento de nuestra propia ranura que globalizar el propio manejador de eventos, pero esto parece funcionar. Es tentador no molestarse en desconectar, asumiendo que cerrar el proyecto y abrir uno nuevo reiniciará todo, pero las ranuras/señales permanecen persistentes.

0 votos

Gracias por tu respuesta, esto será útil para saber cuando porte el código correspondiente a QGIS 3 :)

1voto

Sushant23 Puntos 329

No estoy muy familiarizado con pyqgis, pero cuando cambié la línea en su código de

group.insertChildNode(-1, QgsLayerTreeLayer(vlayer)) 

a

group.insertChildNode(0, QgsLayerTreeLayer(vlayer)) 

Se insertó en la parte superior del grupo, no en la inferior.

1 votos

Gracias por su respuesta, tiene razón en cuanto a la sustitución -1 con 0 coloca la capa en la parte superior del Panel de capas pero no en el Panel de orden de capas . Además, me gustaría que la nueva capa se añadiera a la parte inferior del Panel de capas :)

1 votos

Tienes razón, me lo perdí.

1 votos

Sería una especie de solución para añadir la capa en la parte superior del grupo y desactivar el Control rendering order ya que esto colocaría la capa en la parte superior del Panel de orden de capas . Pero para mi caso de uso, no sería ordenado :)

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X