3

I have a number of vector layers and, occasionally, an image basemap.

I am creating a layout programatically based on this data.

I have a legend but I have zero want or need for the basemap raster layer to be displayed. I want to remove the raster item from the Legend, NOT the whole project.

Answers such as these (and those from years earlier) remove the whole entire layer from the project.

I simply want to remove the legend item. I do however want to keep the raster layer in the project.

This function is called after the layout has been created:

def remove_raster_layers_from_legend(project_layers,project,layout_name):
    layout_manager = project.layoutManager()
    layout_def = layout_manager.layoutByName(layout_name)
    legend = layout_def.itemById('Legend')
    root_group = legend.model().rootGroup()  # QgsLayerTree object
    
    legend.setAutoUpdateModel(False)
    
    for id, layer in project_layers:
        if layer.type().name == 'RasterLayer':
            # Find the legend item corresponding to the layer
            legend_item = root_group.findLayer(layer)
            if legend_item is not None:
                root_group.removeChildNode(legend_item)
    
    legend.adjustBoxSize()
    layout_def.refresh()

The inputs are as follows:

project = QgsProject.instance() # <class 'qgis._core.QgsProject'>
project_layers = QgsProject.instance().mapLayers().items() # <class 'dict_items'> 
layout_name = "PRINT_LAYOUT_1" # <class 'str'>

This is part of a processing script which does some calculations and then styles the layers and creates the print layout.

1 Answer 1

3

Maybe you should consider reconstructing a new legend instead of removing the items from an existing legend. But interestingly, when I use layout.addLayoutItem(legend) in a function, QGIS crashes. Therefore, I added a line by line soluiton.

Use this script:

project = QgsProject.instance()
project_layers = QgsProject.instance().mapLayers().items()
layout_name = "PRINT_LAYOUT_1"

layout_manager = project.layoutManager()
layout = layout_manager.layoutByName(layout_name)

legend = QgsLayoutItemLegend(layout)
legend.setAutoUpdateModel(False)
root = QgsLayerTree()

for id, layer in project_layers:
    if layer.type().name != 'RasterLayer':
        root.addLayer(layer)
        print(layer.name())
        
legend.model().setRootGroup(root)    
legend.adjustBoxSize()
legend.setFrameEnabled(True)
legend.attemptMove(QgsLayoutPoint(0,0, QgsUnitTypes.LayoutMillimeters))

layout.addLayoutItem(legend)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.