qgis,pyqgis,qgis-3,pyqgis-3 – PyQGIS to Set Masked Symbol Layer and Mask Source

pyqgispyqgis-3qgisqgis-3

I have a PyQGIS script to open a GPKG-layer (contour lines) along with a qml-file in QGIS.
In the style file I have enabled label masking and using the contour lines as mask layer:

enter image description here

enter image description here

Making my labels look like this:

enter image description here

However, after running the python-file, the style is as expected (as given in the qml-file), but without the masking (label masking information is not stored in the qml-file?):

enter image description here

My code so far where I have not figured out how to set "Masked symbol layers" and "Mask sources":

# Add geopackage
fileName = "karplantehoyder.gpkg"
layer = QgsVectorLayer(fileName, "hoyder", "ogr")
label = QgsPalLayerSettings()
label.MaskEnabled = True
# masklayer = QgsMaskMarkerSymbolLayer()  #? How do i set the mask symbol layer and mask source
# masklayer.setMasks("hoyder")            # This is not working, have tried id and layer - not working
QgsProject.instance().addMapLayer(layer, True) 
# Load style
layer.loadNamedStyle('./qml/n5hoyder.qml')  # color, line width, label font/size set, but not mask
layer.saveStyleToDatabase(layer.name(),'style n5hoyder',True,'')

How may I do this with PyQGIS-code?

Update: I have also tried to use QgsTextMaskSettings, but I can't figure out how to set the mask layer to be "hoyder" and symbol to be lines.

I have also discovered a strange behaviour? Masks may be set in the layer hoyder's Layer Properties and still be unchecked in Layer styling, and the mask will appear.

enter image description here

If only set in the Layer Styling and not in the Layer Properties, the mask will not appear.

enter image description here

Best Answer

Label masking information is not stored in the qml-file?

I guess "Masked symbol layers" and "Mask sources" settings are not stored in both qml file and Geopackage. I just realized that.

One solution would be as follows:

  • Load qml file
  • Get layer labeling mask settings
  • Set masked symbol layers
  • Apply the setting to the layer
# Add layer
fileName = "karplantehoyder.gpkg"
layer = QgsVectorLayer(fileName, "hoyder", "ogr")
QgsProject.instance().addMapLayer(layer, True) 

# Load qml
layer.loadNamedStyle('./qml/n5hoyder.qml')

# Get current settings of the layer
label_settings = layer.labeling().settings()
# If you use labeling() method before loading qml, you get error
# Because labeling is not enabled for the layer before loading qml


# Get text format of the settings
text_format = label_settings.format()

# Set masked symbol layers
text_format.mask().setMaskedSymbolLayers([
    QgsSymbolLayerReference(layer.id(), QgsSymbolLayerId("", 0))])

# Set format
label_settings.setFormat(text_format)

# Set settings
layer.labeling().setSettings(label_settings)

enter image description here

Documentation: