17.3. 一个简单的插件示例#
本节的目标是自定义 TestPlugin
,以便对栅格和矢量中加载的层进行分类,并分别用层名称填充两个组合框。
17.3.1. 向TestPlugin添加基本逻辑#
如前所述,要定制TestPlugin,我们必须修改文件中的一些代码部分: test_plugin_dialog_base.ui 对于GUI布局,"test_plugin_dialog.py"对于GUI逻辑, 以及测试"plugin.py"以获取插件逻辑。
17.3.2. 使用Qt设计器修改布局#
默认的插件GUI布局只有两个按钮, Ok
和 取消
。
在这里,我们将添加两个组合框,这些组合框将由中插件的逻辑填充"test_plugin.py"。
编辑"test_plugin_dialog_base.ui"GUI布局,用Qt设计器打开, 将显示以下屏幕截图的界面,如 图 17.13 。

图 17.13 Qt设计器#
这是"test_plugin_dialog_base.ui"XML文件。 使用Qt设计器,我们可以重新组织布局,添加新的图形元素,还可以连接与界面相关的事件和触发器。 在前面的屏幕截图中,四个红色框标记设计器部分:
这个“布局区域”是呈现插件GUI的区域。
这个“小部件框”部分包含预定义GUI组件的列表。在这里,我们将查找要添加到GUI布局中的组合框。
这个“对象检查器”第节给出了组成图形用户界面布局的图形组件的层次结构。
这个“属性编辑器”部分列出了可以自定义的图形组件的所有属性。
17.3.3. 添加两个下拉菜单#
接下来的步骤是创建布局,如 图 17.14 所示。

