1

I am trying to generate maps in pdf files by using a pre-defined .qgz layout. I am already able to load layers and adjust color scale, etc. Since the legend is synchronized with the map layers, all the layers I have loaded are listed in the legend.

Using PrintComposer in QGIS I can turn off synchronization and remove the unwanted items in legend. Is there a way to do it automatically in Python? I tried to use QgsLegendModel, but it also removes the layers from map canvas.

unwanted items in legend.

projectInstance= QgsProject.instance()
projectLayoutManager = projectInstance.layoutManager()

for comp in projectLayoutManager.printLayouts():
    for item in comp.items():
        if(isinstance(item, QgsLayoutItemLegend)):                
            model = item.model()
            while model.rowCount()>1:
                 model.removeRow(0)

            break
2

This is code adapted for QGIS 3 from this answer. It adds all layers except one specified. You could swap this out for a list, or conversely, use the layers you want to keep in rather than those you want to leave out.

l = QgsProject.instance().layoutManager()

for layout in l.printLayouts():    
    legend = QgsLayoutItemLegend(layout)
    root = QgsLayerTree()
    for lyr in iface.mapCanvas().layers():
        if lyr.name() != 'Unwanted layer':  
            root.addLayer(lyr)
        legend.model().setRootGroup(root)
        layout.addItem(legend)

In place of if lyr.name() != 'Unwanted layer': you could use

if lyr.name() not in [list, of, unwanted, layer, names]: or

if lyr.name() in [list, of, wanted, layer, names]:

  • iface.mapCanvas().layers() returns an empty list when run within the script. However when I paste it in Python console it returns correct collection of layers. I guess there is an asynchronous update for which I should wait for? – Marcin Kawka Dec 18 '18 at 13:54
  • Are you using a standalone script or one in the Editor in the Python console? – Matt Needle Dec 19 '18 at 12:43
  • I am using Python Editor (within QGIS 3.4) – Marcin Kawka Dec 19 '18 at 12:50
  • That is strange. Mine works as desired. It won't include layers which are unchecked in the layers panel, however. – Matt Needle Dec 19 '18 at 12:53
1

Matt Needle, your solution started to work after I've forced qt to process the bufferd events, before iterating through layers. Thank you for your hint.


from PyQt5 import QtWidgets
inst = QtWidgets.QApplication.instance()
qapp = QtWidgets.qApp
qapp.processEvents()

l = QgsProject.instance().layoutManager()

for layout in l.printLayouts():    
    legend = QgsLayoutItemLegend(layout)
    root = QgsLayerTree()
    for lyr in iface.mapCanvas().layers():
        if lyr.name() != 'Unwanted layer':  
            root.addLayer(lyr)
        legend.model().setRootGroup(root)
        layout.addItem(legend)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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