16.2. Blocchi di codice

Suggerimento

I frammenti di codice di questa pagina necessitano delle seguenti importazioni se sei è al di fuori della console pyqgis:

 1from qgis.core import (
 2    QgsProject,
 3    QgsApplication,
 4    QgsMapLayer,
 5)
 6
 7from qgis.gui import (
 8    QgsGui,
 9    QgsOptionsWidgetFactory,
10    QgsOptionsPageWidget,
11    QgsLayerTreeEmbeddedWidgetProvider,
12    QgsLayerTreeEmbeddedWidgetRegistry,
13)
14
15from qgis.PyQt.QtCore import Qt
16from qgis.PyQt.QtWidgets import (
17    QMessageBox,
18    QAction,
19    QHBoxLayout,
20    QComboBox,
21)
22from qgis.PyQt.QtGui import QIcon

Questa sezione contiene frammenti di codice per facilitare lo sviluppo dei plugin.

16.2.1. Come richiamare un metodo con una scorciatoia da tastiera

Nel plug-in aggiungere a initGui()

self.key_action = QAction("Test Plugin", self.iface.mainWindow())
self.iface.registerMainWindowAction(self.key_action, "Ctrl+I")  # action triggered by Ctrl+I
self.iface.addPluginToMenu("&Test plugins", self.key_action)
self.key_action.triggered.connect(self.key_action_triggered)

A unload() aggiungere

self.iface.unregisterMainWindowAction(self.key_action)

Il metodo che viene richiamato quando si preme CTRL+I

def key_action_triggered(self):
  QMessageBox.information(self.iface.mainWindow(),"Ok", "You pressed Ctrl+I")

È anche possibile consentire agli utenti di personalizzare le scorciatoie da tastiera per le azioni fornite. Questo si ottiene aggiungendo:

1# in the initGui() function
2QgsGui.shortcutsManager().registerAction(self.key_action)
3
4# and in the unload() function
5QgsGui.shortcutsManager().unregisterAction(self.key_action)

16.2.2. Come riutilizzare le icone di QGIS

Poiché sono ben conosciute e trasmettono un messaggio chiaro agli utenti, a volte potresti voler riutilizzare le icone di QGIS nel tuo plugin, invece di disegnarne e impostarne una nuova. Utilizza il metodo getThemeIcon().

Ad esempio, per riutilizzare l’icona fileOpen mActionFileOpen.svg disponibile nel repository del codice QGIS:

1# e.g. somewhere in the initGui
2self.file_open_action = QAction(
3    QgsApplication.getThemeIcon("/mActionFileOpen.svg"),
4    self.tr("Select a File..."),
5    self.iface.mainWindow()
6)
7self.iface.addPluginToMenu("MyPlugin", self.file_open_action)

iconPath() è un altro metodo per richiamare le icone di QGIS. Trovi esempi di richiami alle icone tematiche in QGIS embedded images - Cheatsheet.

16.2.3. Interfaccia per il plugin nella finestra di dialogo delle opzioni

Puoi aggiungere una scheda per le opzioni del plugin a Impostazioni ► Opzioni. Questa soluzione è preferibile all’aggiunta di una voce specifica del menu principale per le opzioni del plugin, in quanto consente di mantenere tutte le impostazioni dell’applicazione QGIS e del plugin in un unico punto, facile da scoprire e da navigare per gli utenti.

Il seguente frammento di codice aggiungerà una nuova scheda vuota per le impostazioni del plugin, pronta per essere popolata con tutte le opzioni e le impostazioni specifiche del plugin. Puoi dividere le classi seguenti in file diversi. In questo esempio, aggiungiamo due classi al file principale mainPlugin.py.

 1class MyPluginOptionsFactory(QgsOptionsWidgetFactory):
 2
 3    def __init__(self):
 4        super().__init__()
 5
 6    def icon(self):
 7        return QIcon('icons/my_plugin_icon.svg')
 8
 9    def createWidget(self, parent):
10        return ConfigOptionsPage(parent)
11
12
13class ConfigOptionsPage(QgsOptionsPageWidget):
14
15    def __init__(self, parent):
16        super().__init__(parent)
17        layout = QHBoxLayout()
18        layout.setContentsMargins(0, 0, 0, 0)
19        self.setLayout(layout)

