Если вы когда-нибудь смотрели на QGIS и думали: «Это отлично, но было бы идеально, если бы он просто делал X», поздравляю — вы только что определили свой следующий проект плагина. Плагины QGIS — это стартовая площадка для геопространственной разработки, и, в отличие от создания целых ГИС-приложений с нуля, создание плагина на удивление доступно. Давайте окунёмся в удивительно цивилизованный мир разработки плагинов QGIS.

Зачем создавать плагин QGIS?

Прежде чем мы углубимся в детали, давайте будем честны с собой: QGIS уже мощный инструмент — он умеет работать с векторными слоями, растровыми данными, пространственным анализом и многим другим. Но иногда вам нужно что-то конкретное. Может быть, вы хотите автоматизировать рабочий процесс, который заставляет вас выполнять одни и те же действия пятьдесят раз в день. Возможно, вам нужно интегрировать проприетарные источники данных. Или, возможно, вы просто хотите произвести впечатление на коллег кастомными функциями, о которых они даже не подозревали.

Плагины позволяют расширить QGIS без изменения его основного кода. Ваш код на Python работает вместе с движком QGIS на C++, и вы получаете доступ ко всему API QGIS. Кроме того, ваш плагин можно упаковать, поделиться им и повторно использовать в разных проектах. Это как бы придаёт QGIS суперсилы, по одной функции Python за раз.

Понимание архитектуры плагинов QGIS

Прежде чем что-либо создавать, давайте разберёмся, что мы на самом деле создаём. Плагин QGIS — это, по сути, пакет Python, который QGIS загружает при запуске (или по требованию). Вот как это работает:

graph TB A["Экземпляр QGIS"] -->|Загружает из| B["~/.qgis2/python/plugins/"] B --> C["Папка вашего плагина"] C --> D["__init__.py"] C --> E["main_module.py"] C --> F["ui_form.ui"] C --> G["resources.qrc"] D -->|Регистрирует| H["Метаданные плагина"] E -->|Содержит| I["Логика и функции плагина"] F -->|Определяет| J["Пользовательский интерфейс"] G -->|Компилирует| K["Ресурсы в Python"] I --> L["Доступ к QgisInterface"] L -->|Взаимодействует с| A

Плагин взаимодействует с QGIS через объект QgisInterface, который предоставляет доступ к меню, слоям, карте и всему, что предлагает QGIS. Ваш пользовательский интерфейс создаётся с помощью Qt Designer (той же среды, которую использует сам QGIS), а ваша бизнес-логика живёт в чистом Python.

Настройка среды разработки

Давайте получим необходимые инструменты. Вам понадобятся три основных компонента:

Plugin Builder — этот плагин QGIS генерирует полный скелет плагина, чтобы вы не начинали с нуля. Это как получить преимущество в гонке, где вы соревнуетесь с собственным разочарованием.

Qt Designer — для создания пользовательского интерфейса вашего плагина. Если у вас установлен QGIS через OSGeo4W, Qt Designer уже включён. На Mac и Linux вам, возможно, придётся установить PyQt отдельно.

Хороший текстовый редактор — VS Code, PyCharm, Sublime Text — выбирайте свой инструмент. Вы будете редактировать файлы Python, и подсветка синтаксиса будет вашим другом.

Установка необходимых инструментов

На Windows: Если вы установили QGIS через OSGeo4W, вам повезло. Qt Designer уже там. Однако для компиляции ресурсов (файлов .qrc, содержащих иконки и другие активы) вам нужно правильно настроить среду. Создайте командный файл с именем compile.bat в директории плагина:

@echo off
call "C:\OSGeo4W64\bin\o4w_env.bat"
call "C:\OSGeo4W64\bin\qt5_env.bat"
call "C:\OSGeo4W64\bin\py3_env.bat"
@echo on
pyrcc5 -o resources.py resources.qrc

(Замените C:\OSGeo4W64\bin\ на путь к вашей установке QGIS, если он отличается.)

На macOS: Сначала установите Homebrew, затем получите PyQt:

brew install pyqt

На Linux (Ubuntu/Debian):

sudo apt-get install python-qt5

Шаг за шагом: создание вашего первого плагина