图 17.14 创建布局#
要创建此布局,请将两个组合框拖动到中央GUI布局。 这个组合框选项可以通过在“小部件框”章节。 同样,我们将在每个组合框的顶部添加两个标签。 要编辑标签,只需双击标签即可进入标签编辑模式。 此操作相当于更改"Text"中的属性“属性编辑器”部分。 创建布局后,我们可以将每个组合框与一个对象名相关联,该对象名将用于区分每个组合框的功能。 为此,我们将更改“对象名”中的属性“属性编辑器”章节。 例如,我们可以将“栅格”组合框的名称设置为“拉斯特斯科博”。 同样,我们将向量组合框重命名为“矢量管”。 用作“对象名”将是引用图形元素的Python变量的名称。 当我们想要获取或设置图形元素的某些属性时,它将在Python代码中使用。
17.3.4. 修改GUI逻辑#
我们的插件不需要修改对话框代码,"test_plugin_dialog.py", 因为所有的GUI更新都将由"test_plugin.py‘直接填充“拉斯特组合拳”和“矢量管”元素。 这是一个设计决策; 在其他情况下,使用添加到对话框中的专用函数在对话框代码中隐藏组合名称的逻辑可能更好或更干净。
17.3.5. 修改插件逻辑#
必须添加我们的核心插件逻辑。 这可以通过修改"test_plugin.py"code。 在许多情况下例如在简单插件或批处理指令中, 只有必须在插件代码中修改"run(self)"函数。
这个“运行()”函数是每次在QGIS工具箱中单击插件按钮或从插件菜单运行插件时调用的函数。 在“运行()”功能,我们必须:
收集所有加载的层
在栅格和矢量图层中分类
在插件GUI中填充组合框
显示加载了新值的GUI
要获取所有列出的层,我们必须询问所有显示层的容器,即“QgsMapLayerRegistry”上课。 为此,我们将使用以下代码:
from qgis.core import QgsMapLayerRegistry layersDict = QgsMapLayerRegistry.instance().mapLayers()
第一行导入类,“QgsMapLayerRegistry”,来自Python模块“qgis.core”。 您可以在代码中的任何位置导入类,但最好在文件开头导入它们。 忘记导入类将在运行时导致错误。 错误如下:
回溯(最近一次呼叫时间):
File "<input>", line 1, in <module>
名称错误:未定义名称“QgsMapLayerRegistry” 在第二行,结果变量,分层听写,是一个Python字典; 它包含一组键值对,其中键是QGIS中层的唯一ID,值是"QgsMapLayer"类, 该类可以是矢量层或栅格层。
变量,分层听写,有后缀,Dict,只是出于说教的原因,但可以简单地命名为“层” 。
17.3.6. 分层#
下一步是创建矢量和栅格图层名列表。 这可以通过循环来实现分层听写按以下方式:
[from qgis.core import QgsMapLayer vectors = [] rasters = [] for (id, map) in layersDict.items():
if (map.type() == QgsMapLayer.VectorLayer):]
vectors.append( map.name() ) elif (map.type() == QgsMapLayer.RasterLayer):
rasters.append(map.name())else:print“id:,id为的图层不是栅格或矢量”
第一行(即导入行)是允许使用“QgsMapLayer”班级。
接下来的两行初始化两个将填充层名称的空Python列表。 使用Python命令向数组中添加元素追加。
这些层是循环的,将每个键值对直接分隔成两个名为“id”和“map”。 这个“id”变量用于在第10行显示警告消息。
这个"map"变量与方法一起使用“类型()”和“名称()”的 QgsMapLayer 班级。 这个"map.type()"调用返回一个枚举器值,该值可以是“0”,“1”或“2”, 但最好将其与此常量的符号名进行比较,以允许更高的可读性。
17.3.7. 填充组合框#
在对加载的层进行分类之后,我们设置插件接口的组合框的值。 这可以通过以下代码完成:
self.dlg.rastersCombo.insertItems(0,rasters)self.dlg.vectorsCombo.insertItems(0,向量)
我们用对象名命名组合框,“拉斯特斯科博”和“矢量管”,在前面的两个代码行中;
组合框用标准的QComboBox填充插入项(…) 调用传递两个层列表。 这个“0”参数是开始添加新元素的索引。
17.3.8. 理解自我#
在前面的两行中,有一个关键字,“self”,这可能会让第一次接触面向对象编程时的所有人感到困惑。 为了解释它,试着跟随"TestPluginDialog()"创建并保存接口。
在 “test_plugin.py” 代码, 那个"__init__(self, iface)" 函数是第一次创建插件GUI的地方,使用以下指令:
self.dlg = TestPluginDialog()
这意味着创建对话框的结果,即"TestPlugiDialog()"构造函数调用, 保存在属于插件当前实例的"dlg"变量中。 在这种情况下,"dlg"被称为对象或实例变量,其中插件的实例用自变量引用。 这个"self"变量几乎总是在每个Python函数中可用; 这允许我们访问"dlg"变量在代码中的任何位置。
17.3.9. 显示并运行对话框#
我们不必在这里编写任何代码,因为它将由插件生成器生成。 显示对话框如何保存在"self.dlg"实例变量如下所示:
# show the dialog self.dlg.show()
# Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed
if result: # Do something useful here - delete the line containing pass and
# substitute with your code. pass
这段代码与插件生成器生成的注释是不言而喻的。
一些改进:正如你自己所看到的,如果插件运行不止一次,它就不能正常工作。 每次运行插件时,组合框的内容都会增长。 如何避免这种行为留给读者去寻找解决办法。
17.3.10. 代码的更多细节#
和往常一样,这个例子的完整代码可以从这本书的源代码中获得。 在这里,我们将鸟瞰"test_plugin.py"包含"TestPlugin"上课。 这个类有其他方法运行(自身); 具体如下:
__init__(self, iface)
tr(self,消息)
add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None)
initGui(自身)
卸载(自身)
以下列表简要介绍了这些方法:
这个"__init__(self, iface)"方法始终存在于每个Python类中,它是构造函数,这意味着每次找到调用时都会调用它, 例如,测试插件(iface),您可以在"__init__.py"代码。在我们的例子中, 构造函数需要 iface公司在构造期间作为参数传递的变量。构造函数的作用是初始化当前的翻译, 创建插件对话框GUI,以及创建要添加插件按钮的工具栏。
这个“tr(self消息)”方法只是访问字符串消息的Qt转换引擎的快捷方式。
这个“initGui(自身)”方法获取图标资源并指示如何与QGIS菜单交互,调用 "add_action(...)" 方法。 当插件加载到QGIS中时,总是调用此方法。记住加载插件和运行插件之间的区别是很重要的。 加载是使用插件管理器完成的,或者如果插件已经在前一个会话中加载,则在QGIS开始时自动完成。 当用户通过点击插件图标或在插件菜单中激活插件来启动插件时,就会运行插件。
这个“add_action(...)”方法有许多允许精细配置的参数,但大多数参数都与默认值一起使用, "True" 或 "None" 。 此方法的主要目标是在插件菜单中创建菜单, 并创建用于调用"运行()"方法。在Qt中,这些按钮是 QAction 班级。
这个“卸载(自身)”方法用于展开以前添加的所有QGIS GUI元素 "add_action(...)" 方法。 当使用插件管理器在QGIS中卸载插件时,总是调用此方法。