夜雨聆风学习资料网

ARTICLE · 992389

基于QGIS 3.44开发Python插件完整教程

基于QGIS 3.44开发Python插件完整教程

本教程以 QGIS LTR 3.44 为例,涵盖从零搭建插件开发环境、调试配置、自动重载以及常见 API 变更,适合已有 Python 基础的读者。


1. 环境准备

1.1 安装 QGIS 3.44

从 QGIS 官网 下载 QGIS LTR 3.44 版本。安装时确保包含 Python 环境和开发工具(OSGeo4W Shell)。

安装完成后,确认 QGIS 自带的 Python 路径,例如:

C:\Program Files\QGIS 3.44.14\apps\Python312

1.2 使用 OSGeo4W Shell

OSGeo4W Shell 是 QGIS 自带的命令行环境,已配置好 Python 路径。在 Windows 开始菜单中搜索 OSGeo4W Shell 打开即可。

1.3 安装调试依赖 debugpy

在 OSGeo4W Shell 中执行:

pip install debugpy

也可以在 QGIS 的 Python 目录中通过命令提示符安装:

cd "C:\Program Files\QGIS 3.44.14\apps\Python312"python -m pip install debugpy

1.4 安装相关插件

  1. Plugin Builder:
      是一个帮你自动生成插件项目骨架的工具,不用从零手写一堆文件,填几个基本信息就能得到一套可直接运行的模板代码。‌‌
  2. Plugin Reloader:
     允许在不重启 QGIS 的情况下重新加载插件代码,将调试效率提升数倍
  3. QGIS DevTools:
     是 NextGIS 开发的插件,专为 QGIS 插件开发者设计,支持通过 debugpy 从 VS Code 远程调试插件。

以上三个插件在 QGIS 插件管理器中搜索并安装,安装完成后如图:

  • Plugin Builder按钮及弹出截图
  • Plugin Reloader按钮及弹出截图
  • QGIS DevTools按钮及弹出截图

2. 创建第一个插件

2.1 使用 Plugin Builder

  1. 在 QGIS 中安装 Plugin Builder 插件(插件管理器搜索 Plugin Builder)。
  2. 打开 插件 → Plugin Builder → Plugin Builder,填写信息: 
    • Class name
      :CamelCase 类名,如 MyPlugin
    • Module name
      :snake_case 文件名,如 my_plugin
    • Plugin name
      :显示在 QGIS 菜单中的名称
    • Description
      :一句话描述
    • Minimum QGIS version
      :最低兼容版本,如 3.44
  3. 选择模板(如 Tool button with dialog),生成插件骨架。

2.2 插件目录结构

生成的插件位于 QGIS 插件目录:

C:\Users\<用户名>\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins\myfirst

典型结构:

myfirst/├── __init__.py├── myfirst.py            # 主逻辑├── myfirst_dialog.py     # 对话框逻辑├── myfirst_dialog_base.ui # Qt Designer 界面文件├── icon.png├── metadata.txt└── ...

4. 调试方法

4.1 VS Code 断点调试配置(基于 QGIS DevTools)

步骤 1:QGIS DevTools安装完成

  • 安装后,QGIS 右下角会出现一个 bug 图标。

步骤 2:启动调试服务器

  • 点击 bug 图标,选择 Start Debugpy Server
  • 默认监听 127.0.0.1:5678,记下端口号。DevTools 支持自定义端口范围,并可配置为 QGIS 启动时自动开启调试服务器。

步骤 3:配置 VS Code launch.json

在插件项目根目录创建 .vscode/launch.json

{    "version": "0.2.0",    "configurations": [        {            "name": "Attach QGIS",            "type": "debugpy",            "request": "attach",            "connect": {                "host": "localhost",                "port": 5678            },            "pathMappings": [                {                    "localRoot": "{env:APPDATA}/QGIS/QGIS3/profiles/default/python/plugins/myfirst"                }            ],            "justMyCode": true        }    ]}

字段说明:

  • type:使用debugpy(旧版教程中的 python 或 ptvsd 已不推荐)。
  • request:attach 表示附加到现有进程。
  • port必须与 DevTools 中的端口一致
  • pathMappings:将本地 VS Code 路径映射到 QGIS 实际插件路径。remoteRoot 需指向插件在 QGIS 中的安装位置。
  • justMyCode:设为 true 可跳过 QGIS 核心代码,只在你自己的插件代码中暂停。

