Zásuvné moduly, tzv. pluginy představují doplňkové nástroje. Jejich úlohou je rozšiřovat funkčnost a širokou škálu použití prostředí QGIS. Úvod do této problematiky je součástí školení QGIS pro začátečníky.
V mnohých případech však může nastat situace, kdy žádný z existujících zásuvných modulů nesplňuje funkcionalitu jakou bychom právě potřebovali. Úroveň rozšiřovaní funkcionality QGIS je různorodá. Za pomoci jazyka Python může jít o přidání jednoduchého tlačítka až po tvorbu sofistikovaných nástrojů. Kromě jazyka Python lze psát zásuvné moduly i v jazyku, ve kterém je napsán samotný QGIS, a to C++. To ale není úplně běžné.
V následující části načrtneme návod, jak si vlastní plugin vytvořit. Použijeme výše uvedený programovací jazyk Python. Postup následně odzkoušíme na jednoduchém reálném příkladu. Vytvoříme zásuvný modul s názvem Save Views, který exportuje grafický výstup ve formě obrázků ve formátu PNG pro každý prvek ve vybrané vektorové vrstvě do zvoleného výstupního adresáře.
Užitečné odkazy
QGIS API (originální pro C++)
QGIS Python API (přepis pro jazyk Python)
Důležité
QGIS verze 2 a 3 se významně liší, a to nejen z uživatelského pohledu, ale i tvorby pluginů. QGIS API verze 3 není s předcházející verzí zpětně kompatibilní. Obsahuje řadu změn, viz Backwards Incompatible Changes. Tento návod je psán pro verzi QGIS 3.
Potřebné nástroje¶
I. Qt Designer¶
Pro tvorbu nového pluginu budeme potřebovat Qt Designer, což je aplikace vývojového frameworku Qt. Tento nástroj využijeme pro tvorbu uživatelského rozhraní nového modulu.
Poznámka
Způsob instalace Qt Designer se liší podle platformy. Na Windows je Qt Designer součástí instalace samotného QGISu. Doporučený postup je použít instalátor OSGeo4W, vybrat volbu Express Desktop a nainstalovat balík QGIS. Qt Designer spustíme přes volbu Qt Designer with QGIS custom widgets. V případě Ubuntu/Debian je Qt Designer součástí balíčku qttools5-dev-tools.
II. Python rozhraní pro Qt¶
Vzhledem k tomu, že budeme vyvíjet plugin v programovacím jazyku
Python, musíme nainstalovat Python rozhraní (Python
bindings) pro Qt (verze 5). Pro
tvorbu zásuvných modulů je potřeba také nástroj pyrcc5
.
Poznámka
Na Windows obsahuje instalátor OSGeo4W vše potřebné. Po
instalaci je nástroj pyrcc5
dostupný v rámci OSGeo4W Shell.
Na Mac OS je potřeba nainstalovat správce balíčků Homebrew a doinstalovat balíček PyQt. V případě Linuxu
(Ubuntu/Debian) jde o balíček pyqt5-dev-tools. V Ubuntu jej
např. nainstalujeme příkazem sudo apt-get install
pyqt5-dev-tools
.
III. Textový editor¶
Vhodný textový editor anebo integrované vývojové prostředí (IDE) jsou pro psaní zdrojového kódu důležité. Mezi oblíbené editory patří například Sublime Text, Vim, GNU Emacs, Notepad++, TextWrangler, IDLE, Atom, Aquamacs, GNU Nano, Kate, gedit, prostředí Spyder či PyCharm a podobně.
Poznámka
V našem případě si vystačíme s vestavěným Python editorem v QGISu. Pro dlouhodnou práci tento editor ale vhodný není.
IV. Zásuvný modul Plugin Builder¶
Tento velmi užitečný zásuvný modul QGISu nám pomůže vytvořit všechny potřebné soubory a standardní podobu kódu pro budoucí plugin. Nainstalujeme jej klasickým způsobem pomocí správce zásuvných modulů v QGISu, viz. školení QGIS pro začátečníky.

