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

이 장에서는 플러그인 개발을 쉽게 할 수 있도록 도와주는 코드 조각(snippet)에 대해 설명합니다.

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

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. 옵션 대화창에 있는 플러그인 용 인터페이스

Settings ► Options 에 사용자 지정 플러그인 옵션을 추가할 수 있습니다. 사용자 플러그인의 옵션을 위해 특정 주 메뉴 항목을 추가하는 것보다는 이 편이 좋은데, 모든 QGIS 응용 프로그램 설정과 플러그인 설정을 단일 위치에 모아두기 때문에 사용자가 설정을 찾고 탐색하기에 더 편하기 때문입니다.

다음 조각은 플러그인의 설정에 새로운 빈 탭만 추가할 것입니다. 사용자가 이 탭에 사용자 플러그인에 특화된 모든 옵션 및 설정을 채워 넣을 수 있습니다. 다음 클래스들을 서로 다른 파일로 분할할 수 있습니다. 이 예제에서 우리는 주 mainPlugin.py 파일 안에 클래스 2개를 추가할 것입니다.

 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. 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.

 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)

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)