步骤 4:开始调试

  1. VS Code 中按 Ctrl+Shift+D 打开 Run and Debug 面板。
  2. 选择 Attach QGIS,点击绿色启动按钮(或 F5)。
  3. 断点变为实心红点表示连接成功。
  4. 在 QGIS 中运行插件,代码会在断点处暂停,可查看变量、单步执行。

4.2 日志输出:QgsMessageLog

print() 在 QGIS 中通常不可见,推荐使用 QgsMessageLog,消息显示在 视图 → 面板 → 日志消息 中。

正确用法:

from qgis.core import QgsMessageLogQgisQgsMessageLog.logMessage("普通信息""myfirst", level=Qgis.Info)QgsMessageLog.logMessage("警告信息""myfirst", level=Qgis.Warning)QgsMessageLog.logMessage("严重错误""myfirst", level=Qgis.Critical)

注意:日志级别定义在 Qgis 类中,而非 QgsMessageLog。常见错误:QgsMessageLog.WARNING 会报 AttributeError

5. 完整示例:获取图层并填充下拉框

5.1 UI编辑

打开Qt Designer with QGIS 3.44.14 custom widgets如图: 点击"打开"按钮,选中插件目录下的"myfirst_dialog_base.ui"文件,打开如图:

5.2 数据填充

以下代码演示从 QgsProject 获取矢量/栅格图层,并填充对话框中的下拉框:

from qgis.core import QgsProject, QgsMapLayer, QgsMessageLog, Qgisdef populate_combos(dlg):    layers = QgsProject.instance().mapLayers()    vectors = []    rasters = []    for layer_id, layer in layers.items():        if layer.type() == QgsMapLayer.VectorLayer:            vectors.append(layer.name())        elif layer.type() == QgsMapLayer.RasterLayer:            rasters.append(layer.name())        else:            QgsMessageLog.logMessage(                f"id: {layer_id} 的图层 [{layer.name()}] 不是栅格或矢量",                "myfirst",                level=Qgis.Warning            )    if hasattr(dlg, 'rastersCombo'):        dlg.rastersCombo.clear()        dlg.rastersCombo.insertItems(0, rasters)    if hasattr(dlg, 'vectorsCombo'):        dlg.vectorsCombo.clear()        dlg.vectorsCombo.insertItems(0, vectors)

在 run() 方法中调用:

def run(self):    if self.first_start:        self.first_start = False        self.dlg = myfirstDialog()    populate_combos(self.dlg)    self.dlg.show()    result = self.dlg.exec_()    if result:        selected = self.dlg.rastersCombo.currentText()        QgsMessageLog.logMessage(f"用户选择: {selected}""myfirst", Qgis.Info)

5.2 最终效果

6. 常见问题与解决

问题
原因
解决方法
ImportError: cannot import name 'QgsMapLayerRegistry'
QGIS 3 已移除该类
改用 QgsProject.instance()
AttributeError: type object 'QgsMessageLog' has no attribute 'WARNING'
日志级别定义在 Qgis 类
使用 Qgis.Warning,并导入 Qgis
断点空心(未绑定)
pathMappings
 配置错误
检查 remoteRoot 是否与 QGIS 插件实际路径一致
连接被拒绝
调试服务器未启动或端口不一致
确认 QGIS DevTools 已启动,端口与 launch.json 一致
修改代码不生效
QGIS 加载的是已安装的插件副本
使用 Plugin Reloader 或重启 QGIS
print()
 无输出
QGIS 默认不显示控制台
使用 QgsMessageLog 或从命令行启动 QGIS

7. 实用技巧与建议

  • 始终使用 QgsMessageLog
     代替 print(),便于在 QGIS 内查看日志。
  • 利用 if self.first_start:
     确保对话框只创建一次,避免重复初始化。
  • 使用 f-string
     格式化日志信息,更简洁。
  • 在插件中合理使用 try...except
    ,捕获异常并记录完整 traceback。
  • 推荐工作流
    :使用 Plugin Reloader + Ctrl+F5 进行快速重载,配合 QGIS DevTools + VS Code 进行断点调试,形成高效的开发闭环。

相关学习资料

返回首页浏览学习资料