16.2. 代码片段

提示

如果您在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

本节介绍代码片段,以方便插件开发。

16.2.1. 如何通过快捷键调用方法

在插件中添加到 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)

unload() 添加

self.iface.unregisterMainWindowAction(self.key_action)

按下CTRL+I时调用的方法

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

还可以允许用户为所提供的操作定制快捷键。这可以通过添加以下内容来实现:

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. 如何重用QGIS图标

因为它们是众所周知的,并且向用户传达了明确的信息,所以您有时可能希望在您的插件中重复使用QGIS图标,而不是绘制和设置新的图标。使用 getThemeIcon() 方法。

例如,要重用 文件打开 mActionFileOpen.svg 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() 是调用QGIS图标的另一种方法。在以下位置找到调用主题图标的示例 QGIS embedded images - Cheatsheet

16.2.3. 选项对话框中插件的界面

您可以将自定义插件选项选项卡添加到 Settings ► Options 。这比为插件选项添加特定的主菜单项更可取,因为它将所有QGIS应用程序设置和插件设置保存在一个地方,用户很容易发现和导航。

下面的代码片断将为插件的设置添加一个新的空白选项卡,以便您填充特定于您的插件的所有选项和设置。您可以将以下类分割到不同的文件中。在此示例中,我们将两个类添加到Main 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)

最后,我们要添加导入并修改 __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)

小技巧

Add custom tabs to layer properties dialog

您可以应用类似的逻辑,使用类将插件自定义选项添加到图层属性对话框中 QgsMapLayerConfigWidgetFactoryQgsMapLayerConfigWidget

16.2.4. 在层树中嵌入层的自定义微件

在中的图层条目旁边或下方显示的常用图层符号系统元素旁边 Layers 面板,你可以添加你自己的小部件,允许快速访问一些经常用于层的操作(设置过滤,选择,样式,用按钮小部件刷新一个层,创建一个基于时间滑块的层,或者只是在那里的标签中显示额外的层信息,或者...)。这些所谓的 Layer tree embedded widgets 通过该图层的属性可用 Legend 选项卡,用于各个层。

下面的代码片段在图例中创建了一个下拉列表,它向您显示了可用于该层的层样式,从而可以在不同的层样式之间快速切换。

 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)

然后从给定层的 Legend 属性选项卡中,拖动 Layer style chooserAvailable widgetsUsed widgets 以在层树中启用该小工具。嵌入的小部件始终显示在其关联的层节点子项目的顶部。

如果你想在插件中使用这些小部件,你可以这样添加它们:

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)