안녕하세요? 이번 글은 "첫 번째 QGIS 플러그인 만들기" 시리즈의 시작으로, "플러그인 생성"에 대해 다뤄보겠습니다. 이 시리즈는 Spatial Thoughts의 우자발 간디(Ujaval Gandhi) 님의 "Building Your First QGIS Plugin (Full Workshop)" 내용을 재정리한 것입니다. 유익한 콘텐츠를 공유해 주신 우자발 간디 님께 감사드리며, 본격적으로 시작해 보겠습니다.
1. QGIS 플러그인이란?
QGIS 플러그인 개발은 개발자들에게 QGIS의 핵심 기능을 추가하거나 확장할 수 있는 강력한 도구를 제공합니다. 플러그인은 사용자 정의 코드를 패키지화하고 배포할 수 있는 메커니즘을 제공하며, 설치, 업데이트, 제거 과정을 간단하고 효율적으로 관리할 수 있도록 설계되어 있습니다.
- QGIS Plugins 웹 포털: https://plugins.qgis.org/
- Developing Python Plugins: https://docs.qgis.org/3.34/en/docs/pyqgis_developer_cookbook/plugins/index.html
QGIS 플러그인은 Python으로 작성되며, QGIS와의 상호작용을 위해 PyQGIS API로 알려진 특별한 함수 집합을 사용합니다. 개발된 플러그인은 QGIS의 "플러그인 > 플러그인 관리 및 설치 > Plugin Manager"를 통해 쉽게 확인하고 관리할 수 있습니다.
2. 플러그인 생성 워크플로
QGIS 플러그인은 Plugin Manager를 통해 관리되며, QGIS 시작 시 자동으로 로드됩니다. 플러그인은 표준 구조를 따르는 파일 집합으로 구성되며, 세 가지 핵심 파일은 다음과 같습니다.
- metadata.txt: 플러그인의 이름, 버전, 저자, 설명 등 메타데이터 정보를 포함합니다.
- __init__.py: 플러그인의 초기화를 담당하며, QGIS에서 플러그인을 인식하도록 합니다.
- main.py: 플러그인의 주요 동작과 기능을 정의하는 파일로, 플러그인의 핵심 로직이 구현됩니다.
주요 플러그인 클래스를 포함하는 파일의 이름은 반드시 main.py일 필요는 없습니다. 개발자는 원하는 이름으로 파일을 지정할 수 있으며, 이를 __init__.py에서 적절히 참조하면 QGIS에서 플러그인을 정상적으로 인식하고 로드할 수 있습니다.
3. 첫 번째 QGIS 플러그인 만들기
이제 실습을 통해 확인해 보겠습니다. 아래는 "Basemap Loader"라는 이름의 플러그인을 구성하는 파일 집합입니다. 이 플러그인을 통해 QGIS 플러그인의 구조와 동작 방식을 이해할 수 있습니다.
플러그인 생성을 위해 필요한 파일들을 포함한 폴더를 생성합니다(예: basemap_loader 폴더). 생성한 폴더를 QGIS가 인식하도록 하기 위해 다음 경로에 복사합니다: 설정 > 사용자 프로파일 > 활성 프로파일 폴더 열기 > python > plugins. 이 과정을 완료하면 플러그인이 QGIS에서 로드될 준비가 됩니다.
QGIS를 재시작한 후, "플러그인 > 플러그인 관리 및 설치 > 설치했습니다" 탭으로 이동합니다. 여기에서 Basemap Loader 플러그인을 찾아 활성화하면, QGIS 툴바에 Basemap Loader 아이콘이 표시됩니다.
이제 플러그인을 구성하는 각 파일을 하나씩 확인해 보겠습니다.
metadata.txt
플러그인의 메타데이터 정보는 플러그인의 이름, 버전, 설명, 작성자 정보 등을 정의하며, metadata.txt 파일에 저장됩니다. 이 정보는 QGIS의 Plugin Manager에서 플러그인을 식별하고 관리하는 데 사용됩니다.
[general]
name=Basemap Loader
description=This plugin adds a basemap layer to QGIS.
version=1.0
qgisMinimumVersion=3.0
author=Ujaval Gandhi
email=ujaval@spatialthoughts.com
icon=logo.png
main.py
main.py는 플러그인의 주요 로직을 포함하는 파일입니다. __init__() 메서드는 플러그인이 QGIS Interface(iface)에 접근할 수 있도록 하며, initGui() 메서드는 플러그인이 로드될 때 호출됩니다. 또한, unload() 메서드는 플러그인이 언로드될 때 호출됩니다. 여기서 run() 메서드는 사용자가 클릭했을 때 메시지가 표시되도록 설정되어 있습니다.
import os
import inspect
from PyQt5.QtWidgets import QAction
from PyQt5.QtGui import QIcon
cmd_folder = os.path.split(inspect.getfile(inspect.currentframe()))[0]
class BasemapLoaderPlugin:
def __init__(self, iface):
self.iface = iface
def initGui(self):
icon = os.path.join(os.path.join(cmd_folder, 'logo.png'))
self.action = QAction(QIcon(icon), 'Load Basemap', self.iface.mainWindow())
self.iface.addToolBarIcon(self.action)
self.action.triggered.connect(self.run)
def unload(self):
self.iface.removeToolBarIcon(self.action)
del self.action
def run(self):
self.iface.messageBar().pushMessage('Hello from Plugin')
__init__.py
__init__.py는 플러그인의 시작 지점에 해당합니다. 이 파일에서는 main.py에서 생성된 플러그인 클래스를 가져와 해당 클래스를 인스턴스로 생성합니다.
from .main import BasemapLoaderPlugin
def classFactory(iface):
return BasemapLoaderPlugin(iface)
현재 Basemap Loader 플러그인은 버튼을 클릭했을 때 "Hello from Plugin"이라는 메시지를 표시하는 기능만 제공합니다. 앞으로 진행될 시리즈를 통해 단계별로 플러그인의 기능을 확장해 보겠습니다.
- 첫 번째 QGIS 플러그인 만들기 - (1) 플러그인 생성
- 첫 번째 QGIS 플러그인 만들기 - (2) 핵심 기능 추가
- 첫 번째 QGIS 플러그인 만들기 - (3) 사용자 인터페이스 추가
- 첫 번째 QGIS 플러그인 만들기 - (4) 플러그인 패키징 및 공유