这一节中所有的代码,如果不在QGIS命令行中执行,都需要导入如下包库
1 2 3 4 5 6 7 8 9 10 11 12 | from qgis.PyQt.QtCore import (
QRectF,
)
from qgis.core import (
QgsProject,
QgsLayerTreeModel,
)
from qgis.gui import (
QgsLayerTreeView,
)
|
20. Cheat sheet for PyQGIS¶
20.1. User Interface¶
Change Look & Feel
1 2 3 4 5 6 7 | from qgis.PyQt.QtWidgets import QApplication
app = QApplication.instance()
app.setStyleSheet(".QWidget {color: blue; background-color: yellow;}")
# You can even read the stylesheet from a file
with open("testdata/file.qss") as qss_file_content:
app.setStyleSheet(qss_file_content.read())
|
Change icon and title
1 2 3 4 5 | from qgis.PyQt.QtGui import QIcon
icon = QIcon("/path/to/logo/file.png")
iface.mainWindow().setWindowIcon(icon)
iface.mainWindow().setWindowTitle("My QGIS")
|
20.2. Settings¶
Get QgsSettings list
1 2 3 4 5 6 | from qgis.core import QgsSettings
qs = QgsSettings()
for k in sorted(qs.allKeys()):
print (k)
|
20.3. Toolbars¶
Remove toolbar
1 2 3 4 5 6 | toolbar = iface.helpToolBar()
parent = toolbar.parentWidget()
parent.removeToolBar(toolbar)
# and add again
parent.addToolBar(toolbar)
|
Remove actions toolbar
actions = iface.attributesToolBar().actions()
iface.attributesToolBar().clear()
iface.attributesToolBar().addAction(actions[4])
iface.attributesToolBar().addAction(actions[3])
20.5. Canvas¶
Access canvas
canvas = iface.mapCanvas()
Change canvas color
from qgis.PyQt.QtCore import Qt
iface.mapCanvas().setCanvasColor(Qt.black)
iface.mapCanvas().refresh()
Map Update interval
from qgis.core import QgsSettings
# Set milliseconds (150 milliseconds)
QgsSettings().setValue("/qgis/map_update_interval", 150)
20.6. Layers¶
Add vector layer
layer = iface.addVectorLayer("testdata/airports.shp", "layer name you like", "ogr")
if not layer or not layer.isValid():
print("Layer failed to load!")
Get active layer
layer = iface.activeLayer()
List all layers
from qgis.core import QgsProject
QgsProject.instance().mapLayers().values()
Obtain layers name
1 2 3 4 5 6 7 8 9 | from qgis.core import QgsVectorLayer
layer = QgsVectorLayer("Point?crs=EPSG:4326", "layer name you like", "memory")
QgsProject.instance().addMapLayer(layer)
layers_names = []
for layer in QgsProject.instance().mapLayers().values():
layers_names.append(layer.name())
print("layers TOC = {}".format(layers_names))
|
layers TOC = ['layer name you like']
Otherwise
layers_names = [layer.name() for layer in QgsProject.instance().mapLayers().values()]
print("layers TOC = {}".format(layers_names))
layers TOC = ['layer name you like']
Find layer by name
from qgis.core import QgsProject
layer = QgsProject.instance().mapLayersByName("layer name you like")[0]
print(layer.name())
layer name you like
Set active layer
from qgis.core import QgsProject
layer = QgsProject.instance().mapLayersByName("layer name you like")[0]
iface.setActiveLayer(layer)
Refresh layer at interval
1 2 3 4 5 6 7 | from qgis.core import QgsProject
layer = QgsProject.instance().mapLayersByName("layer name you like")[0]
# Set seconds (5 seconds)
layer.setAutoRefreshInterval(5000)
# Enable auto refresh
layer.setAutoRefreshEnabled(True)
|
Show methods
dir(layer)
Adding new feature with feature form
1 2 3 4 5 6 7 8 | from qgis.core import QgsFeature, QgsGeometry
feat = QgsFeature()
geom = QgsGeometry()
feat.setGeometry(geom)
feat.setFields(layer.fields())
iface.openFeatureForm(layer, feat, False)
|
Adding new feature without feature form
1 2 3 4 5 6 | from qgis.core import QgsGeometry, QgsPointXY, QgsFeature
pr = layer.dataProvider()
feat = QgsFeature()
feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10,10)))
pr.addFeatures([feat])
|
Get features
for f in layer.getFeatures():
print (f)
<qgis._core.QgsFeature object at 0x7f45cc64b678>
Get selected features
for f in layer.selectedFeatures():
print (f)
Get selected features Ids
selected_ids = layer.selectedFeatureIds()
print(selected_ids)
Create a memory layer from selected features Ids
from qgis.core import QgsFeatureRequest
memory_layer = layer.materialize(QgsFeatureRequest().setFilterFids(layer.selectedFeatureIds()))
QgsProject.instance().addMapLayer(memory_layer)
Get geometry
# Point layer
for f in layer.getFeatures():
geom = f.geometry()
print ('%f, %f' % (geom.asPoint().y(), geom.asPoint().x()))
10.000000, 10.000000
Move geometry
1 2 3 4 5 6 | from qgis.core import QgsFeature, QgsGeometry
poly = QgsFeature()
geom = QgsGeometry.fromWkt("POINT(7 45)")
geom.translate(1, 1)
poly.setGeometry(geom)
print(poly.geometry())
|
<QgsGeometry: Point (8 46)>
Set the CRS
from qgis.core import QgsProject, QgsCoordinateReferenceSystem
for layer in QgsProject.instance().mapLayers().values():
layer.setCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
See the CRS
1 2 3 4 5 | from qgis.core import QgsProject
for layer in QgsProject.instance().mapLayers().values():
crs = layer.crs().authid()
layer.setName('{} ({})'.format(layer.name(), crs))
|
Hide a field column
1 2 3 4 5 6 7 8 9 10 | from qgis.core import QgsEditorWidgetSetup
def fieldVisibility (layer,fname):
setup = QgsEditorWidgetSetup('Hidden', {})
for i, column in enumerate(layer.fields()):
if column.name()==fname:
layer.setEditorWidgetSetup(idx, setup)
break
else:
continue
|
Layer from WKT
1 2 3 4 5 6 7 8 9 10 | from qgis.core import QgsVectorLayer, QgsFeature, QgsGeometry, QgsProject
layer = QgsVectorLayer('Polygon?crs=epsg:4326', 'Mississippi', 'memory')
pr = layer.dataProvider()
poly = QgsFeature()
geom = QgsGeometry.fromWkt("POLYGON ((-88.82 34.99,-88.0934.89,-88.39 30.34,-89.57 30.18,-89.73 31,-91.63 30.99,-90.8732.37,-91.23 33.44,-90.93 34.23,-90.30 34.99,-88.82 34.99))")
poly.setGeometry(geom)
pr.addFeatures([poly])
layer.updateExtents()
QgsProject.instance().addMapLayers([layer])
|
Load all vector layers from GeoPackage
1 2 3 4 5 6 7 8 9 10 11 | fileName = "testdata/sublayers.gpkg"
layer = QgsVectorLayer(fileName, "test", "ogr")
subLayers = layer.dataProvider().subLayers()
for subLayer in subLayers:
name = subLayer.split('!!::!!')[1]
uri = "%s|layername=%s" % (fileName, name,)
# Create layer
sub_vlayer = QgsVectorLayer(uri, name, 'ogr')
# Add layer to map
QgsProject.instance().addMapLayer(sub_vlayer)
|
Load tile layer (XYZ-Layer)
1 2 3 4 5 6 7 8 | from qgis.core import QgsRasterLayer, QgsProject
def loadXYZ(url, name):
rasterLyr = QgsRasterLayer("type=xyz&url=" + url, name, "wms")
QgsProject.instance().addMapLayer(rasterLyr)
urlWithParams = 'type=xyz&url=https://a.tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png&zmax=19&zmin=0&crs=EPSG3857'
loadXYZ(urlWithParams, 'OpenStreetMap')
|
Remove all layers
QgsProject.instance().removeAllMapLayers()
Remove all
QgsProject.instance().clear()
20.7. Table of contents¶
Access checked layers
iface.mapCanvas().layers()
Remove contextual menu
1 2 3 4 5 | ltv = iface.layerTreeView()
mp = ltv.menuProvider()
ltv.setMenuProvider(None)
# Restore
ltv.setMenuProvider(mp)
|
20.8. Advanced TOC¶
Root node
1 2 3 4 5 6 7 8 9 10 11 12 | from qgis.core import QgsVectorLayer, QgsProject, QgsLayerTreeLayer
root = QgsProject.instance().layerTreeRoot()
node_group = root.addGroup("My Group")
layer = QgsVectorLayer("Point?crs=EPSG:4326", "layer name you like", "memory")
QgsProject.instance().addMapLayer(layer, False)
node_group.addLayer(layer)
print(root)
print(root.children())
|
Access the first child node
1 2 3 4 5 6 7 | from qgis.core import QgsLayerTreeGroup, QgsLayerTreeLayer, QgsLayerTree
child0 = root.children()[0]
print (child0.name())
print (type(child0))
print (isinstance(child0, QgsLayerTreeLayer))
print (isinstance(child0.parent(), QgsLayerTree))
|
My Group
<class 'qgis._core.QgsLayerTreeGroup'>
False
True
Find groups and nodes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | from qgis.core import QgsLayerTreeGroup, QgsLayerTreeLayer
def get_group_layers(group):
print('- group: ' + group.name())
for child in group.children():
if isinstance(child, QgsLayerTreeGroup):
# Recursive call to get nested groups
get_group_layers(child)
else:
print(' - layer: ' + child.name())
root = QgsProject.instance().layerTreeRoot()
for child in root.children():
if isinstance(child, QgsLayerTreeGroup):
get_group_layers(child)
elif isinstance(child, QgsLayerTreeLayer):
print ('- layer: ' + child.name())
|
- group: My Group
- layer: layer name you like
Find group by name
print (root.findGroup("My Group"))
<qgis._core.QgsLayerTreeGroup object at 0x7fd75560cee8>
Find layer by id
print(root.findLayer(layer.id()))
<qgis._core.QgsLayerTreeLayer object at 0x7f56087af288>
Add layer
1 2 3 4 5 6 7 | from qgis.core import QgsVectorLayer, QgsProject
layer1 = QgsVectorLayer("Point?crs=EPSG:4326", "layer name you like 2", "memory")
QgsProject.instance().addMapLayer(layer1, False)
node_layer1 = root.addLayer(layer1)
# Remove it
QgsProject.instance().removeMapLayer(layer1)
|
Add group
1 2 3 4 5 | from qgis.core import QgsLayerTreeGroup
node_group2 = QgsLayerTreeGroup("Group 2")
root.addChildNode(node_group2)
QgsProject.instance().mapLayersByName("layer name you like")[0]
|
Move loaded layer
1 2 3 4 5 6 7 8 9 10 11 12 | layer = QgsProject.instance().mapLayersByName("layer name you like")[0]
root = QgsProject.instance().layerTreeRoot()
myLayer = root.findLayer(layer.id())
myClone = myLayer.clone()
parent = myLayer.parent()
myGroup = root.findGroup("My Group")
# Insert in first position
myGroup.insertChildNode(0, myClone)
parent.removeChildNode(myLayer)
|
Move loaded layer to a specific group
1 2 3 4 5 6 7 8 | QgsProject.instance().addMapLayer(layer, False)
root = QgsProject.instance().layerTreeRoot()
myGroup = root.findGroup("My Group")
myOriginalLayer = root.findLayer(layer.id())
myLayer = myOriginalLayer.clone()
myGroup.insertChildNode(0, myLayer)
parent.removeChildNode(myOriginalLayer)
|
Changing visibility
myGroup.setItemVisibilityChecked(False)
myLayer.setItemVisibilityChecked(False)
Is group selected
1 2 3 4 5 | def isMyGroupSelected( groupName ):
myGroup = QgsProject.instance().layerTreeRoot().findGroup( groupName )
return myGroup in iface.layerTreeView().selectedNodes()
print(isMyGroupSelected( 'my group name' ))
|
False
Expand node
print(myGroup.isExpanded())
myGroup.setExpanded(False)
Hidden node trick
1 2 3 4 5 6 7 8 9 10 11 12 13 | from qgis.core import QgsProject
model = iface.layerTreeView().layerTreeModel()
ltv = iface.layerTreeView()
root = QgsProject.instance().layerTreeRoot()
layer = QgsProject.instance().mapLayersByName('layer name you like')[0]
node = root.findLayer( layer.id())
index = model.node2index( node )
ltv.setRowHidden( index.row(), index.parent(), True )
node.setCustomProperty( 'nodeHidden', 'true')
ltv.setCurrentIndex(model.node2index(root))
|
Node signals
1 2 3 4 5 6 7 8 | def onWillAddChildren(node, indexFrom, indexTo):
print ("WILL ADD", node, indexFrom, indexTo)
def onAddedChildren(node, indexFrom, indexTo):
print ("ADDED", node, indexFrom, indexTo)
root.willAddChildren.connect(onWillAddChildren)
root.addedChildren.connect(onAddedChildren)
|
Remove layer
root.removeLayer(layer)
Remove group
root.removeChildNode(node_group2)
Create new table of contents (TOC)
1 2 3 4 5 | root = QgsProject.instance().layerTreeRoot()
model = QgsLayerTreeModel(root)
view = QgsLayerTreeView()
view.setModel(model)
view.show()
|
Move node
cloned_group1 = node_group.clone()
root.insertChildNode(0, cloned_group1)
root.removeChildNode(node_group)
Rename node
cloned_group1.setName("Group X")
node_layer1.setName("Layer X")
20.9. Processing algorithms¶
Get algorithms list
1 2 3 4 5 | from qgis.core import QgsApplication
for alg in QgsApplication.processingRegistry().algorithms():
if 'buffer' == alg.name():
print("{}:{} --> {}".format(alg.provider().name(), alg.name(), alg.displayName()))
|
QGIS (native c++):buffer --> Buffer
Get algorithms help
Random selection
from qgis import processing
processing.algorithmHelp("native:buffer")
...
Run the algorithm
For this example, the result is stored in a temporary memory layer which is added to the project.
from qgis import processing
result = processing.run("native:buffer", {'INPUT': layer, 'OUTPUT': 'memory:'})
QgsProject.instance().addMapLayer(result['OUTPUT'])
Processing(0): Results: {'OUTPUT': 'output_d27a2008_970c_4687_b025_f057abbd7319'}
How many algorithms are there?
len(QgsApplication.processingRegistry().algorithms())
How many providers are there?
from qgis.core import QgsApplication
len(QgsApplication.processingRegistry().providers())
How many expressions are there?
from qgis.core import QgsExpression
len(QgsExpression.Functions())
20.10. Decorators¶
CopyRight
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | from qgis.PyQt.Qt import QTextDocument
from qgis.PyQt.QtGui import QFont
mQFont = "Sans Serif"
mQFontsize = 9
mLabelQString = "© QGIS 2019"
mMarginHorizontal = 0
mMarginVertical = 0
mLabelQColor = "#FF0000"
INCHES_TO_MM = 0.0393700787402 # 1 millimeter = 0.0393700787402 inches
case = 2
def add_copyright(p, text, xOffset, yOffset):
p.translate( xOffset , yOffset )
text.drawContents(p)
p.setWorldTransform( p.worldTransform() )
def _on_render_complete(p):
deviceHeight = p.device().height() # Get paint device height on which this painter is currently painting
deviceWidth = p.device().width() # Get paint device width on which this painter is currently painting
# Create new container for structured rich text
text = QTextDocument()
font = QFont()
font.setFamily(mQFont)
font.setPointSize(int(mQFontsize))
text.setDefaultFont(font)
style = "<style type=\"text/css\"> p {color: " + mLabelQColor + "}</style>"
text.setHtml( style + "<p>" + mLabelQString + "</p>" )
# Text Size
size = text.size()
# RenderMillimeters
pixelsInchX = p.device().logicalDpiX()
pixelsInchY = p.device().logicalDpiY()
xOffset = pixelsInchX * INCHES_TO_MM * int(mMarginHorizontal)
yOffset = pixelsInchY * INCHES_TO_MM * int(mMarginVertical)
# Calculate positions
if case == 0:
# Top Left
add_copyright(p, text, xOffset, yOffset)
elif case == 1:
# Bottom Left
yOffset = deviceHeight - yOffset - size.height()
add_copyright(p, text, xOffset, yOffset)
elif case == 2:
# Top Right
xOffset = deviceWidth - xOffset - size.width()
add_copyright(p, text, xOffset, yOffset)
elif case == 3:
# Bottom Right
yOffset = deviceHeight - yOffset - size.height()
xOffset = deviceWidth - xOffset - size.width()
add_copyright(p, text, xOffset, yOffset)
elif case == 4:
# Top Center
xOffset = deviceWidth / 2
add_copyright(p, text, xOffset, yOffset)
else:
# Bottom Center
yOffset = deviceHeight - yOffset - size.height()
xOffset = deviceWidth / 2
add_copyright(p, text, xOffset, yOffset)
# Emitted when the canvas has rendered
iface.mapCanvas().renderComplete.connect(_on_render_complete)
# Repaint the canvas map
iface.mapCanvas().refresh()
|
20.11. Composer¶
Get print layout by name
1 2 3 4 5 | composerTitle = 'MyComposer' # Name of the composer
project = QgsProject.instance()
projectLayoutManager = project.layoutManager()
layout = projectLayoutManager.layoutByName(composerTitle)
|