I'm generating a map print layout programmatically with PyQGIS. The print layout contains 2 map items, the 'Main map' and 'Inset'. I want the inset to show 'Layer 1', 'Layer 2' and 'Layer 3' (with Layer 3 at the bottom), while the Main map will show all layers, except 'Layer 1' and 'Layer 2'.
I have tried setting the inset layers visibility then locking the layers and styles:
map_item = layout.itemById('Inset')
layers= self.project.mapLayers()
insetLayers=[]
for layerID, l in layers.items():
if l.name() == 'Layer 3':
self.project.layerTreeRoot().findLayer(l.id()).setItemVisibilityChecked(True)
insetLayers.insert(0, l)
elif l.name() in ['Layer 1', 'Layer 2']:
self.project.layerTreeRoot().findLayer(l.id()).setItemVisibilityChecked(True)
insetLayers.append(l)
map_item.setLayers(insetLayers)
map_item.setKeepLayerSet(True)
map_item.setKeepLayerStyles(True)
map_item.refresh()
for l in layers.values():
if l.name() in ['Layer 1','Layer 2']:
self.project.layerTreeRoot().findLayer(l.id()).setItemVisibilityChecked(False)
else:
self.project.layerTreeRoot().findLayer(l.id()).setItemVisibilityChecked(True)
This code locked the inset layers correctly, but 'Layer 1' and 'Layer 2' were showing only their labels, not their features. This could potentially be because 'Layer 3' is above them, but 'Layer 3' is at the bottom of the layers list.
I think this could be solved by setting a data defined override for the layers being displayed, but I'm having trouble doing this. I can set the override expression in QGIS here:
but I can't figure how to do this in PyQGIS. I have tried:
map_item = layout.itemById('Inset')
expression = 'Layer 1|Layer 2|Layer 3'
property_expression = QgsProperty(expression)
map_item.setLayers(property_expression)
map_item.refresh()