QGIS插件开发
目标:开发一个使用工具箱工具的插件
环境准备
软件环境
- windows10
- QGIS:3.4.15-1 (包含PyQGIS模块)
- qt-creator-opensource:5.0.3 (来进行过界面修改)
- pycharm
配置系统环境
配置QGIS的python环境
安装QGIS插件
打开QGIS,工具栏,插件——管理并安装插件。
搜索并安装
Plugin Builder:快速创建一个插件项目
和Plugin Reloader:修改插件代码后,在QGIS中不用重启就能刷新插件
创建项目
官方文档
这里的Class name是插件的类名,Plugin name是你的插件名,Moule name是python模块的名称。
![img](https://gitee.com/SunBaTian/notes_images/raw/master/%20image/notes_mac/c64fc8d30d7099e83e58bb963ea52044.png
如果不想发布插件,只做练习使用,这里建议大家勾选Flag the plugin as experimental选项
这里选择之前设置的插件工作区的路径,自动生成的插件模板就会放置于该目录下。
打开到文件夹位置使用cmd运行命令
pyrcc5 -o resources.py resources.qrc
生成如下文件
将项目放到插件目录下
打开QGIS,工具栏——设置——用户配置——打开活动配置目录。
在这个/profiles/default文件夹下,打开python/plugins文件夹,QGIS的插件都在这里,把工程放到这个文件夹下。
查看效果 关闭QGIS,重启QGIS。
工具栏,插件——管理并安装插件,已安装中,插件赫然在列,勾选上。
工具图标也在界面上,点击图标,插件如下。
使用QT Creator设置插件页面
使用QC打开项目中的.ui文件
设计界面入下
保存
编辑代码
配置pyCharm环境
使用pyCharm打开项目
这里主要就是修改geotest.py文件
代码如下:
"""
/***************************************************************************
geotest
A QGIS plugin
测试工具
Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
-------------------
begin : 2021-12-13
git sha : $Format:%H$
copyright : (C) 2021 by sunbt
email : 1327398885@qq.com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
"""
import processing
from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtWidgets import QAction, QFileDialog, QProgressBar
from qgis.core import *
from .resources import *
from .geotest_dialog import geotestDialog
import os.path
class geotest:
"""QGIS Plugin Implementation."""
def __init__(self, iface):
"""Constructor.
:param iface: An interface instance that will be passed to this class
which provides the hook by which you can manipulate the QGIS
application at run time.
:type iface: QgsInterface
"""
self.iface = iface
self.plugin_dir = os.path.dirname(__file__)
locale = QSettings().value('locale/userLocale')[0:2]
locale_path = os.path.join(
self.plugin_dir,
'i18n',
'geotest_{}.qm'.format(locale))
if os.path.exists(locale_path):
self.translator = QTranslator()
self.translator.load(locale_path)
QCoreApplication.installTranslator(self.translator)
self.actions = []
self.menu = self.tr(u'&geotest')
self.first_start = None
def tr(self, message):
"""Get the translation for a string using Qt translation API.
We implement this ourselves since we do not inherit QObject.
:param message: String for translation.
:type message: str, QString
:returns: Translated version of message.
:rtype: QString
"""
return QCoreApplication.translate('geotest', message)
def 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):
"""Add a toolbar icon to the toolbar.
:param icon_path: Path to the icon for this action. Can be a resource
path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
:type icon_path: str
:param text: Text that should be shown in menu items for this action.
:type text: str
:param callback: Function to be called when the action is triggered.
:type callback: function
:param enabled_flag: A flag indicating if the action should be enabled
by default. Defaults to True.
:type enabled_flag: bool
:param add_to_menu: Flag indicating whether the action should also
be added to the menu. Defaults to True.
:type add_to_menu: bool
:param add_to_toolbar: Flag indicating whether the action should also
be added to the toolbar. Defaults to True.
:type add_to_toolbar: bool
:param status_tip: Optional text to show in a popup when mouse pointer
hovers over the action.
:type status_tip: str
:param parent: Parent widget for the new action. Defaults None.
:type parent: QWidget
:param whats_this: Optional text to show in the status bar when the
mouse pointer hovers over the action.
:returns: The action that was created. Note that the action is also
added to self.actions list.
:rtype: QAction
"""
icon = QIcon(icon_path)
action = QAction(icon, text, parent)
action.triggered.connect(callback)
action.setEnabled(enabled_flag)
if status_tip is not None:
action.setStatusTip(status_tip)
if whats_this is not None:
action.setWhatsThis(whats_this)
if add_to_toolbar:
self.iface.addToolBarIcon(action)
if add_to_menu:
self.iface.addPluginToMenu(
self.menu,
action)
self.actions.append(action)
return action
def initGui(self):
"""Create the menu entries and toolbar icons inside the QGIS GUI."""
icon_path = ':/plugins/geotest/icon.png'
self.add_action(
icon_path,
text=self.tr(u'geotest'),
callback=self.run,
parent=self.iface.mainWindow())
self.first_start = True
def unload(self):
"""Removes the plugin menu item and icon from QGIS GUI."""
for action in self.actions:
self.iface.removePluginMenu(
self.tr(u'&geotest'),
action)
self.iface.removeToolBarIcon(action)
def select_inputA_file(self):
filename, _filter = QFileDialog.getOpenFileName(
self.dlg, "Select input file", "", "*.shp"
)
self.dlg.lineEditShpA.setText(filename)
def select_output_file(self):
filename, _filter = QFileDialog.getSaveFileName(
self.dlg, "Select output file", "", "*.shp"
)
self.dlg.lineEditShpB.setText(filename)
def filter(self, input_path, output_path, condition, layerName):
alg_params = {
'EXPRESSION': condition,
'INPUT': input_path,
'OUTPUT': output_path
}
processing.run('native:extractbyexpression', alg_params)
def run(self):
"""Run method that performs all the real work"""
if self.first_start == True:
self.first_start = False
self.dlg = geotestDialog()
self.dlg.pushButtonShpA.clicked.connect(self.select_inputA_file)
self.dlg.pushButtonShpB.clicked.connect(self.select_output_file)
self.dlg.show()
result = self.dlg.exec_()
if result:
shpAPath = self.dlg.lineEditShpA.text()
condition = self.dlg.lineEditTxt.text()
outPath = self.dlg.lineEditShpB.text()
layerName = outPath.split("/")[len(outPath.split("/")) - 1].replace(".shp", "")
self.filter(shpAPath, outPath, condition, layerName)
vlayer = QgsVectorLayer(outPath, layerName, "ogr")
if vlayer.isValid():
QgsProject.instance().addMapLayer(vlayer)
else:
print("图层加载失败!")
pass
self.iface.messageBar().pushMessage("成功", "加载图层:" + layerName, level=Qgis.Success, duration=3)
具体功能如上有注释
使用reload刷新插件
效果
点击插件,选择数据和填入表达式条件
结果如下:
|