16.1. Estruturando Complementos Python
The main steps for creating a plugin are:
Idea: Have an idea about what you want to do with your new QGIS plugin.
Setup: Create the files for your plugin. Depending on the plugin type, some are mandatory while others are optional
Develop: Write the code in appropriate files
Document: Write the plugin documentation
Optionally: Translate: Translate your plugin into different languages
Teste: Reload your plugin para verificar se tudo está OK
Publicando: publique seu complemento no repositório QGIS ou faça seu próprio repositório como um “arsenal” de “armas GIS” pessoais.
16.1.1. Getting started
Before starting to write a new plugin, have a look at the Repositório Oficial de complementos Python. The source code of existing plugins can help you to learn more about programming. You may also find that a similar plugin already exists and you may be able to extend it or at least build on it to develop your own.
16.1.1.1. Set up plugin file structure
To get started with a new plugin, we need to set up the necessary plugin files.
There are two plugin template resources that can help get you started:
For educational purposes or whenever a minimalist approach is desired, the minimal plugin template provides the basic files (skeleton) necessary to create a valid QGIS Python plugin.
For a more fully feature plugin template, the Plugin Builder can create templates for multiple different plugin types, including features such as localization (translation) and testing.
A typical plugin directory includes the following files:
metadata.txt
- required - Contains general info, version, name and some other metadata used by plugins website and plugin infrastructure.__init__.py
- required - The starting point of the plugin. It has to have theclassFactory()
method and may have any other initialisation code.mainPlugin.py
- core code - The main working code of the plugin. Contains all the information about the actions of the plugin and the main code.form.ui
- for plugins with custom GUI - The GUI created by Qt Designer.form.py
- compiled GUI - The translation of the form.ui described above to Python.resources.qrc
- optional - An .xml document created by Qt Designer. Contains relative paths to resources used in the GUI forms.resources.py
- compiled resources, optional - The translation of the .qrc file described above to Python.
Aviso
If you plan to upload the plugin to the Repositório Oficial de complementos Python you must check that your plugin follows some additional rules, required for plugin Validação.
16.1.2. Writing plugin code
The following section shows what content should be added in each of the files introduced above.
16.1.2.1. metadata.txt
First, the Plugin Manager needs to retrieve some basic information about the
plugin such as its name, description etc. This information is stored in metadata.txt
.
Nota
Todos os metadados devem estar na codificação UTF-8.
Nome dos metadados |
Requerido |
Notas |
---|---|---|
nome |
True |
uma string curta que contém o nome do complemento |
qgisMinimumVersion |
True |
notação dotted da versão mínima do QGIS |
qgisMaximumVersion |
False |
notação dotted da versão máxima do QGIS |
descrição |
True |
texto breve que descreve o complemento, HTML não permitido |
sobre |
True |
texto mais longo que descreve o complemento em detalhes, não é permitido HTML |
versão |
True |
string curta com a notação dotted da versão |
autor |
True |
nome do autor |
True |
email do autor, mostrado apenas no site para usuários logados, mas visível no Gerenciador de complementos após a instalação do complemento |
|
changelog |
False |
string, pode ser multilinha, não é permitido HTML |
experimental |
False |
boolean flag, |
descontinuada |
False |
boolean flag, |
etiquetas |
False |
lista separada por vírgula, são permitidos espaços dentro de tetiquetas individuais |
página inicial |
False |
um URL válido apontando para a página inicial do seu complemento |
repositório |
True |
uma URL válida para o repositório de código-fonte |
tracker |
False |
um URL válido para tickets e relatórios de erros |
ícone |
False |
um nome de arquivo ou um caminho relativo (relativo à pasta base do pacote compactado do complemento) de uma imagem amigável da Web (PNG, JPEG) |
categoria |
False |
one of |
dependencies_de_complemento |
False |
PIP-like comma separated list of other plugins to install, use plugin names coming from their metadata’s name field |
servidor |
False |
boolean flag, |
hasProcessingProvider |
False |
boolean flag, |
By default, plugins are placed in the
menu (we will see in the next section how to add a menu entry for your plugin) but they can also be placed into , , , and menus.Existe uma entrada de metadados de “categoria” correspondente para especificar isso, para que o complemento possa ser classificado de acordo. Essa entrada de metadados é usada como dica para os usuários e informa onde (em qual menu) o complemento pode ser encontrado. Os valores permitidos para “categoria” são: Vetor, Raster, Banco de dados ou Web. Por exemplo, se o seu complemento estará disponível no menu Raster, adicione-o a metadata.txt
category=Raster
Nota
Se qgisMaximumVersion estiver vazio, ele será automaticamente definido para a versão principal mais` .99` quando carregado no Repositório Oficial de complementos Python.
Um exemplo 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 arquivo é requerido pelo sistema de importação do Python. Além disso, o QGIS exige que este arquivo contenha uma função classFactory ()
, chamada quando o complemento é carregado no QGIS. Ele recebe uma referência à QgisInterface
e deve retornar um objeto da classe do seu complemento a partir de mainplugin.py
— no nosso caso, é chamado TestPlugin
(veja abaixo). É assim que __init __. Py
deve se parecer
def classFactory(iface):
from .mainPlugin import TestPlugin
return TestPlugin(iface)
# any other initialisation needed
16.1.2.3. mainPlugin.py
É aqui que a mágica acontece e é assim que a mágica se parece: (por exemplo 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!")
As únicas funções de complemento que devem existir no arquivo principal de complemento (por exemplo mainPlugin.py
) são:
__init__
, que dá acesso à interface QGISinitGui ()
chamado quando o complemento é carregadounload ()
chamado quando o complemento é descarregado
In the above example, addPluginToMenu()
is used.
This will add the corresponding menu action to the
menu. Alternative methods exist to add the action to a different menu. Here is
a list of those methods:
All of them have the same syntax as the
addPluginToMenu()
method.
É recomendável adicionar o menu do complemento a um desses métodos predefinidos para manter a consistência na organização das entradas do complemento. No entanto, você pode adicionar seu grupo de menus personalizado diretamente à barra de menus, como o próximo exemplo demonstra:
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()
Não se esqueça de definir QAction
e QMenu
objectName
com um nome específico ao seu complemento para que ele possa ser personalizado.
While help and about actions can also be added to your custom menu,
a convenient place to make them available is in the
QGIS main pluginHelpMenu()
method.
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
Ao trabalhar em um complemento real, é aconselhável gravá-lo em outro diretório (ativo) e criar um makefile que gere arquivos de recursos + interface do usuário e instale o complemento na instalação do QGIS.
16.1.3. Documenting plugins
A documentação para o complemento pode ser escrita como arquivos de ajuda em HTML. O módulo qgis.utils
fornece uma função showPluginHelp()
, que abrirá o navegador de arquivos de ajuda, da mesma maneira que outras ajudas do QGIS.
A função showPluginHelp()
procura por arquivos de ajuda no mesmo diretório que o módulo de chamada. Ele procurará, por sua vez, index-ll_cc.html
, index-ll.html
, index-en.html
, index-en_us.html `e :file:`index.html
, exibindo o que encontrar primeiro. Aqui ll_cc
é o local QGIS. Isso permite que várias traduções da documentação sejam incluídas no complemento.
A função showPluginHelp()
também pode usar os parâmetros packageName, que identifica um complemento específico para o qual a ajuda será mostrada, o nome do arquivo, que pode substituir o “índice” nos nomes dos arquivos pesquisados e a seção, que é o nome de uma marca de âncora html no documento em que o navegador será posicionado.
16.1.4. Translating plugins
Com algumas etapas, você pode configurar o ambiente para a localização do complemento para que, dependendo das configurações de localidade do seu computador, o complemento seja carregado em diferentes idiomas.
16.1.4.1. Requisitos de software
A maneira mais fácil de criar e gerenciar todos os arquivos de tradução é instalar o Qt Linguist. Em um ambiente GNU/Linux baseado no Debian, você pode instalá-lo digitando:
sudo apt install qttools5-dev-tools
16.1.4.2. Arquivos e diretório
Ao criar o complemento, você encontrará a pasta i18n
no diretório principal do complemento.
Todos os arquivos de tradução devem estar dentro deste diretório.
16.1.4.2.1. Arquivo .pro
Primeiro, você deve criar um arquivo .pro
, que é um arquivo projeto que pode ser gerenciado pelo Qt Linguist.
Neste arquivo .pro
, você deve especificar todos os arquivos e formulários que deseja traduzir. Este arquivo é usado para configurar os arquivos e variáveis de localização. Um possível arquivo de projeto, correspondendo à estrutura de nosso example plugin:
FORMS = ../form.ui
SOURCES = ../your_plugin.py
TRANSLATIONS = your_plugin_it.ts
Seu complemento pode seguir uma estrutura mais complexa e pode ser distribuído por vários arquivos. Se for esse o caso, lembre-se de que pylupdate5
, o programa que usamos para ler o arquivo .pro
e atualizar a string traduzível, não expande caracteres curinga, portanto, você deve colocar todos os arquivos explicitamente no arquivo .pro
. O arquivo do seu projeto pode se parecer com algo assim:
FORMS = ../ui/about.ui ../ui/feedback.ui \
../ui/main_dialog.ui
SOURCES = ../your_plugin.py ../computation.py \
../utils.py
Além disso, o arquivo your_plugin.py
é o arquivo que chama todos os menus e submenus do seu complemento na barra de ferramentas QGIS e você deseja traduzir todos eles.
Finalmente, com a variável TRANSLATIONS, você pode especificar os idiomas de tradução que deseja.
Aviso
Certifique-se de nomear o arquivo ts
como your_plugin_
+ language
+ .ts
, caso contrário, o carregamento do idioma falhará! Use o atalho de 2 letras para o idioma (it para italiano, de para alemão, etc…)
16.1.4.2.2. Arquivo .ts
Depois de criar o .pro
, você estará pronto para gerar os arquivos .ts
para o(s) idioma(s) do seu complemento.
Abra um terminal, vá para o diretório your_plugin/i18n
e digite:
pylupdate5 your_plugin.pro
você deve ver os arquivos your_plugin_language.ts
.
Abra o arquivo .ts
com Qt Linguist e comece a traduzir.
16.1.4.2.3. Arquivo .qm
Quando você terminar de traduzir seu complemento (se algumas strings de caracteres não forem concluídas, o idioma de origem será usado), você deverá criar o arquivo .qm
(o arquivo .ts
compilado que será usado por QGIS).
Basta abrir um cd do terminal no diretório your_plugin/i18n
e digite:
lrelease your_plugin.ts
Agora, no diretório i18n
, você verá o(s) arquivo(s) your_plugin.qm
.
16.1.4.3. Traduzindo usando Makefile
Como alternativa, você pode usar o makefile para extrair mensagens do código python e das caixas de diálogo Qt, se você criou seu complemento com o Plugin Builder. No início do Makefile, há uma variável LOCALES:
LOCALES = en
Adicione a abreviação do idioma a essa variável, por exemplo, para o idioma húngaro:
LOCALES = en hu
Agora você pode gerar ou atualizar o arquivo hu.ts
(e também o arquivo en.ts
) a partir das fontes:
make transup
Depois disso, você atualizou o arquivo .ts
para todos os idiomas definidos na variável LOCALES. Use Qt Linguist para traduzir as mensagens do programa. Terminando a tradução, os arquivos .qm
podem ser criados pelo transcompile:
make transcompile
Você precisa distribuir arquivos .ts
com o seu complemento.
16.1.4.4. Carregue o complemento
Para ver a tradução do seu complemento, abra o QGIS, altere o idioma (
) e reinicie o QGIS.Você deve ver seu complemento no idioma correto.
Aviso
Se você alterar algo no seu complemento (novas UIs, novo menu, etc.), será necessário gerar novamente a versão de atualização do arquivo .ts
e .qm
, portanto, execute novamente o comando acima.
16.1.6. Dicas e truques
16.1.6.1. Recarregador de Complementos
Durante o desenvolvimento do seu complemento, você frequentemente precisará recarregá-lo no QGIS para teste. Isso é muito fácil usando o complemento Plugin Reloader. Você pode encontrá-lo com o Plugin Manager.
16.1.6.2. Automate packaging, release and translation with qgis-plugin-ci
qgis-plugin-ci provides a command line interface to perform automated packaging and deployment for QGIS plugins on your computer, or using continuous integration like GitHub workflows or Gitlab-CI as well as Transifex for translation.
It allows releasing, translating, publishing or generating an XML plugin repository file via CLI or in CI actions.
16.1.6.3. Acessando Complementos
Você pode acessar todas as classes de complementos instalados no QGIS usando python, o que pode ser útil para fins de depuração.
my_plugin = qgis.utils.plugins['My Plugin']
16.1.6.4. Mensagens de log
Os complementos têm sua própria guia dentro de O painel Registo de Mensagens.
16.1.6.5. Arquivo de Recurso
Some plugins use resource files, for example resources.qrc
which define
resources for the GUI, such as icons:
<RCC>
<qresource prefix="/plugins/testplug" >
<file>icon.png</file>
</qresource>
</RCC>
É bom usar um prefixo que não colide com outros plugins ou qualquer parte do QGIS; caso contrário, você poderá obter recursos que não deseja. Agora você só precisa gerar um arquivo Python que conterá os recursos. É feito com pyrcc5 command:
pyrcc5 -o resources.py resources.qrc
Nota
Em ambientes Windows, a tentativa de executar o comando pyrcc5 no prompt de comando ou no Powershell provavelmente resultará no erro “O Windows não pode acessar o dispositivo, caminho ou arquivo especificado […]”. A solução mais fácil é provavelmente usar o OSGeo4W Shell, mas se você estiver confortável modificando a variável de ambiente PATH ou especificando o caminho do executável explicitamente, poderá encontrá-lo em <Your QGIS Install Directory>\bin\pyrcc5.exe
.