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:

  1. Idé: Ha en idé om vad du vill göra med ditt nya QGIS-plugin.

  2. Setup: Skapa filerna för ditt insticksprogram. Beroende på typen av plugin är vissa obligatoriska medan andra är valfria

  3. Develop: Skriv koden i lämpliga filer

  4. Dokument: Skriva dokumentationen för insticksprogrammet

  5. Valfritt: Translate: Översätt ditt insticksprogram till olika språk

  6. Test: Ladda om ditt plugin för att kontrollera om allt är OK

  7. 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 metoden classFactory() 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

email

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, True eller False - True om denna version är experimentell

deprecated

Falskt

boolesk flagga, True eller False, gäller för hela insticksprogrammet och inte bara för den uppladdade versionen

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 Raster, Vector, Database, Mesh och Web

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, True eller False, avgör om insticksprogrammet har ett servergränssnitt

hasProcessingProvider

Falskt

boolean flagga, True eller False, avgör om insticksprogrammet tillhandahåller bearbetningsalgoritmer

Som standard placeras plugins i menyn Plugins (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 Raster, Vector, Database, Mesh och Web.

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änssnittet

  • initGui() anropas när insticksprogrammet laddas

  • unload() anropas när insticksprogrammet avlastas

I exemplet ovan används addPluginToMenu(). Detta kommer att lägga till motsvarande menyåtgärd till menyn Plugins. 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 (Settings ► Options ► General) 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.5. Dela ditt plugin

QGIS är värd för hundratals insticksprogram i insticksarkivet. Överväg att dela med dig av din! Det kommer att utöka möjligheterna med QGIS och människor kommer att kunna lära sig av din kod. Alla insticksprogram som finns i QGIS kan hittas och installeras från QGIS med instickshanteraren.

Information och krav finns här: plugins.qgis.org.

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.