Skip to content

Repository files navigation

QGIS Plugin Builder

Tests Test Coverage Last commit GitHub stars Open issues License: GPL v2 QGIS Plugin Repository Code style: black Imports: isort Linting: flake8 Python QGIS Plugin

QGIS Plugin Builder is a Python-based tool that helps developers quickly scaffold fully structured QGIS plugins. It generates clean boilerplate code, reusable templates, and a best-practice project layout—so you can focus on building geospatial functionality instead of setup. Whether you're new to QGIS plugin development or an experienced GIS developer, this tool streamlines the process of creating plugins with a consistent architecture, reducing development time and improving maintainability.

Key Features

  • Fast plugin scaffolding with minimal setup
  • Pre-built boilerplate following QGIS best practices
  • Template-driven structure for easy customization
  • Built for Python and the QGIS API
  • Ideal for GIS developers, teams, and plugin prototyping
help/source/images/wizard_required_info.png

Walkthrough

1. Install Plugin Builder

Open QGIS and go to Plugins → Manage and Install Plugins. Search for Plugin Builder and install it.

2. Open Plugin Builder

Go to Plugins → Plugin Builder → Plugin Builder. The wizard opens.

3. Fill in the required fields

On the first page enter:

  • Class name — CamelCase Python class name (e.g. MyPlugin)
  • Module name — snake_case file name (e.g. my_plugin)
  • Plugin name — human-readable title shown in QGIS menus
  • Description — one-line summary of what the plugin does
  • Version — starting version number (e.g. 0.1)
  • Minimum QGIS version — minimum compatible version (required; defaults to 4.0)
  • Maximum QGIS version — maximum compatible version (required; defaults to 4.99)
  • Author and Email

On the second page enter a longer About description.

4. Choose a template

On the template page select one of:

  • Tool button with dialog — toolbar button that opens a modal dialog
  • Tool button with dock widget — toolbar button that opens a dock panel
  • Processing provider — adds an algorithm to the Processing toolbox

5. Set publication info (optional)

Enter URLs for your bug tracker, home page, and repository. Add tags to help users find the plugin on the QGIS Plugin Repository.

6. Choose additional components

Check the components you want included:

  • Internationalization — stub i18n setup for adding translated strings
  • Help — a Sphinx documentation project in help/
  • Unit tests — a pytest test suite wired to pytest-qgis; tests use plain assert and are excluded from the packaged plugin via .gitattributes so they never reach QGIS's upload scanner
  • Helper scripts — scripts for publishing to plugins.qgis.org and managing translations
  • Makefile — a GNU Makefile for building and deploying
  • pb_tool — a pb_tool.cfg for the pb_tool command-line deploy tool

7. Generate the plugin

Click Generate, choose an output directory, and click Generate again. Plugin Builder writes all the files into a new directory named after your module.

Resource file compilation is optional. It is best practice to reference resources such as icons and images using os.path rather than Qt's resource system:

icon_path = os.path.join(os.path.dirname(__file__), 'icon.png')
icon = QIcon(icon_path)

This avoids the need to run rcc at build time and keeps your assets visible as ordinary files. If you do use a .qrc file, compile it with:

rcc -g python resources.qrc -o resources.py

8. Deploy and test

Use pb_tool to deploy the generated plugin to your QGIS plugin directory:

cd my_plugin
pip install pb_tool
pb_tool deploy

Then open QGIS, enable the plugin in Plugins → Manage and Install Plugins, and run it to confirm it loads correctly.

9. Running the generated tests

If you included the "Unit tests" component, the plugin ships with a pytest/pytest-qgis suite in test/. These tests import the real qgis Python bindings, so they must run against a Python environment that can see your QGIS install:

  • Create a virtual environment that inherits the system's site-packages so it picks up the qgis bindings, e.g. python3 -m venv --system-site-packages .venv (or uv venv --system-site-packages), then activate it.
  • Set QGIS_PREFIX_PATH so pytest-qgis can locate your QGIS installation: export QGIS_PREFIX_PATH=/usr on most Linux systems, /usr/local on macOS with Homebrew, or the QGIS install directory on Windows.
  • Install the test dependencies: pip install -r requirements-dev.txt (or uv add --dev -r requirements-dev.txt).
  • Run the suite with pytest or make test from the plugin directory.
  • Editors backed by Pyright/Pylance (VS Code) or PyCharm may flag imports like photo_linker.photo_linker_dialog as unresolved, because they don't add the plugin's parent directory to the import path automatically. Fix it by adding "python.analysis.extraPaths": [".."] to .vscode/settings.json (VS Code), or by marking the plugin's parent directory as a Sources Root in PyCharm. Jedi-backed editors (e.g. jedi-language-server, python-lsp-server) resolve this automatically and don't need either fix.

Before publishing

The QGIS Plugins website runs Bandit on every upload as a part of security scanning and treats any B101 (assert_used) finding as critical, blocking the upload outright.

Generated tests use the pytest best-practice assert. The plugin's .gitattributes excludes test/ via export-ignore, so any packaging that goes through git archive (what qgis-plugin-ci and the generated GitHub/GitLab release workflows use) never includes the test suite in the uploaded zip.

This protection only holds if you package through git. If you zip the plugin directory by hand, use a custom build script, or remove/edit .gitattributes, the test/ directory (with its assert statements) can end up in the zip and get your upload rejected. Before uploading anywhere other than through the generated release workflow, confirm test/ isn't included.

10. Start developing

The generated plugin is a working stub. Open the source files in your editor, implement your logic, and use pb_tool deploy -q to redeploy quickly as you iterate.

Documentation

See the help documentation for full details on each wizard field and deployment option.

Contributing

New plugin templates can be added by creating a subdirectory below plugin_templates and registering the template in plugin_templates/__init__.py

Type checking

The pluginbuilder4 package is type-checked with mypy in strict mode (configured in mypy.ini). To run it:

  • Create a virtual environment that inherits the system's site-packages so it picks up the qgis bindings, e.g. python3 -m venv --system-site-packages .venv, then activate it.

  • Install mypy and the type stubs:

    pip install "mypy>=2.4" "qgis-stubs==1.0.0.dev0" types-defusedxml
    

    qgis-stubs 1.x targets QGIS 4 / Qt6 and is currently a pre-release, so it is pinned to an exact version; the 0.x releases target QGIS 3 / Qt5 and won't work. mypy 2.4 or newer is needed to read the PyQt6-stubs it depends on.

  • Run make typecheck from the repository root. The same check runs as a pre-commit hook, which installs its own copies of mypy and the stubs.

qgis-stubs doesn't cover the qgis.PyQt imports, so the stubs/ directory provides small local stubs that re-export the PyQt6 types for qgis.PyQt.QtCore, QtGui, QtWidgets and uic. They are only used by mypy and are not packaged with the plugin.

About

QGIS Plugin Builder – A Python-based scaffolding tool to quickly generate QGIS plugins with boilerplate code, templates, and best-practice structure for geospatial developers.

Topics

Resources

Stars

100 stars

Watchers

9 watching

Forks

Releases

Packages

Used by

Contributors

Languages