16.2. Code Snippets
Hint
The code snippets on this page need the following imports if you’re outside the pyqgis console:
1fromqgis.coreimport ( 2 QgsProject, 3 QgsApplication, 4 QgsMapLayer, 5) 6 7fromqgis.guiimport ( 8 QgsGui, 9 QgsOptionsWidgetFactory, 10 QgsOptionsPageWidget, 11 QgsLayerTreeEmbeddedWidgetProvider, 12 QgsLayerTreeEmbeddedWidgetRegistry, 13) 14 15fromqgis.PyQt.QtCoreimport Qt 16fromqgis.PyQt.QtWidgetsimport ( 17 QMessageBox, 18 QAction, 19 QHBoxLayout, 20 QComboBox, 21) 22fromqgis.PyQt.QtGuiimport QIcon
This section features code snippets to facilitate plugin development.
16.2.1. How to call a method by a key shortcut
In the plug-in add to the 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)
To unload()
add
self.iface.unregisterMainWindowAction(self.key_action)
The method that is called when CTRL+I is pressed
defkey_action_triggered(self): QMessageBox.information(self.iface.mainWindow(),"Ok", "You pressed Ctrl+I")
It is also possible to allow users to customize key shortcuts for the provided actions. This is done by adding:
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. How to reuse QGIS icons
Because they are well-known and convey a clear message to the users, you may want
sometimes to reuse QGIS icons in your plugin instead of drawing and setting a new one.
Use the getThemeIcon()
method.
For example, to reuse the fileOpen mActionFileOpen.svg icon available in the QGIS code repository:
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()
is another method to call QGIS
icons. Find examples of calls to theme icons at QGIS embedded images - Cheatsheet.
16.2.3. Interface for plugin in the options dialog
You can add a custom plugin options tab to Settings ► Options. This is preferable over adding a specific main menu entry for your plugin’s options, as it keeps all of the QGIS application settings and plugin settings in a single place which is easy for users to discover and navigate.
The following snippet will just add a new blank tab for the plugin’s settings,
ready for you to populate with all the options and settings specific to your
plugin.
You can split the following classes into different files. In this example, we are
adding two classes into the main mainPlugin.py
file.
1classMyPluginOptionsFactory(QgsOptionsWidgetFactory): 2 3 def__init__(self): 4 super().__init__() 5 6 deficon(self): 7 return QIcon('icons/my_plugin_icon.svg') 8 9 defcreateWidget(self, parent): 10 return ConfigOptionsPage(parent) 11 12 13classConfigOptionsPage(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)
Finally we are adding the imports and modifying the __init__
function:
1fromqgis.PyQt.QtWidgetsimport QHBoxLayout 2fromqgis.guiimport QgsOptionsWidgetFactory, QgsOptionsPageWidget 3 4 5classMyPlugin: 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 definitGui(self): 21 self.options_factory = MyPluginOptionsFactory() 22 self.options_factory.setTitle(self.tr('My Plugin')) 23 iface.registerOptionsWidgetFactory(self.options_factory) 24 25 defunload(self): 26 iface.unregisterOptionsWidgetFactory(self.options_factory)
Tip
Add custom tabs to layer properties dialog
You can apply a similar logic to add the plugin custom option to the layer
properties dialog using the classes
QgsMapLayerConfigWidgetFactory
and QgsMapLayerConfigWidget
.
16.2.4. Embed custom widgets for layers in the layer tree
Beside usual layer symbology elements displayed next or below the layer entry in the Layers panel, you can add your own widgets, allowing for quick access to some actions that are often used with a layer (setup filtering, selection, style, refreshing a layer with a button widget, create a layer based time slider or just show extra layer information in a Label there, or ...). These so-called Layer tree embedded widgets are made available through the layer’s properties Legend tab for individual layers.
The following code snippet creates a drop-down in the legend which shows you the layer-styles available for the layer, allowing to quickly switch between the different layer styles.
1classLayerStyleComboBox(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 defon_current_changed(self, index): 15 self.layer.styleManager().setCurrentStyle(self.itemText(index)) 16 17classLayerStyleWidgetProvider(QgsLayerTreeEmbeddedWidgetProvider): 18 def__init__(self): 19 QgsLayerTreeEmbeddedWidgetProvider.__init__(self) 20 21 defid(self): 22 return "style" 23 24 defname(self): 25 return "Layer style chooser" 26 27 defcreateWidget(self, layer, widgetIndex): 28 return LayerStyleComboBox(layer) 29 30 defsupportsLayer(self, layer): 31 return True # any layer is fine 32 33provider = LayerStyleWidgetProvider() 34QgsGui.layerTreeEmbeddedWidgetRegistry().addProvider(provider)
Then from a given layer’s Legend properties tab, drag the
Layer style chooser
from the Available widgets to
Used widgets to enable the widget in the layer tree.
Embedded widgets are ALWAYS displayed at the top of their associated layer
node subitems.
If you want to use the widgets from within e.g. a plugin, you can add them like this:
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)