파이썬 프로그래밍 언어로 플러그인을 생성할 수 있습니다. 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. Contains 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 버전과 호환되는 소스를 생성하므로 이 플러그인을 사용하는 편이 좋습니다.
경고
공식 파이썬 플러그인 저장소 에 플러그인을 업로드할 계획이라면, 여러분의 플러그인이 플러그인 검증 에 필요한 몇 가지 추가 규칙을 따르는지 확인해야 합니다.
이제 앞에서 설명한 파일 구조 내부의 각 파일들에 어떤 내용을 추가해야 하는 지를 설명하고 예시를 보여 드리겠습니다.
이 파일은 파이썬의 임포트 체계에서 필요로 합니다. 또한, 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) 내용을 담고 있습니다.
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
주석
In Windows environments, attempting to run the pyrcc4 from
Command Prompt or Powershell will probably result in the error “Windows
cannot access the specified device, path, or file [...]”. The easiest
solution is probably to use the OSGeo4W Shell but if you are comfortable
modifying the PATH environment variable or specifiying the path to the
executable explicitly you should be able to find it at
<Your QGIS Install Directory>\bin\pyrcc4.exe.
이게 전부입니다... 복잡할 게 없죠. ^_____^
이 모든 과정을 정확히 작업했다면 플러그인 관리자가 아무 문제 없이 여러분의 플러그인을 찾아 불러올 것입니다. 그리고, 툴바 아이콘 또는 적당한 메뉴 항목을 선택하면 콘솔에 메시지가 보일 것입니다.
실제 플러그인 작업 시에는 다른 (작업용) 디렉터리에서 플러그인을 개발하고 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 파라미터를 사용할 수 있습니다.
With a few steps you can set up the environment for the plugin localization so
that depending on the locale settings of your computer the plugin will be loaded
in different languages.
The easiest way to create and manage all the translation files is to install
Qt Linguist.
In a Debian-based GNU/Linux environment you can install it typing:
sudo apt-get install qt4-dev-tools
When you create the plugin you will find the i18n folder within the main
plugin directory.
All the translation files have to be within this directory.
First you should create a .pro file, that is a project file that can be
managed by Qt Linguist.
In this .pro file you have to specify all the files and forms you want to
translate. This file is used to set up the localization files and variables.
A possible project file, matching the structure of our
example plugin:
FORMS = ../form.ui
SOURCES = ../your_plugin.py
TRANSLATIONS = your_plugin_it.ts
Your plugin might follow a more complex structure, and it might be distributed
across several files. If this is the case, keep in mind that pylupdate4,
the program we use to read the .pro file and update the translatable string,
does not expand wild card characters, so you need to place every file explicitly
in the .pro file.
Your project file might then look like something like this:
FORMS = ../ui/about.ui ../ui/feedback.ui \
../ui/main_dialog.ui
SOURCES = ../your_plugin.py ../computation.py \
../utils.py
Furthermore, the your_plugin.py file is the file that calls all the menu
and sub-menus of your plugin in the QGIS toolbar and you want to translate them
all.
Finally with the TRANSLATIONS variable you can specify the translation
languages you want.
경고
Be sure to name the ts file like your_plugin_ + language + .ts
otherwise the language loading will fail! Use 2 letters shortcut for the
language (it for Italian, de for German, etc...)
Once you have created the .pro you are ready to generate the .ts file(s)
of the language(s) of your plugin.
Open a terminal, go to your_plugin/i18n directory and type:
pylupdate4 your_plugin.pro
you should see the your_plugin_language.ts file(s).
Open the .ts file with Qt Linguist and start to translate.
When you finish to translate your plugin (if some strings are not completed the
source language for those strings will be used) you have to create the .qm
file (the compiled .ts file that will be used by QGIS).
Just open a terminal cd in your_plugin/i18n directory and type:
now, in the i18n directory you will see the your_plugin.qm file(s).
Alternatively you can use the makefile to extract messages from python code and
Qt dialogs, if you created your plugin with Plugin Builder.
At the beginning of the Makefile there is a LOCALES variable:
Add the abbreviation of the language to this variable, for example for
Hungarian language:
Now you can generate or update the hu.ts file (and the en.ts too)
from the sources by:
After this, you have updated .ts file for all languages set in the LOCALES
variable.
Use Qt4 Linguist to translate the program messages.
Finishing the translation the .qm files can be created by the transcompile:
You have to distribute .ts files with your plugin.
In order to see the translation of your plugin just open QGIS, change the
language () and restart QGIS.
You should see your plugin in the correct language.
경고
If you change something in your plugin (new UIs, new menu, etc..) you have to
generate again the update version of both .ts and .qm file, so run
again the command of above.