Obr. 1 Instalace zásuvného modulu Plugin Builder.¶
V. Zásuvný modul Plugin Reloader¶
Díky tomuto pluginu nemusíme při každé změně našeho kódu restartovat QGIS. Změny se projeví ihned po jeho spuštění. Nainstalujeme jej klasickým způsobem pomocí správce zásuvných modulů v QGISu (pro jeho instalaci je potřeba povolit experimentální moduly v nastavení správce).

Obr. 2 Instalace zásuvného modulu Plugin Reloader.¶
Pět základních kroků pro vytvoření pluginu Save Views¶
1. Vytvoření šablony nového pluginu pomocí zásuvného modulu Plugin Builder
2. Překlad qrc souboru
3. Načtení nového pluginu ve správci zásuvných modulů
4. Vytvoření uživatelského rozhraní pomocí Qt Designer
5. Implementace funkcionality pluginu v rámci Python kódu
1. Vytvoření šablony nového pluginu¶
Po spuštění zásuvného modulu pro tvorbu pluginů se
objeví dialogové okno, kde zadáme základní údaje o našem novém
nástroji, viz. Obr. 3.

Obr. 3 Dialogové okno zásuvného modulu na tvorbu pluginů. Zde vyplníme základní udáje.¶
Poznámka
Class name je název Python třídy a Module name název adresáře. U těchto položek nepoužívejte diakritiku, mezery a pod.

Obr. 4 Na další stránce průvodce vyplníme podrobné informace o našem nástroji (About).¶
V třetí části vybereme šablonu uživatelského prostředí. K dispozici jsou tři:
Tool button with dialog (samostatné okno)
Tool button with dockwidget (přichytnutelné okno)
Processing provider (poskytovatel pro nástoje zpracování, viz školení QGIS pro pokročilé)

Obr. 5 V našem případě zvolíme Tool button with dockwidget.¶
Zadáme text, který se bude zobrazovat v menu. Nakonec vybereme, pod kterou položkou v menu náš nový plugin uživatel najde.

Obr. 6 Na dalších stránce průvodce je možné ovlivnit vytvoření dalších podpůrných souborů (lokalizace, nápověda, …).¶

Obr. 7 Dále je možné vyplnit povinné a volitelné informace, například domovskou stránku, repositář modulu se zdrojovými kódy, označit nástroj jako experimentální a podobně. Tyto udaje lze doplnit ale později. Ponecháme prozatím výchozí hodnoty.¶
Následně se objeví okno, kde je potřebné zadat cestu, ve kterém se
adresář s vytvořeným pluginem vytvoří. Zvolíme vhodné umístění na
vašem disku, v našem případě /opt/qgis_plugins
.

Obr. 8 Cílový adresář, kde se vytvoří šablona s pluginem.¶
Po tomto kroku se objeví potvrzující dialog, tzv. Plugin Builder Results obsahující souhrnné informace.

Obr. 9 Souhrné informace o vytvořeném pluginu.¶
Na tomto místě najdete jednu podstatnou informaci, a to cestu k
adresáři, kde vaše instalace QGISu hledá při načítání zásuvné
moduly. Tato cesta je závislá na platfomě. Pod Linuxem je to typicky
$HOME/.local/share/QGIS/QGIS3/profiles/default/python/plugins
. Pod
Windows
%APPDATA%\Roaming\QGIS\QGIS3\profiles\default\python\plugins
.
2. Překlad qrc souboru¶
Důležité
Tento krok provede Plugin Builder automaticky, pokud je
v systémové cestě dostupný nástroj pyrcc5
.
Otevřte adresář s vytvořeným pluginem, v našem případě
/opt/qgis_plugins/save_views
. Pokud se soubor
resources.py
nevytvořil, je potřeba to napravit. Spustíme z
příkazové konzole příkaz make
. Ten vytvoří na základě Resource
Collection File (*.qrc) jeho Python přepis. Jde vlastně o spuštění
výše uvedeného pyrcc5
.
3. Načtení nového pluginu ve správci zásuvných modulů¶
K tomu, aby nový plugin QGIS po startu našel, existuje více
možností. Nejjednoduší variantou je adresář s pluginem překopírovat do
výchozí cesty zásuvných modulů, viz Krok 1. Lepší
variantou je definovat v nastavení QGISu ( ) proměnnou prostředí QGIS_PLUGINPATH
ukazující na nadřazený adresář vašeho pluginu,
tj. /opt/qgis_plugins
. Po restartu bude QGIS zobrazovat
všechny pluginy, které do tohoto adresáře v budnoucnu umístíte.
Obr. 10 Nastavení proměnné prostředí QGIS_PLUGINPATH
.¶
Po opětovném startu QGISu by měl být v sekci se objeví jeho ikona
a
nová položka v hlavním menu, tak jako jsme zadali, tj. v sekci
.

