PyQGisCookbook--构建Python插件(十八/1)


构建Python插件

为了创建插件,请遵循以下步骤:

  1. 想法:对您要使用新的QGIS插件做什么有想法。你为什么要这么做?您想解决什么问题?是否已经有另一个插件可以解决该问题?

  2. 创建文件:一些是必不可少的(请参阅插件文件

  3. 编写代码:将代码写入适当的文件中

  4. 测试重新加载您的插件以检查是否一切正常

  5. 发布:在QGIS或你的个人仓库中发布您的插件。

编写插件

自从QGIS中引入Python插件以来,出现了许多插件。QGIS团队维护着一个官方的Python插件仓库。您可以通过他们的资料来学习更多有关PyQGIS进行编程的信息,或者了解您是否正在重复开发工作。

插件文件

这是我们的示例插件的目录结构

PYTHON_PLUGINS_PATH/
  MyPlugin/
    __init__.py    --> *required*
    mainPlugin.py  --> *core code*
    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 Designer创建的.xml文档。包含表单资源的相对路径。

  • resources.py =上述.qrc文件到Python的编译文件。

  • form.ui =由Qt Designer创建的GUI。

  • form.py =将上述form.ui编译为Python的文件。

  • metadata.txt =包含插件网站和插件基础结构使用的常规信息,版本,名称和其他一些元数据。

 是一种典型的创建QGIS Python插件的基本文件(框架)的方法。

有一个名为Plugin Builder 3的QGIS插件 ,可为QGIS创建一个插件模板。建议使用此选项,因为它会生成Python 3.x兼容的代码。

警告

注意:如果您打算将插件上传到Python官方插件仓库 ,则必须检查插件是否遵循插件验证所需的一些附加规则

插件内容

在这里,您可以找到在上述文件结构中有关的每个文件中添加内容的信息和示例。

插件元数据

首先,插件管理器需要检索一些有关插件的基本信息,例如其名称,描述等。文件metadata.txt是放置此信息的正确位置。

注意

注意:所有元数据都必须采用UTF-8编码。

元数据名称

需要

备注

name

名称:包含插件名称的短字符串

qgisMinimumVersion

最低QGIS版本号

qgisMaximumVersion

最大QGIS版本号

description

说明:描述插件的简短文本,不允许使用HTML

about

关于:较长的文本,详细描述了插件,不允许使用HTML

version

版本:短字符串,带有点符号的版本号

author

作者名

email

邮箱:作者的电子邮件,仅显示在网站上以登录用户,但在安装插件后在插件管理器中可见

changelog

修改日志:字符串,可以是多行,不允许HTML

experimental

实验性:布尔标志,真或假 - 真,如果这个版本是实验性的

deprecated

适用性:布尔值True或False不仅适用于上载版本,还适用于整个插件

tags

标签:以逗号分隔的列表,各个标签内允许有空格

homepage

主页:指向插件首页的有效URL

repository

仓库:源代码仓库的有效URL

tracker

跟踪:标签和错误报告的有效URL

icon

图标:网络图片(PNG,JPEG)或相对路径(相对于插件压缩包的基本文件夹)的文件名

category

种类:Raster, Vector, Database , Web

plugin_dependencies

插件依赖:类似于PIP的逗号分隔的其他插件列表

server

服务器:布尔标志True或False,确定插件是否具有服务器接口

hasProcessingProvider()

包含处理算法:布尔标志True或False,确定插件是否提供处理算法

 

默认情况下,插件位于“ 插件”菜单中(我们将在下一节中看到如何为插件添加菜单项),但是它们也可以置于RasterVector, DatabaseWeb菜单中。

存在相应的“category”元数据条目以指定该条目,因此可以对插件进行相应的分类。此元数据条目用作用户的提示,并告诉他们可以在哪里(在哪个菜单中)找到插件。“类别”的允许值为:Vector, Raster, Database , Web。例如,如果您的插件可从“ 栅格”菜单使用,则将其添加到metadata.txt

category=Raster

注意

注意:如果qgisMaximumVersion为空,则在上传到Python官方插件仓库时,它将自动设置为主版本加.99。

此meta.txt的示例

; the next section is mandatory

[general]
name=HelloWorld
email=me@example.com
author=Just Me
qgisMinimumVersion=3.0
description=This is an example plugin for greeting the world.
    Multiline is allowed:
    lines starting with spaces belong to the same
    field, in this case to the "description" field.
    HTML formatting is not allowed.
about=This paragraph can contain a detailed description
    of the plugin. Multiline is allowed, HTML is not.
version=version 1.2
tracker=http://bugs.itopen.it
repository=http://www.itopen.it/repo
; end of mandatory metadata

; start of optional metadata
category=Raster
changelog=The changelog lists the plugin versions
    and their changes as in the example below:
    1.0 - First stable release
    0.9 - All features implemented
    0.8 - First testing release

; Tags are in comma separated value format, spaces are allowed within the
; tag name.
; Tags should be in English language. Please also check for existing tags and
; synonyms before creating a new one.
tags=wkt,raster,hello world

; these metadata can be empty, they will eventually become mandatory.
homepage=https://www.itopen.it
icon=icon.png

; experimental flag (applies to the single version)
experimental=True

; deprecated flag (applies to the whole plugin and not only to the uploaded version)
deprecated=False

; if empty, it will be automatically set to major version + .99
qgisMaximumVersion=3.99

; Since QGIS 3.8, a comma separated list of plugins to be installed
; (or upgraded) can be specified.
; The example below will try to install (or upgrade) "MyOtherPlugin" version 1.12
; and any version of "YetAnotherPlugin"
plugin_dependencies=MyOtherPlugin==1.12,YetAnotherPlugin

__init__. py

Python的导入系统需要此文件。同样,QGIS要求此文件包含一个classFactory()函数,当插件加载到QGIS中时会调用该函数。它收到对QgisInterface的实例的引用, 并且必须返回你在mainplugin.py文件定义的插件类对象—在我们的例子中,它被称为TestPlugin(请参见下文)。这__init__.py应该是什么样子

def classFactory(iface):
  from .mainPlugin import TestPlugin
  return TestPlugin(iface)

# any other initialisation needed

mainPlugin.py 

这就是神奇发生的地方,这就是神奇的样子:(例如mainPlugin.py

from qgis.PyQt.QtGui import *
from qgis.PyQt.QtWidgets import *

# initialize Qt resources from file resources.py
from . 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")
    self.action.triggered.connect(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
    self.iface.mapCanvas().renderComplete.connect(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
    self.iface.mapCanvas().renderComplete.disconnect(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将相应的菜单项添加到“ Plugins” 菜单中。用其它函数可以菜单项添加到其它菜单中,这些函数列表是:

它们都具有与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")
    self.action.triggered.connect(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()

不要忘记为您的插件QActionQMenu 设置objectName命名,以便可以自定义。

资源文件

您可以看到,initGui()我们使用了资源文件中的一个图标(在本例中称为resources.qrc

<RCC>
  <qresource prefix="/plugins/testplug" >
     <file>icon.png</file>
  </qresource>
</RCC>

最好使用不会与其他插件或QGIS的任何部分冲突的前缀,否则您可能会获得不需要的资源。现在,您只需要生成一个包含资源的Python文件。这是通过pyrcc5命令完成的:

pyrcc5 -o resources.py resources.qrc

注意

注意:在Windows环境中,尝试从命令提示符或Powershell 运行pyrcc5可能会导致错误“ Windows无法访问指定的设备,路径或文件[…]”。最简单的解决方案可能是使用OSGeo4W Shell,但是如果您愿意修改PATH环境变量或明确指定可执行文件的路径,则应该可以在处找到$(QGis安装路径)\bin\pyrcc5.exe

仅此而已...没什么复杂的

如果您已正确完成所有操作,则应该能够在插件管理器中找到并加载插件,并且在选择工具栏图标或适当的菜单项时在控制台中看到一条消息。

使用真正的插件时,明智的做法是将插件写入另一个(工作)目录中,并创建一个makefile或其它生成文件,该文件将生成UI +资源文件并将插件安装到QGIS安装中。

文档

该插件的文档可以使用HTML格式编写。 qgis.utils模块提供了一个函数showPluginHelp(),该函数将与其他QGIS帮助相同的方式打开帮助文件浏览器。

showPluginHelp()函数在与被调用模块相同的目录中查找帮助文件。它依次搜索 index-ll_cc.htmlindex-ll.htmlindex-en.html, index-en_us.htmlindex.html这些文件,一旦找到就显示。ll_cc是QGIS语言环境。这允许插件附带多种文档翻译。

showPluginHelp()函数还可以使用参数packageName(用于标识要为其显示帮助的特定插件),filename(可以替换正在搜索的文件名中的“ index”)和section(其为html锚标记的名称)。

翻译

通过几步,您可以设置插件本地化的环境,以便根据您计算机的语言环境设置,将以不同的语言加载插件。

软件要求

创建和管理所有翻译文件的最简单方法是安装 Qt Linguist。在基于Debian的GNU / Linux环境中,您可以输入以下内容进行安装:

sudo apt install qttools5-dev-tools

文件和目录

创建插件时,您会在插件主目录中找到i18n文件夹。

所有翻译文件都必须在此目录中。

.pro文件

首先,您应该创建一个.pro文件,该文件是可以由Qt Linguist管理的项目文件。

在此.pro文件中,您必须指定要翻译的所有文件和表格。该文件用于设置本地化文件和变量。一个可能的项目文件,与我们的示例插件的结构匹配 :

FORMS = ../form.ui
SOURCES = ../your_plugin.py
TRANSLATIONS = your_plugin_it.ts

您的插件可能遵循更复杂的结构,并且可能分布在多个文件中。如果是这种情况,请记住,pylupdate5读取.pro内容并更新可翻译字符串时不会扩展通配符(注:在.pro中不能用通配符描述类似的文件,比如 *.py),因此您需要将每个文件明确地放置在.pro文件中。您的pro文件可能看起来像这样:

FORMS = ../ui/about.ui ../ui/feedback.ui \
        ../ui/main_dialog.ui
SOURCES = ../your_plugin.py ../computation.py \
          ../utils.py

此外,该your_plugin.py文件是调用 QGIS工具栏中插件的所有菜单和子菜单的文件,并且您希望将其全部翻译。

最后,使用TRANSLATIONS变量,您可以指定所需的翻译语言。

警告

注意:确保ts文件命名格式为:your_plugin_language.ts 否则语言加载会失败! language使用2个字母的简洁表示(比如:意大利 it,德国 de, 中国 cn,等...)

.ts文件

创建完成后.pro就可以为您的插件语言生成.ts文件了。

打开一个终端,转到your_plugin/i18n目录并键入:

pylupdate5 your_plugin.pro

您应该会看到your_plugin_language.ts文件。

.ts使用Qt Linguist打开文件并开始翻译。

.qm文件

完成翻译插件后(如果某些字符串未完成,则将使用这些字符串的源语言),您必须创建.qm 文件(QGIS将使用已编译.ts的文件)。

只需在your_plugin/i18n目录中打开终端cd 并输入:

lrelease your_plugin.ts

现在,在i18n目录中,您将看到your_plugin.qm文件。

使用Makefile进行翻译

另外,如果您是使用Plugin Builder创建的插件,则可以使用makefile从python代码和Qt对话框中提取消息。在Makefile的开头,有一个LOCALES变量:

LOCALES = en

在此变量中添加语言的缩写,例如匈牙利语言:

LOCALES = en hu

现在,您可以通过以下方式从源中生成或更新hu.ts文件(en.ts也是如此):

make transup

此后,您已经更新设置的LOCALES变量中所有语言的.ts文件。使用Qt语言学家翻译程序消息。完成翻译后,.qm可以通过反编译来创建文件:

make transcompile

您必须使用插件分发.ts文件。

加载插件

为了启用插件的翻译,请打开QGIS更改语言(“设置”‣“选项”‣“常规”),然后重新启动QGIS。

您应该以正确的语言查看插件。

警告

注意:如果您在插件中进行了更改(新的UI,新的菜单等),则必须 再次生成.ts.qm文件的更新版本,并运行以上命令。

技巧和窍门

插件重新加载

在开发插件期间,您经常需要将你的插件重新加载到QGIS中进行测试。您可以使用插件管理器的Plugin Reloader插件。

访问插件

您可以使用python从QGIS中获得所有已安装插件的类,这对于调试非常方便。

my_plugin = qgis.utils.plugins['My Plugin']

日志消息

插件在“ 日志消息面板(Log Messages Panel)”中具有自己的选项卡。

分享你的插件

QGIS在插件仓库中托管了数百个插件。考虑分享您的插件,人们将能够从您的代码中学习或可能将扩展QGIS。可以使用插件管理器从QGIS中找到并安装所有托管的插件。

分享的插件URL:plugins.qgis.org

下一个   前一个

©版权所有2002-现在,QGIS项目 最近更新于2020年4月3日09:14。

使用Sphinx使用Read the Docs提供的主题构建。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值