刚结束了QGIS插件开发的上机实习,时间很紧,只开发了一些简单的小功能,供大家参考,欢迎交流!
插件实现的功能是修改点状要素的样式(包括大小、颜色),样式包括SVG格式的图片和QGIS自带的点状样式如circle、square、cross……
版本方面我自己用的是QGIS Desktop 3.22.8和PyCharm 2021.2.4。安利一款无脑激活PyCharm的方法,直接激活99年!
链接:https://pan.baidu.com/s/1jN19mcAh2Ej_xOp6NNTLSg
提取码:1cee
环境配置
QGIS端的配置
首先在QGIS插件管理中安装 Plugin Builder3和Plugin Reloader两个插件。
具体作用如下(不感兴趣的同学可以跳过)
PB:可以生成一个QGIS插件模板,在生成的插件模板基础上根据我们的需要进行二次开发;PR:可以动态加载QGIS已经安装的插件,这样在后续开发中如果对插件进行了改动,可以直接动态重新载入插件,而不用重启QGIS。
安装好之后,就可以使用PB生成插件模板,设置好路径。这里需要注意的是QGIS在这一路径(……QGIS\QGIS3\profiles\default\python\plugins)取读文件,所以后续的插件更新都要确保放在这个文件夹。
Pycharm端的配置
首先是在pycharm中选择Python interpreter解释器,这里需要选择QGIS安装目录中的python-qgis-ltr.bat文件作为解释器。
选中python-qgis.bat为解释器后,下面的Package栏就会弹出一系列包。但是为了开发,我们还需要自己安装一些包(pyuic、pyrcc、qtdesigner)。
Pyuic的作用:Pyuic可将ui文件自动编译为py文件。在利用Qtdesigner with QGIS进行ui设计之后,鼠标选中工程目录中的ui文件,点击tools-external tools-pyuic即可生成一个与ui文件同名的py文件,即ui文件对应的py代码。Ui文件可以在Qtdesigner with QGIS软件中操作也可以直接在pycharm中安装(“C:\Users\Lenovo\AppData\Local\Programs\Python\Python38\Lib\site-packages\qt5_applications\Qt\bin\designer.exe”),这样方便ui和py环境的切换。pyrcc的作用是将resources.qrc转为py文件。
点击File->setting->tools->external tools,点击加号,照着下面的填写:

Pyuic安装方法:program的路径填写为可以按上面的pyrcc的路径写,但是我在实际操作的过程中发现ui转py可以进行但是转出来的py文件为空,所以我通过cmd-pip install pyqt5-tools下载了安装包,将路径填为该安装包中pyuic5.exe的路径,问题解决。


至此,QGIS端和pycharm端的环境配置结束!
UI设计
这里大家根据自己喜好设计就好,我把自己的放在这里仅供参考。
需要说明的是在修改完ui之后若要给相应的button绑定功能,一定不要忘记更新ui对应的py文件。
代码实现
import os
import sys
from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QFileDialog, QMessageBox, QWidget, QApplication, QColorDialog, QLineEdit
from qgis.PyQt import uic
from qgis.PyQt import QtWidgets
from qgis._core import QgsVectorLayer, QgsProject, QgsCoordinateReferenceSystem, QgsRasterLayer, QgsColorRampShader, \
QgsRasterShader, QgsSingleBandPseudoColorRenderer, QgsMarkerSymbol, QgsMapLayerProxyModel
from qgis.core import (QgsSvgMarkerSymbolLayer, QgsMarkerSymbol, QgsSingleSymbolRenderer)
from qgis.PyQt.QtCore import QPointF
FORM_CLASS, _ = uic.loadUiType(os.path.join(
os.path.dirname(__file__), 'adddata_dialog_base.ui'))
class AddDataDialog(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, parent=None):
"""Constructor."""
super(AddDataDialog, self).__init__(parent)
self.setupUi(self)
self.pushButtonSVG.clicked.connect(self.SelectSvg)
self.comboBox.currentIndexChanged.connect(self.SelectSymbol)
self.spinBox.valueChanged.connect(self.change_table)
self.spinBoxSVG.valueChanged.connect(self.change_tableSvg)
self.pushButtonColor.clicked.connect(self.showDialog)
self.mMapLayerComboBox.setFilters(QgsMapLayerProxyModel.PointLayer)
self.mMapLayerComboBox.layerChanged.connect(self.isSomethingSelected)
def change_table(self):
self.number = self.spinBox.value()
def change_tableSvg(self):
self.numberSvg = self.spinBoxSVG.value()
def isSomethingSelected(self):
vlayer = self.mMapLayerComboBox.currentLayer()
self.vlayer = vlayer
# 选择符号
def SelectSymbol(self):
symbol = str(self.comboBox.currentText())
# path = self.fullPath
number = self.number
# vlayer = QgsVectorLayer(path)
vlayer = self.vlayer
props = vlayer.renderer().symbol().symbolLayer(0).properties()
color = self.color
props['color'] = color
props['name'] = symbol
props['size'] = number
vlayer.renderer().setSymbol(QgsMarkerSymbol.createSimple(props))
# show the changes
vlayer.triggerRepaint()
if not vlayer.isValid():
print("Layer failed to load!")
else:
QgsProject.instance().addMapLayer(vlayer)
# 选择svg
def SelectSvg(self):
fullPath, format = QFileDialog.getOpenFileNames(None, '打开数据s', '', '*.svg')
if fullPath:
if os.path.exists(fullPath):
vlayer = self.vlayer
svg_size = self.numberSvg
svg = QgsSvgMarkerSymbolLayer(fullPath) # 加载SVG的路径
svg.setSize(svg_size) # 设置大小
svg.setOffset(QPointF(0, -svg_size // 2)) # 设置偏移,因为这个SVG是定位点是在底部的
symbol = QgsMarkerSymbol()
symbol.appendSymbolLayer(svg) # 添加SVG的标记
symbol.deleteSymbolLayer(0) # 删除默认的原始标记
renderer = QgsSingleSymbolRenderer(symbol)
vlayer.setRenderer(renderer)
vlayer.triggerRepaint()
QgsProject.instance().addMapLayer(vlayer)
def showDialog(self):
col = QColorDialog.getColor() # 调用取色器
self.color = col
欢迎留言!