Теперь самое интересное. Давайте создадим практичный плагин под названием Layer Inspector — он позволит пользователям выбирать слой, просматривать его свойства и экспортировать сводку в текстовый файл. Не революционно, но достаточно полезно, чтобы продемонстрировать рабочий процесс.

Шаг 1: Генерация скелета плагина

Откройте QGIS и перейдите в Plugins → Plugin Builder → Plugin Builder. Вы получите форму. Заполните её следующим образом:

  • Class Name: LayerInspector
  • Plugin Name: Layer Inspector
  • Description: Inspect vector layer properties and export metadata
  • Module Name: layer_inspector
  • Version: 1.0.0
  • Author: Ваше имя
  • Email: Ваш email

Нажмите Next и проследуйте через диалоги. Когда вас спросят о шаблоне, выберите Tool button with dialog. Это даст вам диалоговое окно, которое открывается при запуске вашего плагина. Выберите Vector в качестве местоположения меню, так как этот плагин работает с векторными данными.

После заполнения формы Plugin Builder создаёт папку в директории плагинов QGIS (обычно ~/.qgis2/python/plugins/ на Linux/Mac или C:\Users\YourUsername\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins\ на Windows).

Шаг 2: Структура плагина

Внутри папки layer_inspector вы найдёте:

layer_inspector/
├── __init__.py          # Инициализация плагина и метаданные
├── layer_inspector.py   # Основной класс плагина и логика
├── layer_inspector_dialog.py  # Логика диалогового окна
├── layer_inspector_dialog_base.ui  # Файл UI от Qt Designer
├── resources.qrc        # Файл конфигурации ресурсов
└── resources.py         # Скомпилированные ресурсы (сгенерированы)

Файл init.py — это точка входа вашего плагина. Он сообщает QGIS, как называется ваш плагин, какая у него версия и как его загружать. Вам редко понадобится его изменять.

Файл layer_inspector.py — это место, где происходит волшебство. Здесь вы определяете основной класс плагина, который QGIS будет инстанцировать.

Шаг 3: Разработка UI с помощью Qt Designer

Дважды щёлкните на файле .ui (или щёлкните правой кнопкой мыши и откройте в Qt Designer). Вы увидите пустое диалоговое окно. Давайте создадим что-то полезное:

  1. Перетащите Combo Box на форму (здесь будут храниться имена слоёв).
  2. Добавьте метку выше Combo Box с надписью «Выберите слой».
  3. Добавьте Text Browser ниже Combo Box (для отображения информации о слое).
  4. Добавьте две кнопки внизу: «Проверить» и «Экспорт».

Назовите ваши виджеты соответствующим образом:

  • Combo box: layerComboBox
  • Text browser: infoTextBrowser
  • Кнопка «Проверить»: inspectButton
  • Кнопка «Экспорт»: exportButton

Сохраните файл UI. Qt сам позаботится о макете и стилях.

Шаг 4: Написание логики плагина

Теперь откройте layer_inspector.py в вашем текстовом редакторе. Вы увидите шаблон с несколькими уже заготовленными методами. Вот как может выглядеть рабочая версия:

from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtWidgets import QAction, QFileDialog, QMessageBox
from qgis.core import QgsProject
from qgis.gui import QgisInterface
from .layer_inspector_dialog import LayerInspectorDialog
import os
class LayerInspector:
    def __init__(self, iface: QgisInterface):
        self.iface = iface
        self.plugin_dir = os.path.dirname(__file__)
        self.dlg = None
        self.current_layer = None
    def initGui(self):
        """Создаёт меню плагина и элементы панели инструментов"""
        icon_path = os.path.join(self.plugin_dir, 'icon.png')
        self.action = QAction(QIcon(icon_path), u"Layer Inspector", self.iface.mainWindow())
        self.action.triggered.connect(self.run)
        self.iface.addToolVectorMenu(u"&Инструменты", self.action)
        self.iface.addToolbarIcon(self.action)
    def unload(self):
        """Удаляет значок плагина из меню/панели инструментов"""
        self.iface.removeToolBarIcon(self.action)
        del self.action
    def run(self):
        """Запускает плагин"""
        if self.dlg is None:
            self.dlg = LayerInspectorDialog(self.iface)
            self.dlg.