16.1. Estructurar Complementos de Python
Los pasos principales para crear un complemento son:
Idea: Tenga una idea de lo que quiere hacer con tu nuevo complemento QGIS.
Configuración: Crea los archivos para tu complemento. Dependiendo del tipo de complemento, algunos son obligatorios y otros opcionales.
Desarrollar: Escribir el código en los archivos correspondientes
Documentar: Escribir la documentación del complemento
Opcionalmente: * Traducir*: Traduce su complemento en diferentes idiomas
Test: Recarga tu complemento para comprobar si todo está bien
Publish: Publique su complemento en el repositorio de QGIS o cree su propio repositorio como un «arsenal» de «armas GIS» personales.
16.1.1. Cómo empezar
Antes de empezar a escribir un nuevo complemento, eche un vistazo al Repositorio oficial de complementos de Python. El código fuente de los complementos existentes puede ayudarle a aprender más sobre programación. También puedes encontrar que ya existe un complemento similar y puede ser capaz de extenderlo o al menos basarte en él para desarrollar el tuyo propio.
16.1.1.1. Configurar la estructura de archivos del complemento
Para empezar con un nuevo complemento, necesitamos configurar los archivos necesarios del complemento.
Existen dos recursos de plantillas de complementos que pueden ayudarle a empezar:
Para fines educativos o siempre que se desee un enfoque minimalista, la plantilla minimal plugin template proporciona los archivos básicos (esqueleto) necesarios para crear un complemento válido de QGIS Python.
Para una plantilla de complemento más completa, el Plugin Builder puede crear plantillas para múltiples tipos de complementos diferentes, incluyendo características como localización (traducción) y pruebas.
Un directorio de complementos típico incluye los siguientes archivos:
metadata.txt
- requerido - Contiene información general, versión, nombre y algunos otros metadatos utilizados por el sitio web de complementos y la infraestructura de complementos.__init__.py
- requerido - El punto de inicio del complemento. Tiene que tener el métodoclassFactory()
y puede tener cualquier otro código de inicialización.mainPlugin.py
- código núcleo - El código principal de trabajo del complemento. Contiene toda la información sobre las acciones del complemento y el código principal.form.ui
- para complementos con IGU personalizada - La IGU creada por Qt Designer.form.py
- GUI compilado - La traducción del form.ui descrito anteriormente a Python.resources.qrc
- opcional - Un documento .xml creado por Qt Designer. Contiene rutas relativas a los recursos utilizados en los formularios GUI.resources.py
- recursos compilados, opcional - La traducción del archivo .qrc descrito anteriormente a Python.
Advertencia
Si planea subir el complemento al Repositorio oficial de complementos de Python debe comprobar que su complemento sigue algunas reglas adicionales, requeridas para el complemento Validación.
16.1.2. Escribir el código del complemento
La siguiente sección muestra qué contenido debe añadirse en cada uno de los archivos introducidos anteriormente.
16.1.2.1. metadata.txt
En primer lugar, el Gestor de Complementos necesita recuperar cierta información básica sobre el complemento, como su nombre, descripción, etc. Esta información se almacena en metadata.txt
.
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 |
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, |
obsoleto |
Falso |
bandera booleana, |
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 las siguientes opciones: |
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, |
hasProcessingProvider |
Falso |
bandera booleana, |
De forma predeterminada, los complementos se colocan en el menú
(veremos en la siguiente sección cómo añadir una entrada de menú para tu complemento) pero también pueden colocarse en los menús , , , y .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("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 QGISinitGui()
llamado cuando se carga el complementounload()
llamado cuando se descarga el complemento
En el ejemplo anterior, se usó addPluginToMenu()
. Esto agregará la acción de menú correspondiente al menú . 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("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.
Aunque las acciones de ayuda y acerca de también se pueden añadir a su menú personalizado, un lugar conveniente para hacerlas disponibles es en el menú principal de QGIS pluginHelpMenu()
.
def initGui(self):
self.help_action = QAction(
QIcon("testplug:icon.png"),
self.tr("Test Plugin..."),
self.iface.mainWindow()
)
# Add the action to the Help menu
self.iface.pluginHelpMenu().addAction(self.help_action)
self.help_action.triggered.connect(self.show_help)
@staticmethod
def show_help():
""" Open the online help. """
QDesktopServices.openUrl(QUrl('https://docs.qgis.org'))
def unload(self):
self.iface.pluginHelpMenu().removeAction(self.help_action)
del self.help_action
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 de complementos
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 de complementos
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 (
) 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.6. Consejos y Trucos
16.1.6.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.6.2. Automatice el empaquetado, la publicación y la traducción con qgis-plugin-ci
qgis-plugin-ci proporciona una interfaz de línea de comandos para realizar el empaquetado y despliegue automatizado de los complementos de QGIS en su ordenador, o utilizando la integración continua como Flujos de trabajo de GitHub o Gitlab-CI así como Transifex para la traducción.
Permite liberar, traducir, publicar o generar un archivo XML de repositorio de complementos a través de CLI o en acciones CI.
16.1.6.3. 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.6.4. Registro de Mensajes
Los complementos tienen su propia pestaña dentro de Panel de mensajes de registro.
16.1.6.5. Archivo de Recursos
Algunos complementos utilizan archivos de recursos, por ejemplo resources.qrc
que definen recursos para la interfaz gráfica de usuario, como iconos:
<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
.