파이썬 프로그래밍 언어로 플러그인을 생성할 수 있습니다. C++로 작성된 전통적인 플러그인에 비해 더 쉽게 플러그인을 작성하고, 이해하고, 유지하고 배포할 수 있는데, 이는 파이썬 언어의 동적 특성 덕분입니다.
QGIS 플러그인 관리자가 C++ 플러그인과 파이썬 플러그인의 목록을 모두 보여줍니다. 다음 경로에서 플러그인들을 찾습니다.
플러그인 작성
QGIS가 파이썬 플러그인을 지원하기 시작하면서, 수많은 플러그인들이 생겨났습니다. 플러그인 저장소 위키 페이지 에서 그중 일부를 찾아볼 수 있습니다. 여러분은 여기에 올려진 플러그인의 소스를 통해 PyQGIS의 프로그래밍에 대해 더 배우거나, 다른 사람이 했던 고생을 되풀이 하고 있는 것은 아닌지 확인할 수 있습니다. 또한 QGIS 팀에서 공식 파이썬 플러그인 저장소 를 운영하고 있습니다. 플러그인을 개발할 준비는 됐지만 뭘 해야 할지 모르겠다고요? 파이썬 플러그인 아이디어 위키 페이지 에서 PyQGIS 커뮤니티가 원하는 플러그인 기능들을 찾아볼 수 있답니다!
플러그인 파일
다음은 우리가 만들 예시 플러그인의 디렉터리 구조입니다.
PYTHON_PLUGINS_PATH/
MyPlugin/
__init__.py --> *required*
mainPlugin.py --> *required*
metadata.txt --> *required*
resources.qrc --> *likely useful*
resources.py --> *compiled version, likely useful*
form.ui --> *likely useful*
form.py --> *compiled version, likely useful*
이 파일들이 의미하는 바는 다음과 같습니다.
__init__.py = 플러그인의 시작점입니다. 이 파일 내부에 classFactory() 메소드는 반드시 있어야 하고, 다른 초기화 코드도 들어갈 수 있습니다.
mainPlugin.py = 플러그인의 주요 작업 코드입니다. 이 파일은 플러그인이 수행할 작업에 대한 모든 정보와 주요 코드를 담고 있습니다.
resources.qrc = Qt 디자이너가 생성한 .xml 문서입니다. 폼이 사용하는 리소스의 상대 경로를 담고 있습니다.
resources.py = 방금 설명한 .qrc 파일을 파이썬으로 번역한 파일입니다.
form.ui = Qt 디자이너가 생성한 GUI입니다.
form.py = 방금 설명한 form.ui 파일을 파이썬으로 번역한 파일입니다.
- metadata.txt = Required for QGIS >= 1.8.0. Containts general info,
version, name and some other metadata used by plugins website and plugin
infrastructure. Since QGIS 2.0 the metadata from __init__.py are not
accepted anymore and the metadata.txt is required.
웹페이지 를 통해 온라인 상에서 자동화된 방법으로, 전형적인 QGIS 파이썬 플러그인의 (골격이 되는) 기본 파일들을 생성할 수 있습니다.
또 인터넷 연결 없이도 QGIS에서 플러그인 템플릿을 생성할 수 있는 Plugin Builder 라는 QGIS 플러그인도 있습니다. QGIS 2.0 버전과 호환되는 소스를 생성하므로 이 플러그인을 사용하는 편이 좋습니다.
경고
공식 파이썬 플러그인 저장소 에 플러그인을 업로드할 계획이라면, 여러분의 플러그인이 플러그인 검증 에 필요한 몇 가지 추가 규칙을 따르는지 확인해야 합니다.
플러그인 구성요소
이제 앞에서 설명한 파일 구조 내부의 각 파일들에 어떤 내용을 추가해야 하는 지를 설명하고 예시를 보여 드리겠습니다.
__init__.py
이 파일은 파이썬의 임포트 체계에서 필요로 합니다. 또한, QGIS는 이 파일 내부에 QGIS가 플러그인을 불러올 때 호출되는 classFactory() 함수가 들어 있을 것을 요구합니다. 이 함수는 QgisInterface 클래스 인스턴스의 참조값을 받아서 mainplugin.py 파일에 있는 플러그인 클래스의 인스턴스를 반환해야만 합니다. 본 예시에서는 TestPlugin 이라는 이름이군요(다음 코드를 보세요). __init__.py 파일에는 다음과 같은 내용이 들어갑니다.
def classFactory(iface):
from mainPlugin import TestPlugin
return TestPlugin(iface)
## any other initialisation needed
mainPlugin.py
이 파일이 실제 작업을 수행하는 파일이며, 다음과 같은 (예시: mainPlugin.py) 내용을 담고 있습니다.
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
# initialize Qt resources from file resources.py
import resources
class TestPlugin:
def __init__(self, iface):
# save reference to the QGIS interface
self.iface = iface
def initGui(self):
# create action that will start plugin configuration
self.action = QAction(QIcon(":/plugins/testplug/icon.png"), "Test plugin", self.iface.mainWindow())
self.action.setObjectName("testAction")
self.action.setWhatsThis("Configuration for test plugin")
self.action.setStatusTip("This is status tip")
QObject.connect(self.action, SIGNAL("triggered()"), self.run)
# add toolbar button and menu item
self.iface.addToolBarIcon(self.action)
self.iface.addPluginToMenu("&Test plugins", self.action)
# connect to signal renderComplete which is emitted when canvas
# rendering is done
QObject.connect(self.iface.mapCanvas(), SIGNAL("renderComplete(QPainter *)"), self.renderTest)
def unload(self):
# remove the plugin menu item and icon
self.iface.removePluginMenu("&Test plugins", self.action)
self.iface.removeToolBarIcon(self.action)
# disconnect form signal of the canvas
QObject.disconnect(self.iface.mapCanvas(), SIGNAL("renderComplete(QPainter *)"), self.renderTest)
def run(self):
# create and show a configuration dialog or something similar
print "TestPlugin: run called!"
def renderTest(self, painter):
# use painter for drawing to map canvas
print "TestPlugin: renderTest called!"
플러그인의 메인 소스 파일(예를 들어 mainPlugin.py) 안에 다음과 같은 플러그인 함수들이 반드시 들어가야 합니다.
__init__ –> QGIS 인터페이스에 접근할 수 있게 해줍니다.
initGui() –> 플러그인이 로드될 때 호출됩니다.
unload() –> 플러그인이 언로드될 때 호출됩니다.
앞의 예시 코드에서 볼 수 있듯이, addPluginToMenu() 함수가 쓰이고 있습니다. 이 함수가 메뉴에 플러그인과 연결되는 메뉴 액션을 추가할 것입니다. 다른 메뉴에 액션을 추가하는 유사 메소드도 있습니다. 다음은 그 메소드들의 목록입니다.
- addPluginToRasterMenu()
- addPluginToVectorMenu()
- addPluginToDatabaseMenu()
- addPluginToWebMenu()
이들은 모두 addPluginToMenu() 메소드와 동일한 문법을 따릅니다.
플러그인 항목을 구성하는 방법의 일관성을 유지하려면, 여러분의 플러그인 메뉴를 이런 미리 정의된 메소드를 이용해 추가하는 편이 좋습니다. 하지만, 여러분이 임으로 만든 메뉴 그룹을 다음 예시에서와 같이 직접 메뉴 바에 추가할 수도 있습니다.
def initGui(self):
self.menu = QMenu(self.iface.mainWindow())
self.menu.setObjectName("testMenu")
self.menu.setTitle("MyMenu")
self.action = QAction(QIcon(":/plugins/testplug/icon.png"), "Test plugin", self.iface.mainWindow())
self.action.setObjectName("testAction")
self.action.setWhatsThis("Configuration for test plugin")
self.action.setStatusTip("This is status tip")
QObject.connect(self.action, SIGNAL("triggered()"), self.run)
self.menu.addAction(self.action)
menuBar = self.iface.mainWindow().menuBar()
menuBar.insertMenu(self.iface.firstRightStandardMenu().menuAction(), self.menu)
def unload(self):
self.menu.deleteLater()
메뉴와 툴바의 사용자 지정 기능을 이용할 수 있도록, QAction 및 QMenu 클래스의 objectName 을 플러그인의 고유한 명칭으로 설정하는 일을 잊지 마십시오.
리소스 파일
앞의 예시 코드에서 initGui() 함수를 보면 리소스 파일(이 경우 파일명 resources.qrc)에 있는 아이콘을 사용했다는 사실을 알 수 있습니다.
<RCC>
<qresource prefix="/plugins/testplug" >
<file>icon.png</file>
</qresource>
</RCC>
It is good to use a prefix that will not collide with other plugins or any
parts of QGIS, otherwise you might get resources you did not want. Now you
just need to generate a Python file that will contain the resources. It’s
done with pyrcc4 command
pyrcc4 -o resources.py resources.qrc
이게 전부입니다... 복잡할 게 없죠. ^_____^
이 모든 과정을 정확히 작업했다면 플러그인 관리자가 아무 문제 없이 여러분의 플러그인을 찾아 불러올 것입니다. 그리고, 툴바 아이콘 또는 적당한 메뉴 항목을 선택하면 콘솔에 메시지가 보일 것입니다.
실제 플러그인 작업 시에는 다른 (작업용) 디렉터리에서 플러그인을 개발하고 UI 및 리소스 파일을 생성할 makefile을 작성한 다음, 그 결과물을 QGIS의 플러그인 폴더에 설치하는 것이 좋습니다.
문서화
플러그인을 위한 문서는 HTML 도움말 파일로 만들 수 있습니다. 이 파일로 다른 QGIS 도움말과 마찬가지로 도움말을 제공하는 방법을 qgis.utils 모듈의 showPluginHelp() 함수가 제공합니다.
The showPluginHelp`() function looks for help files in the same
directory as the calling module. It will look for, in turn,
index-ll_cc.html, index-ll.html, index-en.html,
index-en_us.html and index.html, displaying whichever it finds
first. Here ll_cc is the QGIS locale. This allows multiple translations of
the documentation to be included with the plugin.
또한 showPluginHelp() 함수는 도움말이 보여질 특정 플러그인을 지정하는 packageName 파라미터, 탐색의 대상이 될 파일명의 “index” 부분을 대체할 수 있는 filename 파라미터, 그리고 웹브라우저에서 문서의 어느 부분을 보여줄 것인지 지정하는 HTML 앵커 태그(anchor tag)의 명칭인 section 파라미터를 사용할 수 있습니다.