Comunicare con l’utente

Questa sezione mostra alcuni metodi ed elementi che dovrebbero essere usati per comunicare con l’utente, in modo da mantenere la consistenza nell’interfaccia utente.

Showing messages. The QgsMessageBar class

Utilizzare il box dei messaggi potrebbe essere una cattiva idea dal punto di vista dell’esperienza utente. Solitamente, per mostrare un messaggio di informazione o di errore/avvertimento, la barra dei messaggi di QGIS é l’opzione migliore.

Utilizzando il riferimento all’oggetto interfaccia di QGIS, é possibile mostrare un messaggio nell barra dei messaggi utilizzando il seguente codice

from qgis.core import Qgis
iface.messageBar().pushMessage("Error", "I'm sorry Dave, I'm afraid I can't do that", level=Qgis.Critical)
../../_images/errorbar.png

Barra dei messaggi di QGIS

É possibile impostare una durata per mostrarlo per un tempo limitato

iface.messageBar().pushMessage("Ooops", "The plugin is not working as it should", level=Qgis.Critical, duration=3)
../../_images/errorbar-timed.png

Barra dei messaggi di QGIS con timer

The examples above show an error bar, but the level parameter can be used to creating warning messages or info messages, using the Qgis.MessageLevel enumeration. You can use up to 4 different levels:

  1. Info
  2. Warning
  3. Critical
  4. Success
../../_images/infobar.png

Barra dei messaggi di QGIS (informazioni)

I widget possono essere aggiunti alla barra dei messaggi, ad esempio il pulsante per mostrare piú informazioni

def showError():
    pass

widget = iface.messageBar().createMessage("Missing Layers", "Show Me")
button = QPushButton(widget)
button.setText("Show Me")
button.pressed.connect(showError)
widget.layout().addWidget(button)
iface.messageBar().pushWidget(widget, Qgis.Warning)
../../_images/bar-button.png

Barra dei messaggi di QGIS con un pulsante

É possibile usare una barra dei messaggi nella propria finestra di dialogo senza dover mostrare una finestra di messaggi, o nel caso in cui non abbia senso mostrarla nella finestra principale di QGIS.

class MyDialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.bar = QgsMessageBar()
        self.bar.setSizePolicy( QSizePolicy.Minimum, QSizePolicy.Fixed )
        self.setLayout(QGridLayout())
        self.layout().setContentsMargins(0, 0, 0, 0)
        self.buttonbox = QDialogButtonBox(QDialogButtonBox.Ok)
        self.buttonbox.accepted.connect(self.run)
        self.layout().addWidget(self.buttonbox, 0, 0, 2, 1)
        self.layout().addWidget(self.bar, 0, 0, 1, 1)
    def run(self):
        self.bar.pushMessage("Hello", "World", level=Qgis.Info)

myDlg = MyDialog()
myDlg.show()
../../_images/dialog-with-bar.png

Barra dei messaggi di QGIS in una finestra di dialogo personalizzata

Mostrare l’avanzamento

Le barre di avanzamento si possono mettere anche nella barra dei messaggi di QGIS, dato che, come abbiamo visto, accetta i widget. Di seguito un esempio che potrete provare nella console.

import time
from qgis.PyQt.QtWidgets import QProgressBar
from qgis.PyQt.QtCore import *
progressMessageBar = iface.messageBar().createMessage("Doing something boring...")
progress = QProgressBar()
progress.setMaximum(10)
progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
progressMessageBar.layout().addWidget(progress)
iface.messageBar().pushWidget(progressMessageBar, Qgis.Info)

for i in range(10):
    time.sleep(1)
    progress.setValue(i + 1)

iface.messageBar().clearWidgets()

Also, you can use the built-in status bar to report progress, as in the next example:

vlayer = QgsProject.instance().mapLayersByName("countries")[0]

count = vlayer.featureCount()
features = vlayer.getFeatures()

for i, feature in enumerate(features):
    # do something time-consuming here
    print('') # printing should give enough time to present the progress

    percent = i / float(count) * 100
    # iface.mainWindow().statusBar().showMessage("Processed {} %".format(int(percent)))
    iface.statusBarIface().showMessage("Processed {} %".format(int(percent)))

iface.statusBarIface().clearMessage()

Logging

É possibile utilizzare il sistema di logging di QGIS per annotare tutte le informazioni che riguardano l’esecuzione del codice che si vogliono salvare.

# 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)

Avvertimento

Use of the Python print statement is unsafe to do in any code which may be multithreaded. This includes expression functions, renderers, symbol layers and Processing algorithms (amongst others). In these cases you should always use thread safe classes (QgsLogger or QgsMessageLog) instead.

Nota

You can see the output of the QgsMessageLog in the Pannello Messaggi di Log

Nota

  • QgsLogger is for messages for debugging / developers (i.e. you suspect they are triggered by some broken code)
  • QgsMessageLog is for messages to investigate issues by sysadmins (e.g. to help a sysadmin to fix configurations)