16.2. Fragmentos de código

Consejo

Los fragmentos de código en esta página necesitan las siguientes adiciones si está fuera de la consola de pyqgis:

 1from qgis.core import (
 2    QgsProject,
 3    QgsApplication,
 4    QgsMapLayer,
 5)
 6
 7from qgis.gui import (
 8    QgsGui,
 9    QgsOptionsWidgetFactory,
10    QgsOptionsPageWidget,
11    QgsLayerTreeEmbeddedWidgetProvider,
12    QgsLayerTreeEmbeddedWidgetRegistry,
13)
14
15from qgis.PyQt.QtCore import Qt
16from qgis.PyQt.QtWidgets import (
17    QMessageBox,
18    QAction,
19    QHBoxLayout,
20    QComboBox,
21)
22from qgis.PyQt.QtGui import QIcon

Esta sección cuenta con fragmentos de código para facilitar el desarrollo de complementos.

16.2.1. Cómo llamar a un método por un atajo de teclado

En el complemento añadir a la initGui()

self.key_action = QAction("Test Plugin", self.iface.mainWindow())
self.iface.registerMainWindowAction(self.key_action, "Ctrl+I")  # action triggered by Ctrl+I
self.iface.addPluginToMenu("&Test plugins", self.key_action)
self.key_action.triggered.connect(self.key_action_triggered)

Para añadir unload()

self.iface.unregisterMainWindowAction(self.key_action)

El método que se llama cuando se presiona CTRL+I

def key_action_triggered(self):
  QMessageBox.information(self.iface.mainWindow(),"Ok", "You pressed Ctrl+I")

También es posible permitir a los usuarios personalizar los atajos de teclado para las acciones proporcionadas. Esto se hace añadiendo:

1# in the initGui() function
2QgsGui.shortcutsManager().registerAction(self.key_action)
3
4# and in the unload() function
5QgsGui.shortcutsManager().unregisterAction(self.key_action)

16.2.2. Cómo reutilizar los iconos de QGIS

Debido a que son bien conocidos y transmiten un mensaje claro a los usuarios, es posible que a veces desee reutilizar los iconos de QGIS en su plugin en lugar de dibujar y establecer uno nuevo. Utilice el método getThemeIcon().

Por ejemplo, para reutilizar el icono fileOpen mActionFileOpen.svg disponible en el repositorio de código de QGIS:

1# e.g. somewhere in the initGui
2self.file_open_action = QAction(
3    QgsApplication.getThemeIcon("/mActionFileOpen.svg"),
4    self.tr("Select a File..."),
5    self.iface.mainWindow()
6)
7self.iface.addPluginToMenu("MyPlugin", self.file_open_action)

iconPath() es otro método para llamar a los iconos de QGIS. Encuentre ejemplos de llamadas a iconos temáticos en Imágenes incrustadas en QGIS - Hoja de trucos.

16.2.3. Interfaz para complemento en el cuadro de diálogo de opciones

Puede agregar una pestaña de opciones de complementos personalizados a Configuración -> Opciones. Esto es preferible a agregar una entrada de menú principal específica para las opciones de su complemento, ya que mantiene todas las configuraciones de la aplicación QGIS y las configuraciones del complemento en un solo lugar que es fácil de descubrir y navegar por los usuarios.

El siguiente fragmento solo agregará una nueva pestaña en blanco para la configuración del complemento, lista para que la complete con todas las opciones y configuraciones específicas de su complemento. Puede dividir las siguientes clases en diferentes archivos. En este ejemplo, estamos agregando dos clases al archivo principal mainPlugin.py.

 1class MyPluginOptionsFactory(QgsOptionsWidgetFactory):
 2
 3    def __init__(self):
 4        super().__init__()
 5
 6    def icon(self):
 7        return QIcon('icons/my_plugin_icon.svg')
 8
 9    def createWidget(self, parent):
10        return ConfigOptionsPage(parent)
11
12
13class ConfigOptionsPage(QgsOptionsPageWidget):
14
15    def __init__(self, parent):
16        super().__init__(parent)
17        layout = QHBoxLayout()
18        layout.setContentsMargins(0, 0, 0, 0)
19        self.setLayout(layout)

Finalmente estamos agregando las importaciones y modificando la función __init__:

 1from qgis.PyQt.QtWidgets import QHBoxLayout
 2from qgis.gui import QgsOptionsWidgetFactory, QgsOptionsPageWidget
 3
 4
 5class MyPlugin:
 6    """QGIS Plugin Implementation."""
 7
 8    def __init__(self, iface):
 9        """Constructor.
10
11        :param iface: An interface instance that will be passed to this class
12            which provides the hook by which you can manipulate the QGIS
13            application at run time.
14        :type iface: QgsInterface
15        """
16        # Save reference to the QGIS interface
17        self.iface = iface
18
19
20    def initGui(self):
21        self.options_factory = MyPluginOptionsFactory()
22        self.options_factory.setTitle(self.tr('My Plugin'))
23        iface.registerOptionsWidgetFactory(self.options_factory)
24
25    def unload(self):
26        iface.unregisterOptionsWidgetFactory(self.options_factory)

Truco

Añadir pestañas personalizadas al diálogo de propiedades de capa

Puede aplicar una lógica similar para agregar la opción personalizada del complemento al cuadro de diálogo de propiedades de la capa usando las clases QgsMapLayerConfigWidgetFactory y QgsMapLayerConfigWidget.

16.2.4. Incrustar widgets personalizados para capas en el árbol de capas

Además de los elementos habituales de simbología de capas que se muestran al lado o debajo de la entrada de la capa en el panel Capas, puede añadir sus propios widgets, permitiendo un acceso rápido a algunas acciones que se utilizan a menudo con una capa (configuración de filtrado, selección, estilo, actualización de una capa con un widget de botón, creación de un deslizador de tiempo basado en la capa o simplemente mostrar información adicional de la capa en una etiqueta, o …). Estos llamados Widgets incrustados en el árbol de capas están disponibles a través de la pestaña Legend de las propiedades de cada capa.

El siguiente fragmento de código crea un desplegable en la leyenda que muestra los estilos de capa disponibles para la capa, permitiendo cambiar rápidamente entre los diferentes estilos de capa.

 1class LayerStyleComboBox(QComboBox):
 2    def __init__(self, layer):
 3        QComboBox.__init__(self)
 4        self.layer = layer
 5        for style_name in layer.styleManager().styles():
 6            self.addItem(style_name)
 7
 8        idx = self.findText(layer.styleManager().currentStyle())
 9        if idx != -1:
10          self.setCurrentIndex(idx)
11
12        self.currentIndexChanged.connect(self.on_current_changed)
13
14    def on_current_changed(self, index):
15        self.layer.styleManager().setCurrentStyle(self.itemText(index))
16
17class LayerStyleWidgetProvider(QgsLayerTreeEmbeddedWidgetProvider):
18    def __init__(self):
19        QgsLayerTreeEmbeddedWidgetProvider.__init__(self)
20
21    def id(self):
22        return "style"
23
24    def name(self):
25        return "Layer style chooser"
26
27    def createWidget(self, layer, widgetIndex):
28        return LayerStyleComboBox(layer)
29
30    def supportsLayer(self, layer):
31        return True   # any layer is fine
32
33provider = LayerStyleWidgetProvider()
34QgsGui.layerTreeEmbeddedWidgetRegistry().addProvider(provider)

A continuación, desde la pestaña de propiedades Leyenda de una capa determinada, arrastre el Selector de estilo de capa de Widgets disponibles a Widgets utilizados para habilitar el widget en el árbol de capas. Los widgets incrustados SIEMPRE se muestran en la parte superior de sus subelementos de nodo de capa asociados.

Si quiere utilizar los widgets desde, por ejemplo, un complemento, puede añadirlos así:

1layer = iface.activeLayer()
2counter = int(layer.customProperty("embeddedWidgets/count", 0))
3layer.setCustomProperty("embeddedWidgets/count", counter+1)
4layer.setCustomProperty("embeddedWidgets/{}/id".format(counter), "style")
5view = self.iface.layerTreeView()
6view.layerTreeModel().refreshLayerLegend(view.currentLegendNode())
7view.currentNode().setExpanded(True)