13. Communiceren met de gebruiker
Hint
De codesnippers op deze pagina hebben de volgende import nodig als u buiten de console van PyQGIS bent:
1from qgis.core import (
2 QgsMessageLog,
3 QgsGeometry,
4)
5
6from qgis.gui import (
7 QgsMessageBar,
8)
9
10from qgis.PyQt.QtWidgets import (
11 QSizePolicy,
12 QPushButton,
13 QDialog,
14 QGridLayout,
15 QDialogButtonBox,
16)
Dit gedeelte geeft enkele methoden en elementen weer die zouden moeten worden gebruikt om te communiceren met de gebruiker, om consistentie in de gebruikersinterface te behouden.
13.1. Berichten weergeven. De klasse QgsMessageBar
Het gebruiken van berichtenvakken kan een slecht idee zijn vanuit het gezichtspunt van de gebruiker. Voor het weergeven van een korte regel met informatie of een waarschuwing/foutberichten, is de QGIS berichtenbalk gewoonlijk een betere optie.
U kunt, met behulp van de verwijzing naar het interface-object van QGIS, een bericht weergeven in de berichtenbalk met de volgende code
from qgis.core import Qgis
iface.messageBar().pushMessage("Error", "I'm sorry Dave, I'm afraid I can't do that", level=Qgis.Critical)
Messages(2): Error : I'm sorry Dave, I'm afraid I can't do that
U kunt een duur instellen om het voor een beperkte tijd weer te geven
iface.messageBar().pushMessage("Ooops", "The plugin is not working as it should", level=Qgis.Critical, duration=3)
Messages(2): Ooops : The plugin is not working as it should
Het voorbeeld hierboven geeft een foutenbalk weer, maar de parameter level
kan worden gebruikt om waarschuwingen of informatie-berichten te maken, respectievelijk met behulp van de enumeratie Qgis.MessageLevel
. U kunt tot maximaal 4 verschillende niveaus gebruiken.
Informatie
Waarschuwing
Kritisch
Succes
Widgets kunnen aan de berichtenbalk worden toegevoegd, zoals bijvoorbeeld een knop om meer informatie weer te geven
1def showError():
2 pass
3
4widget = iface.messageBar().createMessage("Missing Layers", "Show Me")
5button = QPushButton(widget)
6button.setText("Show Me")
7button.pressed.connect(showError)
8widget.layout().addWidget(button)
9iface.messageBar().pushWidget(widget, Qgis.Warning)
Messages(1): Missing Layers : Show Me
U kunt zelfs een berichtenbalk in uw eigen dialoogvenster gebruiken zodat u geen berichtenvak hoeft weer te geven, of als het geen zin heeft om het in het hoofdvenster van QGIS weer te geven
1class MyDialog(QDialog):
2 def __init__(self):
3 QDialog.__init__(self)
4 self.bar = QgsMessageBar()
5 self.bar.setSizePolicy( QSizePolicy.Minimum, QSizePolicy.Fixed )
6 self.setLayout(QGridLayout())
7 self.layout().setContentsMargins(0, 0, 0, 0)
8 self.buttonbox = QDialogButtonBox(QDialogButtonBox.Ok)
9 self.buttonbox.accepted.connect(self.run)
10 self.layout().addWidget(self.buttonbox, 0, 0, 2, 1)
11 self.layout().addWidget(self.bar, 0, 0, 1, 1)
12 def run(self):
13 self.bar.pushMessage("Hello", "World", level=Qgis.Info)
14
15myDlg = MyDialog()
16myDlg.show()
13.2. Voortgang weergeven
Voortgangsbalken kunnen ook worden opgenomen in de berichtenbalk van QGIS, omdat, zoals we al hebben gezien, die widgets accepteert. Hier is een voorbeeld dat u kunt proberen in de console.
1import time
2from qgis.PyQt.QtWidgets import QProgressBar
3from qgis.PyQt.QtCore import *
4progressMessageBar = iface.messageBar().createMessage("Doing something boring...")
5progress = QProgressBar()
6progress.setMaximum(10)
7progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
8progressMessageBar.layout().addWidget(progress)
9iface.messageBar().pushWidget(progressMessageBar, Qgis.Info)
10
11for i in range(10):
12 time.sleep(1)
13 progress.setValue(i + 1)
14
15iface.messageBar().clearWidgets()
Messages(0): Doing something boring...
U kunt ook de ingebouwde statusbalk gebruiken om de voortgang weer te geven, zoals in het volgende voorbeeld:
1vlayer = iface.activeLayer()
2
3count = vlayer.featureCount()
4features = vlayer.getFeatures()
5
6for i, feature in enumerate(features):
7 # do something time-consuming here
8 print('.') # printing should give enough time to present the progress
9
10 percent = i / float(count) * 100
11 # iface.mainWindow().statusBar().showMessage("Processed {} %".format(int(percent)))
12 iface.statusBarIface().showMessage("Processed {} %".format(int(percent)))
13
14iface.statusBarIface().clearMessage()
13.3. Loggen
Er zijn in QGIS drie verschillende soorten loggen beschikbaar om alle informatie over het uitvoeren van uw code te loggen en op te slaan. Elk heeft zijn eigen specifieke locatie voor de uitvoer. Bepaal eerst de juiste manier van loggen voor uw doel:
QgsMessageLog
is voor het communiceren met gebruikers van problemen. De uitvoer van het QgsMessageLog wordt weergegeven in het paneel Logboekberichten.De ingebouwde module van Python voor logging is voor het debuggen op het niveau van de QGIS Python API (PyQGIS). Het wordt aanbevolen aan scriptontwikkelaars in Python die hun code voor Python moeten debuggen, bijv. object-ID’s of geometrieën
QgsLogger
is voor berichten voor QGIS intern debuggen / ontwikkelaars d.i. als u vermoedt dat zij worden veroorzaakt door een beschadigde code). Berichten zijn alleen zichtbaar in ontwikkelversies van QGIS.
Voorbeelden voor de verschillende typen van loggen worden weergegeven in de volgende gedeelten hieronder.
Waarschuwing
Gebruiken van het argument print
in Python is niet veilig om in enige code te gebruiken die multithreaded zou kunnen zijn en vertraagt het algoritme extreem. Dit omvat functies voor expressies, renderers, symboollagen en algoritmes voor Processing (naast andere). In deze gevallen zou u in plaats daarvan altijd de module van Python logging of thread-veilige klassen (QgsLogger
of QgsMessageLog
) moeten gebruiken.
13.3.1. QgsMessageLog
# You can optionally pass a 'tag' and a 'level' parameters
QgsMessageLog.logMessage("Your plugin code has been executed correctly", 'MyPlugin', level=Qgis.Info)
QgsMessageLog.logMessage("Your plugin code might have some problems", level=Qgis.Warning)
QgsMessageLog.logMessage("Your plugin code has crashed!", level=Qgis.Critical)
MyPlugin(0): Your plugin code has been executed correctly
(1): Your plugin code might have some problems
(2): Your plugin code has crashed!
Notitie
U kunt de uitvoer van QgsMessageLog
zien in het Paneel Logboekmeldingen
13.3.2. De ingebouwde module voor loggen in Python
1import logging
2formatter = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
3logfilename=r'c:\temp\example.log'
4logging.basicConfig(filename=logfilename, level=logging.DEBUG, format=formatter)
5logging.info("This logging info text goes into the file")
6logging.debug("This logging debug text goes into the file as well")
De methode basicConfig configureert de basis instelling van het loggen. In de bovenstaande code worden de bestandsnaam, het niveau van loggen en de indeling gedefinieerd. De bestandsnaam verwijst naar waar het logbestand moet worden weggeschreven, het niveau van loggen definieert welke niveaus moeten worden uitgevoerd en de indeling definieert de indeling waarin elk bericht wordt uitgevoerd.
2020-10-08 13:14:42,998 - root - INFO - This logging text goes into the file
2020-10-08 13:14:42,998 - root - DEBUG - This logging debug text goes into the file as well
Als u het logbestand wilt verwijderen, elke keer als u uw script uitvoert, kunt u iets doen als:
if os.path.isfile(logfilename):
with open(logfilename, 'w') as file:
pass
Meer bronnen over hoe de mogelijkheden voor loggen in Python te gebruiken zijn beschikbaar op:
Waarschuwing
Onthoud dat loggen zonder dat naar en bestand te sturen door een bestandsnaam in te stellen het loggen multithreaded zou kunnen zijn, wat de uitvoer in hoge mate vertraagt.