Viktigt
Översättning är en gemenskapsinsats du kan gå med i. Den här sidan är för närvarande översatt till 100.00%.
13. Kommunicera med användaren
Råd
Kodsnuttarna på den här sidan behöver följande import om du befinner dig utanför pyqgis-konsolen:
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)
I det här avsnittet beskrivs några metoder och element som bör användas för att kommunicera med användaren, så att användargränssnittet blir konsekvent.
13.1. Visning av meddelanden. Klassen QgsMessageBar
Att använda meddelanderutor kan vara en dålig idé ur användarupplevelsesynpunkt. För att visa en liten informationsrad eller ett varnings-/felmeddelande är QGIS meddelandefält vanligtvis ett bättre alternativ.
Med hjälp av referensen till QGIS-gränssnittsobjektet kan du visa ett meddelande i meddelandefältet med följande kod
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

Fig. 13.28 QGIS meddelandefält
Du kan ställa in en varaktighet för att visa den under en begränsad tid
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

Fig. 13.29 QGIS meddelandefält med timer
Exemplen ovan visar en felrad, men parametern level
kan användas för att skapa varningsmeddelanden eller informationsmeddelanden med hjälp av Qgis.MessageLevel
uppräkning. Du kan använda upp till 4 olika nivåer:
Info
Varning
Kritiskt
Lyckades

Fig. 13.30 QGIS meddelandefält (info)
Widgets kan läggas till i meddelandefältet, t.ex. en knapp för att visa mer information
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

Fig. 13.31 QGIS meddelandefält med en knapp
Du kan även använda ett meddelandefält i din egen dialogruta så att du inte behöver visa en meddelanderuta, eller om det inte är meningsfullt att visa den i QGIS huvudfönster
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()

Fig. 13.32 QGIS meddelandefält i anpassad dialog
13.2. Visar framsteg
Progressfält kan också placeras i QGIS meddelandefält, eftersom det, som vi har sett, accepterar widgetar. Här är ett exempel som du kan prova i konsolen.
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...
Du kan också använda den inbyggda statusfältet för att rapportera framsteg, som i nästa exempel:
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. Loggning
Det finns tre olika typer av loggning tillgängliga i QGIS för att logga och spara all information om körningen av din kod. Var och en har sin specifika utmatningsplats. Tänk på att använda rätt loggningssätt för ditt ändamål:
QgsMessageLog
är för meddelanden för att kommunicera problem till användaren. Utdata från QgsMessageLog visas i panelen för loggmeddelanden.Den i Python inbyggda logging-modulen är avsedd för felsökning på samma nivå som QGIS Python API (PyQGIS). Den rekommenderas för Python-skriptutvecklare som behöver felsöka sin Python-kod, t.ex. objekt-ID:n eller geometrier
QgsLogger
är för meddelanden för QGIS intern felsökning / utvecklare (dvs. du misstänker att något utlöses av någon trasig kod). Meddelanden är endast synliga med utvecklarversioner av QGIS.
Exempel på de olika loggningstyperna visas i följande avsnitt nedan.
Varning
Användning av Pythons print
-sats är osäkert att göra i all kod som kan vara flertrådad och extremt saktar ner algoritmen. Detta inkluderar uttrycksfunktioner, renderare, symbolskikt och behandlingsalgoritmer (bland andra). I dessa fall bör du alltid använda pythonmodulen logging eller trådsäkra klasser (QgsLogger
eller QgsMessageLog
) istället.
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!
Observera
Du kan se utdata från QgsMessageLog
i Panel för loggmeddelanden
13.3.2. Den inbyggda loggningsmodulen i 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")
Metoden basicConfig konfigurerar den grundläggande inställningen för loggningen. I koden ovan definieras filnamn, loggningsnivå och format. Filnamnet anger var loggfilen ska skrivas, loggningsnivån definierar vilka nivåer som ska matas ut och formatet definierar i vilket format varje meddelande ska matas ut.
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
Om du vill radera loggfilen varje gång du kör ditt skript kan du göra något liknande:
if os.path.isfile(logfilename):
with open(logfilename, 'w') as file:
pass
Mer information om hur du använder python-loggningsfunktionen finns på
Varning
Observera att om du inte loggar till en fil genom att ange ett filnamn kan loggningen vara flertrådad, vilket gör att utdata går långsammare.