Infine, aggiungiamo le importazioni e modifichiamo la funzione __init__:

 1from qgis.PyQt.QtWidgets import QHBoxLayout
 2from qgis.gui import QgsOptionsWidgetFactory, QgsOptionsPageWidget
 3
 4
 5class MyPlugin:
 6    """QGIS Plugin Implementation."""
 7
 8    def __init__(self, iface):
 9        """Constructor.
10
11        :param iface: An interface instance that will be passed to this class
12            which provides the hook by which you can manipulate the QGIS
13            application at run time.
14        :type iface: QgsInterface
15        """
16        # Save reference to the QGIS interface
17        self.iface = iface
18
19
20    def initGui(self):
21        self.options_factory = MyPluginOptionsFactory()
22        self.options_factory.setTitle(self.tr('My Plugin'))
23        iface.registerOptionsWidgetFactory(self.options_factory)
24
25    def unload(self):
26        iface.unregisterOptionsWidgetFactory(self.options_factory)

Suggerimento

Aggiungere schede personalizzate alla finestra di dialogo delle proprietà dei layer

Puoi adottare una logica simile per aggiungere l’opzione personalizzata del plugin alla finestra di dialogo delle proprietà del layer, usando le classi QgsMapLayerConfigWidgetFactory e QgsMapLayerConfigWidget.

16.2.4. Incorporare widget personalizzati per i layer nell’albero dei layer

Oltre ai consueti elementi della simbologia dei layer visualizzati accanto o sotto la voce del layer nel pannello Layer, puoi aggiungere i tuoi widget, consentendo l’accesso rapido ad alcune azioni spesso utilizzate con un layer (impostazione di filtri, selezioni, stili, aggiornamento di un layer con un widget pulsante, creazione di un cursore temporale basato sul layer o semplicemente visualizzazione di informazioni extra sul layer in un’etichetta, o …). Questi cosiddetti Widget incorporati nell’albero dei layer sono resi disponibili per i singoli layer attraverso le proprietà Legenda del layer.

Il seguente frammento di codice crea un menu a tendina nella legenda che mostra gli stili di livello disponibili per il layer, consentendo di passare rapidamente tra i diversi stili di livello.

 1class LayerStyleComboBox(QComboBox):
 2    def __init__(self, layer):
 3        QComboBox.__init__(self)
 4        self.layer = layer
 5        for style_name in layer.styleManager().styles():
 6            self.addItem(style_name)
 7
 8        idx = self.findText(layer.styleManager().currentStyle())
 9        if idx != -1:
10          self.setCurrentIndex(idx)
11
12        self.currentIndexChanged.connect(self.on_current_changed)
13
14    def on_current_changed(self, index):
15        self.layer.styleManager().setCurrentStyle(self.itemText(index))
16
17class LayerStyleWidgetProvider(QgsLayerTreeEmbeddedWidgetProvider):
18    def __init__(self):
19        QgsLayerTreeEmbeddedWidgetProvider.__init__(self)
20
21    def id(self):
22        return "style"
23
24    def name(self):
25        return "Layer style chooser"
26
27    def createWidget(self, layer, widgetIndex):
28        return LayerStyleComboBox(layer)
29
30    def supportsLayer(self, layer):
31        return True   # any layer is fine
32
33provider = LayerStyleWidgetProvider()
34QgsGui.layerTreeEmbeddedWidgetRegistry().addProvider(provider)

Quindi, dalla scheda delle proprietà Legenda di un dato layer, trascina la Scelta stile layer da Widget disponibili alla Widget utilizzati` per abilitare il widget nell’albero del layer. I widget incorporati sono SEMPRE visualizzati in cima alle sottovoci dei nodi di livello associati.

Se vuoi utilizzare i widget dall’interno, ad esempio, di un plugin, puoi aggiungerli in questo modo:

1layer = iface.activeLayer()
2counter = int(layer.customProperty("embeddedWidgets/count", 0))
3layer.setCustomProperty("embeddedWidgets/count", counter+1)
4layer.setCustomProperty("embeddedWidgets/{}/id".format(counter), "style")
5view = self.iface.layerTreeView()
6view.layerTreeModel().refreshLayerLegend(view.currentLegendNode())
7view.currentNode().setExpanded(True)