Obr. 11 Aktivace zásuvného modulu Save Views.¶
Spuštěním otevřeme dialog nástroje, který obsahuje popisek
(Obr. 12).

Obr. 12 Okno modulu Save Views po prvním spuštění.¶
Tip
V této fázi je dobré se zamyslet nad funkcionalitou pluginu, jaký bude typ vstupních dat a podobně. Na základě našich požadavků je vhodné si vytvořit testovací sadu.
Vytvoříme si jednoduchý projekt v QGISu, který bude obsahovat několik vektorových vrstev. Na Obr. 13 jsou zobrazeny například požární stanice, železnice, kraje, velkoplošné území a státní hranice České republiky.

Obr. 13 Příklad projektu s vektorovými vrstvami v QGIS.¶
4. Vytvoření uživatelského rozhraní pomocí Qt Designer¶
Vzhled a elementy dialogového okna pluginu budeme upravovat v programu Qt Designer. V hlavní liště zvolíme Obr. 14 je znázorněné prozatím prázdné okno (SaveViewsDockWidgetBase) s objekty (tzv. widgety) dockWidgetContets a label. Pomocí metody drag-and-drop je možné z levého panelu přidávat další objekty a jejich názvy a vlastnosti měnit v pravé části okna aplikace Qt Designer.
a otevřeme soubor s příponou *.ui. V našem případě save_views_dockwidget_base.ui, který najdeme v adresáři vytvořeného pluginu. Na
Obr. 14 Dialogové okno vytvářeného pluginu v prostředí aplikace Qt Designer.¶
Nejrpve v pravém panelu změníme předvolený text objektu label na
Select a layer
(Obr. 15).
Obr. 15 Editace objektů dialogového okna.¶
Dále v levé části okna najdeme objekt typu Combo Box a tažením myši jej umistíme do vhodného místa okna zásuvného modulu.

Obr. 16 Přidání nového widgetu typu Combo Box.¶
Tip
Pro reálný vývoj je vhodné výchozí názvy objektů (v našem případě label a comboBox) nastavit na hodnoty odpovídajícím reálnému využití, např.místo combobox layerSelect a pod.
Po uložení |plugin-reloader|. V Choose a plugin to be reloaded nastavíme SaveViews (Obr. 17) a plugin spustíme. Tím se aktualizuje podoba našeho pluginu.
přejdeme do prostředí QGIS, kde použijeme plugin Plugin Reloader
Obr. 17 Konfigurace zásuvného modulu Plugin Reloader.¶
Po kliknutí na ikonu se otevře okno odpovídající návrhu na
Obr. 15.

Obr. 18 Okno modulu Save Views po úpravě uživatelského rozhraní.¶
5. Implementace funkcionality nástroje a další úpravy¶
Řekněme, že chceme, aby se po spuštění pluginu Combo Box automaticky
naplnil vektorovými vrstvami aktuálního projektu. Hlavním souborem,
který se stará o logiku jednotlivých objektů, je v našem případě
save_views.py
. Otevřeme jej v textovém editoru a najdeme
metodu run()
. Tato metoda se spouští při každém startu pluginu. Na
její konec umístíme následující kód (Obr. 19).
# populate the Combo Box with the vector layers loaded in QGIS
from qgis.core import QgsProject, QgsMapLayer
self.dockwidget.comboBox.clear()
for layer in QgsProject.instance().mapLayers().values():
if layer.type() != QgsMapLayer.VectorLayer:
continue
self.dockwidget.comboBox.addItem(layer.name())
Obr. 19 Úprava zdrojového kódu s cílem naplnit Combo Box vektorovými vrstvami.¶
Po znovu načtení pluginu |plugin-reloader| a jeho otevření je
vidět, že se změny úspěšně projevily (Obr. 20).

Obr. 20 Vzhled dialogového okna po změnách ve zdrojovém kódu.¶
Poznámka
V případě, že skončí spustění či znovunačtení chybou, tak hledejte relevatní informace ve Zprávách výpisů, konkrétně v záložce Python chyba.

Tip
Namísto obecného objektu Combo Box by bylo možné použít
specifický widget QGISu, a to QgsMapLayerComboBox
. Využití
tohoto specifického widgetu by nám ušetřilo pár řádek kódu.
Todo
doplnit nazev tridy
Úkol
Seznam vrstev se načítá pouze při spuštění pluginu. Upravte zdrojový kód tak, aby umožňoval znovunačtení seznamu vrstev i během běhu pluginu.
Obdobně vložíme do okna další elementy a přiřadíme jim příslušnou
funkcionalitu. Kromě popisu Select output directory
půjde o
objekty Line Edit, Tool Button, Push Button. U widgetu
pushButton ve vlastnostech změníme text na Save All
. Nastavíme
přiměřené rozměry pro každý element a upravený soubor uložíme.
Důležité jsou názvy jednotlivých objektů, viz. Obr. 21,
budeme je ještě potřebovat.
Obr. 21 Finální návrh uživatelského rozhraní pluginu Save Views.¶
Poznámka
Pokud je uživatelské rozhraní definováno více objekty (widgety) je vhodné je rozumně pojmenovat. V případě našeho jednoduchého modulu si vystačíme s předvolenými názvy.
V dalším kroku potřebujeme přidat kód, který zabezpečí, aby se po
kliknutí na tlačítko ...
otevřel dialog, ve kterém zvolíme adresář
pro uložení výsledných obrazových souborů pro každý prvek ve vybrané
vektorové vrstvě. O tuto funkcionalitu se postará nová metoda
select_output_directory()
, kterou přidáme na konec souboru
save_views.py
, Obr. 22.
# open directory browser and populate the line edit widget
def select_output_dir(self):
from PyQt5.QtWidgets import QFileDialog
self.dirname = QFileDialog.getExistingDirectory(
self.dockwidget, "Select directory ", os.path.expanduser("~")
)
self.dockwidget.lineEdit.setText(self.dirname)
Tip
os.path.expanduser("~")
nastaví cestu při otevření
dialogu na domovský adresář.
Poznámka
Kód importující použité třídy jako např. from
PyQt5.Widgets import QFileDialog
je vhodnější umístit na začátek
souboru. Zde uvádíme především pro přehlednost úprav.

Obr. 22 Metoda, která otevře dialog pro výběr výstupního adresáře.¶
Úkol
Upravte zdrojový kód tak, aby si dialog pamatoval poslední použitý adresář.
Následně propojíme metodu select_output_dir()
s tlačítkem
toolButton
(tlačítko ...
). To provedeme přidáním níže
uvedených řádků do metody __run__()
, nejlépe na konec těla
podmínky if self.dockwidget == None
, viz
Obr. 22.
# connect the select_output_file() method to the clicked signal of the tool button widget
self.dockwidget.toolButton.clicked.connect(self.select_output_dir)
Na konec metody __run__()
ještě přidáme kód zajišťující obnovení
prázdného obsahu objektu lineEdit
.
# clear the previously loaded text (if any) in the line edit widget
self.dockwidget.lineEdit.clear()
Obr. 23 Úpravy v kódu zajišťující propojení metody select_output_dir()
a tlačítka ...
.¶
Soubor uložíme, plugin znovu načteme a vyzkoušíme (Obr. 24).

Obr. 24 Načtení adresáře pro grafické výstupy pomocí nového pluginu.¶
Posledním krokem je změnit to, aby se po kliknutí na tlačítko Save
all
opravdu provedlo, co chceme. Vytvoříme novou metodu
save_views()
, kterou umístíme na konec souboru
save_views.py
, viz Obr. 25.
def save_views(self):
from PyQt5.QtGui import QColor, QPixmap
from qgis.core import QgsProject
from qgis.utils import iface
# save graphical output for every row in attribute table
layer_name = self.dockwidget.comboBox.currentText()
layer = QgsProject.instance().mapLayersByName(layer_name)[0]
for feature in layer.getFeatures():
layer.selectByIds([feature.id()])
self.iface.mapCanvas().setSelectionColor(QColor("transparent"));
box = layer.boundingBoxOfSelected()
self.iface.mapCanvas().setExtent(box)
pixmap = QPixmap(self.iface.mapCanvas().mapSettings().outputSize().width(),
self.iface.mapCanvas().mapSettings().outputSize().height()
)
mapfile = os.path.join(self.dirname, '{0}_{1:03d}.png'.format(layer_name, feature.id()))
self.iface.mapCanvas().saveAsImage(mapfile, pixmap)
layer.removeSelection()
# save also full extend of vector layer
canvas = self.iface.mapCanvas()
canvas.setExtent(layer.extent())
pixmap = QPixmap(self.iface.mapCanvas().mapSettings().outputSize().width(),
self.iface.mapCanvas().mapSettings().outputSize().height()
)
mapfile = os.path.join(self.dirname, '{}_full.png'.format(layer_name))
self.iface.mapCanvas().saveAsImage(mapfile, pixmap)
Tuto metodu provážeme s tlačítkem Save all
.
# connect the save_views() method to the clicked signal of the push button widget
self.dockwidget.pushButton.clicked.connect(self.save_views)
Obr. 25 Doplnění kódu do metody run().¶
Úkol
Opravte chybu, která nastane po stisknutí tlačítka Save
all
v případě, že není nastaven adresář pro výstupní soubory.
Úkol
Upravte kód tak, aby mohl zadat uživatel výstupní adresář
ručně bez tlačítka ...
.
Grafické výstupy po aplikovaní na vrstvu krajů jsou zobrazeny na Obr. 26. Jejich názvy v adresáři závisí na názvu konkrétní vektorové vrstvy. Liší se pouze pořadovým číslem.

Obr. 26 Grafické soubory uložené ve zvoleném adresáři pro vektorovou vrstvu krajů České republiky.¶
Tip
V případě, že chceme změnit ikonu, stačí nový soubor s ikonkou,
např. Obr. 27, uložit do adresáře save_views
jako soubor icon.png
a spustit příkaz make clean && make
v
příkazové řádce. Nakonec znovunačteme plugin pomocí modulu Plugin
Reloader.

Obr. 27 Příklad nové ikonky¶
Výsledný soubor save_views.py
je ke stažení také zde.
Jiný příklad využití¶
Na obrázku Obr. 28 je uveden projekt s katastrálními daty. Vyznačené jsou parcely, přes které budou procházet plánované inženýrské sítě.

Obr. 28 Znázornění parcel přes které májí procházet plánované inženýrské sítě.¶
Použitím pluginu Save Views můžeme pro každého vlastníka vyhodnotit grafické znázornění jeho parcely, na které bude zapsané věcné břemeno (Obr. 29).

Obr. 29 Pohled na každou parcelu jako výsledek zásuvného modulu Save Views.¶