Viktigt
Översättning är en gemenskapsinsats du kan gå med i. Den här sidan är för närvarande översatt till 100.00%.
16.1. Strukturering av Python-plugins
De viktigaste stegen för att skapa ett plugin är:
Idé: Ha en idé om vad du vill göra med ditt nya QGIS-plugin.
Setup: Skapa filerna för ditt insticksprogram. Beroende på typen av plugin är vissa obligatoriska medan andra är valfria
Develop: Skriv koden i lämpliga filer
Valfritt: Translate: Översätt ditt insticksprogram till olika språk
Test: Ladda om ditt plugin för att kontrollera om allt är OK
Publicera: Publicera din plugin i QGIS repository eller skapa din egen repository som en ”arsenal” av personliga ”GIS-vapen”.
16.1.1. Kom igång
Innan du börjar skriva ett nytt insticksprogram, ta en titt på Officiellt Python plugin-repository. Källkoden för befintliga insticksprogram kan hjälpa dig att lära dig mer om programmering. Du kanske också upptäcker att ett liknande plugin redan finns och att du kanske kan utöka det eller åtminstone bygga vidare på det för att utveckla ditt eget.
16.1.1.1. Konfigurera plugin-filens struktur
För att komma igång med ett nytt plugin måste vi konfigurera de nödvändiga plugin-filerna.
Det finns två resurser för plugin-mallar som kan hjälpa dig att komma igång:
För utbildningsändamål eller när ett minimalistiskt tillvägagångssätt önskas, tillhandahåller minimal plugin-mall de grundläggande filer (skelett) som krävs för att skapa ett giltigt QGIS Python-plugin.
För en plugin-mall med mer fullständiga funktioner kan Plugin Builder skapa mallar för flera olika plugin-typer, inklusive funktioner som lokalisering (översättning) och testning.
En typisk plugin-katalog innehåller följande filer:
metadata.txt
- krävs - Innehåller allmän information, version, namn och några andra metadata som används av plugins webbplats och plugin-infrastruktur.__init__.py
- krävs - Startpunkten för insticksprogrammet. Den måste ha metodenclassFactory()
och kan ha annan initialiseringskod.mainPlugin.py
- kärnkod - Den huvudsakliga arbetskoden för insticksprogrammet. Innehåller all information om pluginets åtgärder och huvudkoden.form.ui
- för insticksprogram med eget GUI - Det GUI som skapats av Qt Designer.form.py
- kompilerad GUI - Översättningen av form.ui som beskrivs ovan till Python.resources.qrc
- valfritt - Ett .xml-dokument som skapats av Qt Designer. Innehåller relativa sökvägar till resurser som används i GUI-formulären.resources.py
- kompilerade resurser, valfritt - Översättningen av den ovan beskrivna .qrc-filen till Python.LICENSE
- krävs om insticksprogrammet ska publiceras eller uppdateras i QGIS Plugins Directory, annars valfritt. Filen ska vara en ren textfil utan filtillägg i filnamnet.
Varning
Om du planerar att ladda upp insticksprogrammet till Officiellt Python plugin-repository måste du kontrollera att ditt insticksprogram följer några ytterligare regler, som krävs för insticksprogrammet Validering.
16.1.2. Skriva plugin-kod
I följande avsnitt visas vilket innehåll som ska läggas till i var och en av de filer som introducerades ovan.
16.1.2.1. metadata.txt
Först måste Plugin Manager hämta grundläggande information om pluginet, t.ex. dess namn, beskrivning osv. Denna information lagras i metadata.txt
.
Observera
Alla metadata måste vara i UTF-8-kodning.
Namn på metadata |
Obligatorisk |
Anteckningar |
---|---|---|
namn |
Sant |
en kort sträng som innehåller namnet på insticksprogrammet |
qgisMinimumVersion |
Sant |
prickad notation av minsta QGIS-version |
qgisMaximumVersion |
Falskt |
streckad notation av maximal QGIS-version |
description |
Sant |
kort text som beskriver insticksprogrammet, ingen HTML tillåten |
about |
Sant |
längre text som beskriver pluginet i detalj, ingen HTML tillåten |
version |
Sant |
kort sträng med versionen prickad notation |
author |
Sant |
författarens namn |
Sant |
författarens e-postadress, visas endast på webbplatsen för inloggade användare, men syns i Plugin Manager efter att pluginet har installerats |
|
changelog |
Falskt |
sträng, kan vara flerradig, ingen HTML tillåten |
experimental |
Falskt |
boolean flagga, |
deprecated |
Falskt |
boolesk flagga, |
tags |
Falskt |
kommaseparerad lista, mellanslag är tillåtna inom enskilda taggar |
homepage |
Falskt |
en giltig URL som pekar på hemsidan för ditt plugin |
repository |
Sant |
en giltig URL för källkodsarkivet |
tracker |
Falskt |
en giltig URL för ärenden och felrapporter |
icon |
Falskt |
ett filnamn eller en relativ sökväg (i förhållande till basmappen i insticksprogrammets komprimerade paket) för en webbvänlig bild (PNG, JPEG) |
category |
Falskt |
en av |
plugin_dependencies |
Falskt |
PIP-liknande kommaseparerad lista över andra insticksprogram som ska installeras, använd insticksprogrammens namn från deras metadatas namnfält |
server |
Falskt |
boolean flagga, |
hasProcessingProvider |
Falskt |
boolean flagga, |
Som standard placeras plugins i menyn
(vi kommer i nästa avsnitt att se hur du lägger till en menypost för ditt plugin) men de kan också placeras i menyerna , , , och .En motsvarande ”kategori” metadatapost finns för att ange detta, så att plugin-programmet kan klassificeras i enlighet därmed. Denna metadatapost används som tips för användare och talar om för dem var (i vilken meny) plugin-programmet kan hittas. Tillåtna värden för ”category” är: Vektor, Raster, Databas eller Webb. Till exempel, om ditt plugin kommer att finnas tillgängligt från Raster-menyn, lägg till detta i metadata.txt
category=Raster
Observera
Om qgisMaximumVersion är tom, kommer den automatiskt att sättas till huvudversionen plus .99 när den laddas upp till Officiellt Python plugin-repository.
Ett exempel på detta är 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
Denna fil krävs av Pythons importsystem. QGIS kräver också att denna fil innehåller en classFactory()
-funktion, som anropas när insticksprogrammet laddas in i QGIS. Den får en referens till instansen av QgisInterface
och måste returnera ett objekt av din plugins klass från mainplugin.py
— i vårt fall heter den TestPlugin
(se nedan). Så här bör __init__.py
se ut
def classFactory(iface):
from .mainPlugin import TestPlugin
return TestPlugin(iface)
# any other initialisation needed
16.1.2.3. mainPlugin.py
Det är här det magiska händer och det är så här det magiska ser ut: (t.ex. :fil:`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!")
De enda plugin-funktioner som måste finnas i plugin-huvudkällfilen (t.ex. mainPlugin.py
) är
__init__
som ger tillgång till QGIS-gränssnittetinitGui()
anropas när insticksprogrammet laddasunload()
anropas när insticksprogrammet avlastas
I exemplet ovan används addPluginToMenu()
. Detta kommer att lägga till motsvarande menyåtgärd till menyn . Det finns alternativa metoder för att lägga till åtgärden i en annan meny. Här är en lista över dessa metoder:
Alla dessa har samma syntax som metoden addPluginToMenu()
.
Att lägga till din plugin-meny till en av dessa fördefinierade metoder rekommenderas för att hålla konsekvens i hur plugin-poster organiseras. Du kan dock lägga till din anpassade menygrupp direkt i menyfältet, vilket nästa exempel visar:
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()
Glöm inte att ställa in QAction
och QMenu
objectName
till ett namn som är specifikt för ditt plugin så att det kan anpassas.
Även om hjälp och om-åtgärder också kan läggas till i din anpassade meny, är en bekväm plats att göra dem tillgängliga i QGIS huvudmeny :menuselection:Help --> Plugins
. Detta görs med hjälp av pluginHelpMenu()
-metoden.
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
När du arbetar med ett riktigt insticksprogram är det klokt att skriva insticksprogrammet i en annan (arbets)katalog och skapa en makefile som genererar UI + resursfiler och installerar insticksprogrammet i din QGIS-installation.
16.1.3. Dokumentera plugins
Dokumentationen för insticksprogrammet kan skrivas som HTML-hjälpfiler. Modulen qgis.utils
tillhandahåller en funktion, showPluginHelp()
, som öppnar webbläsaren för hjälpfiler på samma sätt som annan QGIS-hjälp.
Funktionen showPluginHelp()
letar efter hjälpfiler i samma katalog som den anropande modulen. Den letar i tur och ordning efter index-ll_cc.html
, index-ll.html
, index-en.html
, index-en_us.html
och index.html
, och visar den som hittas först. Här är ll_cc
QGIS-landets språk. Detta gör att flera översättningar av dokumentationen kan inkluderas med insticksprogrammet.
Funktionen showPluginHelp()
kan också ta parametrar packageName, som identifierar ett specifikt plugin för vilket hjälpen ska visas, filename, som kan ersätta ”index” i namnen på de filer som söks, och section, som är namnet på en html-ankartagg i det dokument som webbläsaren ska placeras på.
16.1.4. Översättning av plugins
Med några få steg kan du ställa in miljön för plugin-lokalisering så att plugin-programmet laddas på olika språk beroende på lokalinställningarna på din dator.
16.1.4.1. Krav på programvara
Det enklaste sättet att skapa och hantera alla översättningsfiler är att installera Qt Linguist. I en Debian-baserad GNU/Linux-miljö kan du installera den genom att skriva:
sudo apt install qttools5-dev-tools
16.1.4.2. Filer och kataloger
När du skapar pluginet hittar du mappen i18n
i huvudkatalogen för pluginet.
Alla översättningsfiler måste finnas i den här katalogen.
16.1.4.2.1. .pro-fil
Först bör du skapa en .pro
-fil, det vill säga en projekt-fil som kan hanteras av Qt Linguist.
I den här filen .pro
måste du ange alla filer och formulär som du vill översätta. Den här filen används för att konfigurera lokaliseringsfilerna och variablerna. En möjlig projektfil som matchar strukturen i vårt exempelplugin:
FORMS = ../form.ui
SOURCES = ../your_plugin.py
TRANSLATIONS = your_plugin_it.ts
Ditt insticksprogram kan ha en mer komplex struktur och kan vara distribuerat över flera filer. Om så är fallet, kom ihåg att pylupdate5
, det program vi använder för att läsa filen .pro
och uppdatera den översättningsbara strängen, inte expanderar jokertecken, så du måste placera varje fil uttryckligen i filen .pro
. Din projektfil kan då se ut ungefär så här:
FORMS = ../ui/about.ui ../ui/feedback.ui \
../ui/main_dialog.ui
SOURCES = ../your_plugin.py ../computation.py \
../utils.py
Dessutom är filen your_plugin.py
den fil som kallar alla menyer och undermenyer för ditt plugin i QGIS verktygsfält och du vill översätta dem alla.
Slutligen kan du med variabeln TRANSLATIONS ange vilka översättningsspråk du vill ha.
Varning
Var noga med att namnge filen ts
som ditt_plugin_
+ language
+ .ts
annars kommer språkinläsningen att misslyckas! Använd genvägen med 2 bokstäver för språket (it för italienska, de för tyska, etc …)
16.1.4.2.2. .ts fil
När du har skapat .pro
är du redo att generera .ts
-filen (er) för språket (erna) i ditt plugin.
Öppna en terminal, gå till katalogen your_plugin/i18n
och skriv:
pylupdate5 your_plugin.pro
bör du se filen your_plugin_language.ts
.
Öppna filen .ts
med Qt Linguist och börja översätta.
16.1.4.2.3. .qm-fil
När du är klar med att översätta ditt plugin (om vissa strängar inte är färdiga kommer källspråket för dessa strängar att användas) måste du skapa filen .qm
(den kompilerade .ts
-filen som kommer att användas av QGIS).
Öppna bara en terminal cd i katalogen your_plugin/i18n
och skriv:
lrelease your_plugin.ts
nu, i katalogen i18n
kommer du att se filen ditt_plugin.qm
.
16.1.4.3. Översätt med hjälp av Makefile
Alternativt kan du använda makefilen för att extrahera meddelanden från pythonkod och Qt-dialogrutor, om du har skapat ditt plugin med Plugin Builder. I början av Makefile finns det en LOCALES-variabel:
LOCALES = en
Lägg till förkortningen för språket i denna variabel, t.ex. för ungerska:
LOCALES = en hu
Nu kan du generera eller uppdatera filen hu.ts
(och även en.ts
) från källorna genom att:
make transup
Efter detta har du uppdaterat filen .ts
för alla språk som anges i variabeln LOCALES. Använd Qt Linguist för att översätta programmeddelandena. När översättningen är klar kan filerna .qm
skapas av transcompile:
make transcompile
Du måste distribuera .ts
-filer med ditt plugin.
16.1.4.4. Ladda insticksprogrammet
För att se översättningen av ditt plugin, öppna QGIS, ändra språk (
) och starta om QGIS.Du bör se din plugin på rätt språk.
Varning
Om du ändrar något i ditt plugin (nya UIs, ny meny, etc..) måste du ** generera igen ** uppdateringsversionen av både .ts
och .qm
-filen, så kör kommandot ovan igen.
16.1.6. Tips och tricks
16.1.6.1. Plugin Återladdare
Under utvecklingen av ditt insticksprogram kommer du ofta att behöva ladda om det i QGIS för testning. Detta är mycket enkelt med hjälp av Plugin Reloader plugin. Du kan hitta det med Plugin Manager.
16.1.6.2. Automatisera paketering, release och översättning med qgis-plugin-ci
qgis-plugin-ci tillhandahåller ett kommandoradsgränssnitt för att utföra automatiserad paketering och distribution för QGIS-plugins på din dator, eller med hjälp av kontinuerlig integration som GitHub workflows eller Gitlab-CI samt Transifex för översättning.
Det gör det möjligt att släppa, översätta, publicera eller generera en XML plugin repository-fil via CLI eller i CI-åtgärder.
16.1.6.3. Tillgång till plugins
Du kan komma åt alla klasser av installerade insticksprogram från QGIS med hjälp av python, vilket kan vara praktiskt för felsökning.
my_plugin = qgis.utils.plugins['My Plugin']
16.1.6.4. Loggmeddelanden
Plugins har en egen flik inom Panel för loggmeddelanden.
16.1.6.5. Resursfil
Vissa plugins använder resursfiler, t.ex. resources.qrc
som definierar resurser för GUI, t.ex. ikoner:
<RCC>
<qresource prefix="/plugins/testplug" >
<file>icon.png</file>
</qresource>
</RCC>
Det är bra att använda ett prefix som inte kolliderar med andra plugins eller delar av QGIS, annars kan du få resurser som du inte vill ha. Nu behöver du bara generera en Python-fil som kommer att innehålla resurserna. Det görs med kommandot pyrcc5:
pyrcc5 -o resources.py resources.qrc
Observera
I Windows-miljöer kommer försök att köra pyrcc5 från Command Prompt eller Powershell förmodligen att resultera i felet ”Windows kan inte komma åt den angivna enheten, sökvägen eller filen […]”. Den enklaste lösningen är förmodligen att använda OSGeo4W Shell men om du känner dig bekväm med att ändra PATH-miljövariabeln eller ange sökvägen till den körbara filen uttryckligen bör du kunna hitta den på <Your QGIS Install Directory>\bin\pyrcc5.exe
.