Het is mogelijk plug-ins te maken in de programmeertaal Python. In vergelijking met de klassieke plug-ins die zijn geschreven in C++ zouden deze eenvoudiger te schrijven, te begrijpen, te onderhouden en te verdelen zijn vanwege de dynamische natuur van de taal Python.
Plug-ins in Python worden samen met plug-ins in C++ vermeld in Beheer en installeer plug-ins in QGIS. Er wordt naar gezocht in deze paden:
Sinds de introductie van plug-ins in Python in QGIS, zijn een anatal Plug-ins verschenen - op Plugin Repositories wiki page kunt u er enkele van vinden, u kunt hun bronnen gebruiken om meer te leren over het programmeren met PyQGIS of uitzoeken of u de inspanningen voor de ontwikkeling niet dupliceert. Het team van QGIS onderhoudt ook een Officiële Python plug-in opslagplaats. Klaar om een plug-in te maken, maar geen idee wat te doen? Python Plugin Ideas wiki page vermeldt wensen van de gemeenschap!
Hier is de mappenstructuur van uw voorbeeld-plug-in
PYTHON_PLUGINS_PATH/
MyPlugin/
__init__.py --> *required*
mainPlugin.py --> *required*
metadata.txt --> *required*
resources.qrc --> *likely useful*
resources.py --> *compiled version, likely useful*
form.ui --> *likely useful*
form.py --> *compiled version, likely useful*
Wat is de betekenis van de bestanden:
__init__.py = Het beginpunt van de plug-in. Het moet de methode classFactory() hebben en mag elke andere code voor initialisatie hebben.
mainPlugin.py = De belangrijkste werkende code van de plug-in. Bevat alle informatie over de acties van de plug-in en de hoofdcode.
resources.qrc = Het door Qt Designer gemaakte .xml-document. Bevat relatieve paden naar de bronnen van de formulieren.
resources.py = De vertaling van het bestand .qrc, hierboven beschreven, naar Python.
form.ui = De GUI, gemaakt door Qt Designer.
form.py = De vertaling van de form.ui, hierboven beschreven, naar Python.
metadata.txt = Vereist voor QGIS >= 1.8.0. bevat algemene informatie, versie, naam en enkele andere metadata, gebruikt door de website van de plug-in en infrastructuur van de plug-in. Vanaf QGIS 2.0 wordt de metadata uit __init__.py niet meer geaccepteerd en is het bestand metadata.txt vereist.
Hier staat een online geautomatiseerde manier voor het maken van de basisbestanden (skelet) van een typische plug-in voor Python in QGIS.
Er is ook een plug-in voor QGIS, genaamd Plugin Builder die een sjabloon voor een plug-in maakt uit QGIS en geen internetverbinding vereist. Dit is de aanbevolen optie, omdat het compatibele bronnen produceert voor 2.0.
Hier vindt u informatie en voorbeelden over wat in elk van de bestanden moet worden toegevoegd in de hierboven beschreven bestandsstructuur.
Dit bestand wordt vereist door het systeem voor importeren van Python. Ook vereist QGIS dat dit bestand een functie classFactory() bevat, die wordt aangeroepen als de plug-in wordt geladen in QGIS. Het ontvangt een verwijzing naar de instance van QgisInterface en moet een instance teruggeven van de klasse van uw plug-in uit mainplugin.py — in ons geval is dat genaamd TestPlugin (zie hieronder). Zo zou __init__.py er uit moeten zien
def classFactory(iface):
from mainPlugin import TestPlugin
return TestPlugin(iface)
## any other initialisation needed
Dit is waar de magie gebeurt en dit is hoe de magie eruit ziet: (biijv. mainPlugin.py)
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
# initialize Qt resources from file resources.py
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(":/plugins/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")
QObject.connect(self.action, SIGNAL("triggered()"), 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
QObject.connect(self.iface.mapCanvas(), SIGNAL("renderComplete(QPainter *)"), 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
QObject.disconnect(self.iface.mapCanvas(), SIGNAL("renderComplete(QPainter *)"), 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 enige functies voor plug-ins die moeten bestaan in het hoofd-bronbestand (bijv. mainPlugin.py) zijn:
__init__ –> wat toegang geeft tot de interface van QGIS
initGui() –> aangeroepen wanneer de plug-in wordt geladen
unload() –> aangeroepen wanneer de plug-in wordt ontladen
U kunt zien dat in het voorbeeld hierboven addPluginToMenu() is gebruikt. Dit zal de overeenkomstige menuactie toevoegen aan het menu . Alternatieve methoden bestaan om de actie aan een ander menu toe te wijzen. Hier is een lijst met die methoden:
- addPluginToRasterMenu()
- addPluginToVectorMenu()
- addPluginToDatabaseMenu()
- addPluginToWebMenu()
Alle hebben dezelfde syntaxis als de methode addPluginToMenu().
Toevoegen van het menu van uw plug-in aan een van de voorgedefinieerde methoden wordt aanbevolen om consistentie te behouden in hoe items voor plug-ins zijn georganiseerd. U kunt echter uw aangepaste groepen voor het menu direct aan de Menubalk toevoegen, zoals het volgende voorbeeld demonstreert:
def initGui(self):
self.menu = QMenu(self.iface.mainWindow())
self.menu.setObjectName("testMenu")
self.menu.setTitle("MyMenu")
self.action = QAction(QIcon(":/plugins/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")
QObject.connect(self.action, SIGNAL("triggered()"), 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()
Vergeet niet om QAction en QMenu objectName in te stellen op een naam die specifiek is voor uw plug-in zodat hij kan worden aangepast.
U kunt zien dat we in initGui() een pictogram hebben gebruikt uit het bronbestand (in ons geval resources.qrc aangeroepen)
<RCC>
<qresource prefix="/plugins/testplug" >
<file>icon.png</file>
</qresource>
</RCC>
Het is goed om een voorvoegsel te gebruiken dat niet zal botsen met andere plug-ins of andere delen van QGIS, anders krijgt u misschien bronnen die u niet wilt. Nu dient nog slechts een bestand in Python te genereren dat de bronnen zal bevatten. dat wordt gedaan met de opdracht pyrcc4
pyrcc4 -o resources.py resources.qrc
Notitie
In omgevingen van Windows zal het proberen uit te voeren van de opdracht pyrcc4 vanuit de Opdracht prompt of Powershell resulteren in de fout “Windows cannot access the specified device, path, or file [...]”. De eenvoudigste oplossing is waarschijnlijk om de OSGeo4W Shell te gebruiken maar als u er niet voor terugschrikt om de omgevingsvariabele PATH aan te passen of het pad naar het uitvoerbare bestand expliciet te specificeren zou u in staat moeten zijn het te vinden op <Your QGIS Install Directory>\bin\pyrcc4.exe.
En dat is alles... niets gecompliceerds :)
Als u alles juist heeft gedaan zou u in staat moeten zijn uw plug-in op te zoeken en te laden vanuit Beheer en installeer plug-ins en een bericht in de console te zien wanneer het pictogram op de werkbalk of het menuitem is geselecteerd.
Bij het werken aan een echte plug-in is het verstandig om de plug-in in een andere (werk-)map te schrijven en een makefile te maken dat de UI + bronbestanden zal genereren en de plug-in zal installeren in uw installatie van QGIS.
De documentatie voor de plug-in mag worden geschreven als helpbestanden in HTML. De module qgis.utils verschaft een functie, showPluginHelp() dat de browser voor Helpbestanden zal openen, op dezelfde manier als andere help voor QGIS.
De functie showPluginHelp`() zoekt naar de helpbestanden in dezelfde map als waar de module wordt aangeroepen. Het zal zoeken naar, op volgorde, index-ll_cc.html, index-ll.html, index-en.html, index-en_us.html en index.html, en geeft die, welke als eerste wordt gevonden, weer. Hier is ll_cc de locale van QGIS. Dit maakt het mogelijk meerdere vertalingen van de documentatie op te nemen met de plug-in.
De functie showPluginHelp() kan ook de parameters packageName , welke een specifieke plug-in specificeert waarvoor de Helpbestanden zullen worden weergegeven, filename, wat “index” mag vervangen in de namen van de gezochte bestanden, en section, wat de naam is van een tag voor een HTML-anker in het document waar de browser zal worden gepositioneerd, aannemen.
Met enkele stappen kunt u de omgeving instellen voor de vertaling van de plug-in zodat, afhankelijk van de instellingen voor de locale op uw computer, zal de plug-in worden geladen in verschillende talen.
De eenvoudigste manier om alle bestanden voor vertalingen te maken en te beheren is om Qt Linguist te installeren. In een op Debian gebaseerde GNU/ Linux-achtige omgeving kunt u het installeren door te typen:
sudo apt-get install qt4-dev-tools
Wanneer u de plug-in maakt vindt u de map i18n in de hoofdmap van de map.
Alle bestanden voor de vertalingen moeten in deze map staan.
Eerst zou u een .pro-bestand moeten maken, dat is een project-bestand dat kan worden beheerd door Qt Linguist.
In dit .pro-bestand dient u alle bestanden en formulieren te specificeren die u wilt vertalen. Dit bestand wordt gebruikt om de bestanden en variabelen voor de vertalingen in te stellen. Een mogelijk projectbestand dat overeenkomt met de structuur van onze example plugin:
FORMS = ../form.ui
SOURCES = ../your_plugin.py
TRANSLATIONS = your_plugin_it.ts
Uw plug-in zou een meer complexe structuur kunnen hebben, en het zou uit meerdere verschillende bestanden kunnen bestaan. Als dat het geval is, onthoud dan dat pylupdate4, het programma dat we gebruiken om het .pro-bestand te lezen en de te vertalen tekenreeksen bij te werken, geen jokertekens toestaat, dus dient u elk bestand expliciet te vermelden in het .pro-bestand. Uw projectbestand zou er dan mogelijk als volgt uit kunnen zien:
FORMS = ../ui/about.ui ../ui/feedback.ui \
../ui/main_dialog.ui
SOURCES = ../your_plugin.py ../computation.py \
../utils.py
Verder is het bestand your_plugin.py het bestand dat alle menu’s en sub-menu’s van uw plug-in in de werkbalk van QGIS aanroept en u wilt het in zijn geheel vertalen.
Tenslotte kunt u met de variabele TRANSLATIONS de vertaalde talen specificeren die u wilt.
Waarschuwing
Zorg er voor het bestand ts net zo te noemen als your_plugin_ + language + .ts anders zal het laden van de taal mislukken! Gebruik 2-letterige afkortingen voor de taal (it voor Italiaans, de voor Duits, etc...)
Als u eenmaal de .pro hebt gemaakt bent u gereed om de/het .ts bestand(en) van de taal(talen) voor uw plug-in te genereren.
Open een terminal, ga naar de map your_plugin/i18n en type:
pylupdate4 your_plugin.pro
u zou het/de bestand(en) your_plugin_language.ts moeten zien.
Open het bestand .ts met Qt Linguist en begin met vertalen.
Wanneer het vertalen van uw plug-in voltooid is (als enkele tekenreeksen niet voltooid zijn zal de taal van de bron worden gebruikt voor die tekenreeksen) dient u het bestand .qm te maken (het gecompileerde .ts-bestand dat zal worden gebruikt door QGIS).
Open een terminal, cd naar de map your_plugin/i18n en type:
nu zou u in de map i18n het/de bestand(en) your_plugin_language.ts moeten zien.
Alternatively you can use the makefile to extract messages from python code and
Qt dialogs, if you created your plugin with Plugin Builder.
At the beginning of the Makefile there is a LOCALES variable:
Add the abbreviation of the language to this variable, for example for
Hungarian language:
Now you can generate or update the hu.ts file (and the en.ts too)
from the sources by:
After this, you have updated .ts file for all languages set in the LOCALES
variable.
Use Qt4 Linguist to translate the program messages.
Finishing the translation the .qm files can be created by the transcompile:
You have to distribute .ts files with your plugin.
Open QGIS, wijzig de taal () en herstart QGIS om de vertaling van uw plug-in te zien.
U zou uw plug-in in de juiste taal moeten zien.
Waarschuwing
Indien u iets wijzigt in uw plug-in (nieuwe UI’s, nieuw menu, etc..) dient de bijgewerkte versie van de bestanden .ts en .qm opnieuw te generen, voer dus opnieuw de hierboven genoemde opdracht uit.