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
../../_images/errorbar.png

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
../../_images/errorbar-timed.png

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:

  1. Info

  2. Varning

  3. Kritiskt

  4. Lyckades

../../_images/infobar.png

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
../../_images/bar-button.png

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()
../../_images/dialog-with-bar.png

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.