PyQGIS Rule-Based Labelling – How to Control Rule-Based Labelling Using PyQGIS

labelingpyqgisqgis-3rule-based

Following on from this question: How to turn on/off all labels of all layers in QGIS, OP mentioned in his comment that he uses rule-based labels. I tried searching online as to how these types of labels could be read and modified but only managed to find this post from lutraconsulting:

In order to facilitate addition of rule-based labelling, some internal changes were made to the QGIS labelling engine interface. The labelling is now driven by the new class QgsLabelingEngineV2 which may have several label providers associated with it.

Sounds great. However, when reading through the QgsLabelingEngineV2 class, it mentions:

this class is not a part of public API yet.

Is it currently possible to control rule-based labelling using python?

Best Answer

Below some help to setup rule based labeling from scratch with the new QGIS 3 API

#Configure label settings
settings = QgsPalLayerSettings()
settings.fieldName = 'myFieldName'
textFormat = QgsTextFormat()
textFormat.setSize(10)
settings.setFormat(textFormat)
#create and append a new rule
root = QgsRuleBasedLabeling.Rule(QgsPalLayerSettings())
rule = QgsRuleBasedLabeling.Rule(settings)
rule.setDescription(fieldName)
rule.setFilterExpression('myExpression')
root.appendChild(rule)
#Apply label configuration
rules = QgsRuleBasedLabeling(root)
myLayer.setLabeling(rules)
myLayer.triggerRepaint()

Unfortunately I can't find how to iterate over existing rules, the labeling() method available for vector layers return an object of QgsAbstractVectorLayerLabeling class but it seems there is no way to get the root rule (QgsRuleBasedLabeling) from this class, the only possibility I found is to get directly pal settings using providers ids but I can't access to rules tree. Anyone have a clue ?

EDIT

It's now fixed, labeling() function return a QgsRuleBasedLabeling() : https://github.com/qgis/QGIS/commit/4b365a8f47d96b35f7609859e580388927ae0606

Related Question