jueves, 8 de marzo de 2018

Cómo conectar una QComboBox para actualizar adecuadamente las capas en un plugin con QGIS 3

En un post anterior se trataba el mismo tema para la versión anterior de QGIS. Empleaba la clase QgsLegendInterface que actualmente fue removida en QGIS 3. Este documento señala que la remoción fue realizada en favor de la clase QgsLayerTreeNode y otras no especifícadas.

Para averiguar cuáles son esas otras clases posibles utilizo mi plugin Get Pattern para las clases core y gui y la palabra clave Tree. Los resultados pueden observarse en la imagen siguiente:


Aunque la oferta es amplia (21 clases) lo que ahora hay que averiguar es cuál es el método de iface que convierte a alguna de las clases anteriores. La palabra clave sigue siendo Tree y el número de ellas ahora si se reduce ampliamente; tal como se observa a continuación:


En la Python Console se averiguan cuáles son esas posibles clases y sólo los dos últimos métodos arrojan resultados: QgsLayerTreeMapCanvasBridge y QgsLayerTreeView. Ahora lo que resta es averiguar en esas dos clases, con la palabra clave Changed, cuál arroja un método que verifique cambio de "layers" y pueda conectarse a un slot. El resultado puede observarse a continuación y es la clase QgsLayerTreeMapCanvasBridge con el método 'canvasLayersChanged'.


Por tanto, el código en el plugin puede modificarse como sigue para que funcione de la manera esperada.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
.
.
.
    def __init__(self, iface):
.
.
.
        self.dlg.comboBox.clear()
        layers = self.iface.mapCanvas().layers()
        layer_list = [ layer.name() for layer in layers ]
        self.dlg.comboBox.addItems(layer_list)
.
.
.
    def change_layers(self):
        self.dlg.comboBox.clear()
        layers = self.iface.mapCanvas().layers()
        layer_list = [ layer.name() for layer in layers ]
        self.dlg.comboBox.addItems(layer_list)

    def run(self):
        """Run method that performs all the real work"""
        self.iface.layerTreeCanvasBridge().canvasLayersChanged.connect(self.change_layers)
        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with you
.
.
.


No hay comentarios: