16.1. Estructurar Complementos de Python

Para crear un complemento, aquí hay algunos pasos a seguir:

  1. Idea: Have an idea about what you want to do with your new QGIS plugin. Why do you do it? What problem do you want to solve? Is there already another plugin for that problem?

  2. Create files: algunos son esenciales (ver Ficheros de un complemento)

  3. Write code: Escriba el código en archivos apropiados

  4. Test: Recarga tu complemento para comprobar si todo está bien

  5. Publish: Publique su complemento en el repositorio de QGIS o cree su propio repositorio como un «arsenal» de «armas GIS» personales.

16.1.1. Escribiendo un complemento

Desde la introducción de los complementos de Python en QGIS, han aparecido varios complementos. El equipo de QGIS mantiene un Repositorio oficial de complementos de Python. Puede usar su fuente para aprender más sobre la programación con PyQGIS o averiguar si está duplicando el esfuerzo de desarrollo.

16.1.1.1. Ficheros de un complemento

Aquí está la estructura de directorios de nuestro complemento de ejemplo

PYTHON_PLUGINS_PATH/
  MyPlugin/
    __init__.py    --> *required*
    mainPlugin.py  --> *core code*
    metadata.txt   --> *required*
    resources.qrc  --> *likely useful*
    resources.py   --> *compiled version, likely useful*
    form.ui        --> *likely useful*
    form.py        --> *compiled version, likely useful*

Cuál es el significado de los ficheros:

  • :fichero:`__init__.py` = El punto de partida del complemento. Debe tener el método classFactory y puede tener cualquier otro código de inicialización.

  • :fichero:`mainPlugin.py` = El código principal del complemento. Contiene toda la información sobre las acciones del complemento y el código principal.

  • :fichero:`resources.qrc` = El documento .xml creado por Qt Designer. Contiene las rutas relativas de los recursos de los formularios.

  • :fichero:`resources.py` = La traducción del fichero .qrc descrito anteriormente a lenguaje Python.

  • :fichero:`form.ui` = La interfaz gráfica de usuario creada por Qt Designer.

  • form.py = La traducción de form.ui descrita anteriormente a Python.

  • metadata.txt = Contiene información general, versión, nombre y algunos otros metadatos utilizados por el sitio web de complementos y la infraestructura de complementos.

Aquí es una forma de crear los archivos básicos (esqueleto) de un complemento típico de QGIS Python.

Hay un complemento de QGIS llamado Plugin Builder 3 que crea una plantilla de complemento para QGIS. Esta es la opción recomendada, ya que produce fuentes compatibles con 3.x.

Advertencia

Si planea cargar el complemento en el Repositorio oficial de complementos de Python debe verificar que su complemento siga algunas reglas adicionales, necesarias para el complemento Validación

16.1.2. Contenido del complemento

Aquí puede encontrar información y ejemplos sobre qué agregar en cada uno de los archivos en la estructura de archivo descrita anteriormente.

16.1.2.1. Metadatos del complemento

Primero, el administrador de complementos necesita recuperar información básica sobre el complemento, como su nombre, descripción, etc. Archivo metadata.txt es el lugar correcto para colocar esta información.

Nota

Todos los metadatos deben estar en codificación UTF-8.

Nombre de metadatos

Necesario

Notas

Nombre

Verdadero

una cadena corta que contiene el nombre del complemento

qgisMinimumVersion

Verdadero

notación con puntos de la versión mínima de QGIS

qgisMaximumVersion

Falso

notación con puntos de la versión máxima de QGIS

descripción

Verdadero

texto breve que describe el complemento, no se permite HTML

acerca

Verdadero

texto más largo que describe el complemento en detalles, no se permite HTML

versión

Verdadero

cadena corta con la notación punteada de la versión

autor

Verdadero

nombre del autor

email

Verdadero

correo electrónico del autor, que solo se muestra en el sitio web para los usuarios que han iniciado sesión, pero que es visible en el Administrador de complementos después de instalar el complemento

registro de cambios

Falso

cadena, puede ser de varias líneas, no se permite HTML

experimental

Falso

bandera booleana, True o False - True si esta versión es experimental

obsoleto

Falso

bandera booleana, True o False, se aplica a todo el complemento y no solo a la versión cargada

etiquetas

Falso

lista separada por comas, los espacios son permitidos dentro de etiquetas individuales

homepage

Falso

una URL válida que apunta a la página de inicio de su complemento

repositorio

Verdadero

una URL válida al repositorio de código fuente

rastreador

Falso

Una URL válida a los tickets y reportes de errores

icono

Falso

un nombre de archivo o una ruta relativa (relativa a la carpeta base del paquete comprimido del complemento) de una imagen compatible con la web (PNG, JPEG)

categoría

Falso

una de Ráster, Vectorial, Base de Datos y Web

plugin_dependencies

Falso

Lista separada por comas de otros complementos a instalar, utiliza los nombres de los complementos procedentes del campo de nombre de sus metadatos

servidor

Falso

bandera booleana, True o False, determina si el complemento tiene una interfaz de servidor

hasProcessingProvider

Falso

bandera booleana, True o False, determina si el complemento proporciona algoritmos de procesamiento

De forma predeterminada, los complementos se colocan en el menú Complementos (veremos en la siguiente sección cómo agregar una entrada de menú para su complemento) pero también se pueden colocar en el menú Ráster, Vectorial, Base de Datos y Web.

Existe una entrada de metadatos de «categoría» correspondiente para especificar eso, por lo que el complemento se puede clasificar en consecuencia. Esta entrada de metadatos se utiliza como sugerencia para los usuarios y les dice dónde (en qué menú) se puede encontrar el complemento. Los valores permitidos para «categoría» son: Vectorial, Ráster, Base de datos o Web. Por ejemplo, si su complemento estará disponible en el menú Ráster, agréguelo a metadata.txt

category=Raster

Nota

Si qgisMaximumVersion está vacío, se establecerá automáticamente en la versión principal más .99 cuando se cargue en el Repositorio oficial de complementos de Python.

Un ejemplo para este metadata.txt

; the next section is mandatory

[general]
name=HelloWorld
email=me@example.com
author=Just Me
qgisMinimumVersion=3.0
description=This is an example plugin for greeting the world.
    Multiline is allowed:
    lines starting with spaces belong to the same
    field, in this case to the "description" field.
    HTML formatting is not allowed.
about=This paragraph can contain a detailed description
    of the plugin. Multiline is allowed, HTML is not.
version=version 1.2
tracker=http://bugs.itopen.it
repository=http://www.itopen.it/repo
; end of mandatory metadata

; start of optional metadata
category=Raster
changelog=The changelog lists the plugin versions
    and their changes as in the example below:
    1.0 - First stable release
    0.9 - All features implemented
    0.8 - First testing release

; Tags are in comma separated value format, spaces are allowed within the
; tag name.
; Tags should be in English language. Please also check for existing tags and
; synonyms before creating a new one.
tags=wkt,raster,hello world

; these metadata can be empty, they will eventually become mandatory.
homepage=https://www.itopen.it
icon=icon.png

; experimental flag (applies to the single version)
experimental=True

; deprecated flag (applies to the whole plugin and not only to the uploaded version)
deprecated=False

; if empty, it will be automatically set to major version + .99
qgisMaximumVersion=3.99

; Since QGIS 3.8, a comma separated list of plugins to be installed
; (or upgraded) can be specified.
; The example below will try to install (or upgrade) "MyOtherPlugin" version 1.12
; and any version of "YetAnotherPlugin".
; Both "MyOtherPlugin" and "YetAnotherPlugin" names come from their own metadata's
; name field
plugin_dependencies=MyOtherPlugin==1.12,YetAnotherPlugin

16.1.2.2. __init__.py

Este archivo es requerido por el sistema de importación de Python. Además, QGIS requiere que este archivo contenga una función classFactory(), que se llama cuando el complemento se carga en QGIS. Recibe una referencia a la instancia de: class: QgisInterface <qgis.gui.QgisInterface> y debe devolver un objeto de la clase de su complemento desde mainplugin.py — en nuestro caso se llama TestPlugin (ver más abajo). Así es como debería verse __init __. Py

def classFactory(iface):
  from .mainPlugin import TestPlugin
  return TestPlugin(iface)

# any other initialisation needed

16.1.2.3. mainPlugin.py

Aquí es donde ocurre la magia y así es como se ve la magia: (por ejemplo mainPlugin.py)

from qgis.PyQt.QtGui import *
from qgis.PyQt.QtWidgets import *

# initialize Qt resources from file resources.py
from . import resources

class TestPlugin:

  def __init__(self, iface):
    # save reference to the QGIS interface
    self.iface = iface

  def initGui(self):
    # create action that will start plugin configuration
    self.action = QAction(QIcon(":/plugins/testplug/icon.png"),
                          "Test plugin",
                          self.iface.mainWindow())
    self.action.setObjectName("testAction")
    self.action.setWhatsThis("Configuration for test plugin")
    self.action.setStatusTip("This is status tip")
    self.action.triggered.connect(self.run)

    # add toolbar button and menu item
    self.iface.addToolBarIcon(self.action)
    self.iface.addPluginToMenu("&Test plugins", self.action)

    # connect to signal renderComplete which is emitted when canvas
    # rendering is done
    self.iface.mapCanvas().renderComplete.connect(self.renderTest)

  def unload(self):
    # remove the plugin menu item and icon
    self.iface.removePluginMenu("&Test plugins", self.action)
    self.iface.removeToolBarIcon(self.action)

    # disconnect form signal of the canvas
    self.iface.mapCanvas().renderComplete.disconnect(self.renderTest)

  def run(self):
    # create and show a configuration dialog or something similar
    print("TestPlugin: run called!")

  def renderTest(self, painter):
    # use painter for drawing to map canvas
    print("TestPlugin: renderTest called!")

Las únicas funciones de complemento que deben existir en el archivo fuente del complemento principal (por ejemplo mainPlugin.py) son:

  • __init__ que da acceso a la interfaz QGIS

  • initGui() llamado cuando se carga el complemento

  • unload() llamado cuando se descarga el complemento

En el ejemplo anterior, se usó addPluginToMenu(). Esto agregará la acción de menú correspondiente al menú Complementos. Existen métodos alternativos para agregar la acción a un menú diferente. Aquí hay una lista de esos métodos:

Todos tienen la misma sintaxis que el método addPluginToMenu().

Se recomienda agregar su menú de complementos a uno de esos métodos predefinidos para mantener la coherencia en la forma en que se organizan las entradas de los complementos. Sin embargo, puede agregar su grupo de menú personalizado directamente a la barra de menú, como lo demuestra el siguiente ejemplo:

def initGui(self):
    self.menu = QMenu(self.iface.mainWindow())
    self.menu.setObjectName("testMenu")
    self.menu.setTitle("MyMenu")

    self.action = QAction(QIcon(":/plugins/testplug/icon.png"),
                          "Test plugin",
                          self.iface.mainWindow())
    self.action.setObjectName("testAction")
    self.action.setWhatsThis("Configuration for test plugin")
    self.action.setStatusTip("This is status tip")
    self.action.triggered.connect(self.run)
    self.menu.addAction(self.action)

    menuBar = self.iface.mainWindow().menuBar()
    menuBar.insertMenu(self.iface.firstRightStandardMenu().menuAction(),
                       self.menu)

def unload(self):
    self.menu.deleteLater()

No olvide establecer QAction y QMenu objectName con un nombre específico para su complemento para que pueda personalizarse.

16.1.2.4. Archivo de Recursos

Puede ver que en initGui()`hemos usado un icono del archivo de recursos (llamado :file:`resources.qrc() en nuestro caso)

<RCC>
  <qresource prefix="/plugins/testplug" >
     <file>icon.png</file>
  </qresource>
</RCC>

Es bueno usar un prefijo que no colisione con otros complementos o partes de QGIS, de lo contrario, podría obtener recursos que no deseaba. Ahora solo necesita generar un archivo Python que contendrá los recursos. Se hace con el comando pyrcc5:

pyrcc5 -o resources.py resources.qrc

Nota

En entornos Windows, intentar ejecutar pyrcc5 desde el símbolo del sistema o Powershell probablemente resultará en el error» Windows no puede acceder al dispositivo, ruta o archivo especificado […] «. La solución más fácil es probablemente utilizar OSGeo4W Shell, pero si se siente cómodo modificando la variable de entorno PATH o especificando la ruta al ejecutable de forma explícita, debería poder encontrarla en <Your QGIS Install Directory>\bin\pyrcc5.exe.

Y eso es todo… nada complicado :)

Si ha hecho todo correctamente, debería poder encontrar y cargar su complemento en el administrador de complementos y ver un mensaje en la consola cuando se selecciona el icono de la barra de herramientas o el elemento de menú apropiado.

Cuando trabaje en un complemento real, es aconsejable escribir el complemento en otro directorio (de trabajo) y crear un archivo MAKE que generará UI + archivos de recursos e instalará el complemento en su instalación de QGIS.

16.1.3. Documentación

La documentación del complemento se puede escribir como archivos de ayuda HTML. El módulo qgis.utils proporciona una función, showPluginHelp() que abrirá el navegador de archivos de ayuda, de la misma manera que otras ayudas de QGIS.

La función showPluginHelp() busca archivos de ayuda en el mismo directorio que el módulo de llamada. Buscará, a su vez, index-ll_cc.html, index-ll.html, index-en.html, index-en_us.html `y :file:`index.html, mostrando el que encuentre primero. Aquí ll_cc es la configuración regional de QGIS. Esto permite que se incluyan múltiples traducciones de la documentación con el complemento.

La función showPluginHelp() también puede tomar parámetros packageName, que identifica un complemento específico para el que se mostrará la ayuda, nombre de archivo, que puede reemplazar» índice «en los nombres de los archivos que se buscan, y sección, que es el nombre de una etiqueta de anclaje html en el documento en el que se colocará el navegador.

16.1.4. Traducción

Con unos pocos pasos, puede configurar el entorno para la localización del complemento de modo que, según la configuración regional de su computadora, el complemento se cargue en diferentes idiomas.

16.1.4.1. Requisitos de Software

La forma más fácil de crear y administrar todos los archivos de traducción es instalar Qt Linguist. En un entorno GNU/Linux basado en Debian, puede instalarlo escribiendo:

sudo apt install qttools5-dev-tools

16.1.4.2. Archivos y directorio

Cuando cree el complemento, encontrará la carpeta i18n dentro del directorio principal del complemento.

Todos los archivos de traducción deben estar dentro de este directorio.

16.1.4.2.1. archivo .pro

Primero debe crear un archivo .pro, que es un archivo proyecto que puede ser administrado por Qt Linguist.

En este archivo .pro debe especificar todos los archivos y formularios que desea traducir. Este archivo se utiliza para configurar los archivos de localización y las variables. Un posible archivo de proyecto, que coincide con la estructura de nuestro complemento de ejemplo:

FORMS = ../form.ui
SOURCES = ../your_plugin.py
TRANSLATIONS = your_plugin_it.ts

Su complemento puede seguir una estructura más compleja y puede estar distribuido en varios archivos. Si este es el caso, tenga en cuenta que pylupdate5, el programa que usamos para leer el archivo .pro y actualizar la cadena traducible, no expande los caracteres comodín, por lo que debe colocar cada archivo explícitamente en el archivo .pro. Su archivo de proyecto podría verse así:

FORMS = ../ui/about.ui ../ui/feedback.ui \
        ../ui/main_dialog.ui
SOURCES = ../your_plugin.py ../computation.py \
          ../utils.py

Además, el archivo your_plugin.py es el archivo que llama a todos los menús y submenús de su complemento en la barra de herramientas de QGIS y desea traducirlos todos.

Finalmente, con la variable TRANSLATIONS puede especificar los idiomas de traducción que desee.

Advertencia

Asegúrese de nombrar el archivo ts como your_plugin_ + language + .ts, de lo contrario, la carga del idioma fallará. Utilice el atajo de 2 letras para el idioma (it para italiano, de a alemán, etc.)

16.1.4.2.2. archivo .ts

Una vez que haya creado el .pro, estará listo para generar los archivos .ts para el(los) idioma(s) de su complemento.

Abra una terminal, vaya al directorio your_plugin/i18n y escriba:

pylupdate5 your_plugin.pro

debería ver el archivo(s) your_plugin_language.ts.

Abra el archivo .ts con Qt Linguist y comience a traducir.

16.1.4.2.3. archivo .qm

Cuando termine de traducir su complemento (si algunas cadenas no se completan, se utilizará el idioma de origen para esas cadenas), debe crear el archivo .qm (el archivo .ts compilado que se utilizará por QGIS).

Simplemente abra un cd de terminal en el directorio your_plugin/i18n y escriba:

lrelease your_plugin.ts

ahora, en el directorio i18n verá el archivo(s) your_plugin.qm.

16.1.4.3. Traducir usando Makefile

Alternativamente, puede usar el archivo MAKE para extraer mensajes del código Python y los cuadros de diálogo Qt, si creó su complemento con Plugin Builder. Al comienzo del Makefile hay una variable LOCALES:

LOCALES = en

Agregue la abreviatura del idioma a esta variable, por ejemplo, para el idioma húngaro:

LOCALES = en hu

Ahora puede generar o actualizar el archivo hu.ts (y el en.ts también) desde las fuentes mediante:

make transup

Después de esto, ha actualizado el archivo .ts para todos los idiomas configurados en la variable LOCALES. Utilice Qt Linguist para traducir los mensajes del programa. Al finalizar la traducción, el transcompile puede crear los archivos .qm:

make transcompile

Tienes que distribuir archivos .ts” con tu complemento.

16.1.4.4. Carga el complemento

Para ver la traducción de su complemento, abra QGIS, cambie el idioma (Configuración -> Opciones -> General) y reinicie QGIS.

Debería ver su complemento en el idioma correcto.

Advertencia

Si cambia algo en su complemento (nuevas IU, nuevo menú, etc.), debe generar nuevamente la versión de actualización de los archivos .ts y .qm, así que vuelva a ejecutar el comando de arriba.

16.1.5. Consejos y Trucos

16.1.5.1. Recargador de Complemento

Durante el desarrollo de su complemento, con frecuencia deberá volver a cargarlo en QGIS para realizar pruebas. Esto es muy fácil con el complemento Recargador de complementos. Puedes encontrarlo con el Administrador de Complementos.

16.1.5.2. Acceder a complementos

Puede acceder a todas las clases de complementos instalados desde QGIS utilizando Python, que puede ser útil para fines de depuración.

my_plugin = qgis.utils.plugins['My Plugin']

16.1.5.3. Registro de Mensajes

Los complementos tienen su propia pestaña dentro de Panel de mensajes de registro.

16.1.5.4. Compartir su complemento

QGIS aloja cientos de complementos en el repositorio de complementos. ¡Considere compartir el suyo! Ampliará las posibilidades de QGIS y la gente podrá aprender de su código. Todos los complementos alojados se pueden encontrar e instalar desde QGIS con el Administrador de complementos.

La información y los requisitos están aquí: plugins.qgis.org.