3

I'm creating a legend in my print composer and only want "visible", or active, layers shown in the legend. This means I want only layers with the box checked in my layers panel.

Here is how I create my legend.

legend = QgsLayoutItemLegend(layout)
legend.setTitle("Legend")
layout.addLayoutItem(legend)

Looking at the documentation for QgsLayoutItemLegend there is a method: setLegendFilterByMapEnabled() whose description is: enter image description here

This leads me to believe if I do something like:

legend.setLegendFilterByMapEnabled(True)

My legend will only include "active" layers. But my legend still includes all layers, active and inactive.

What am I missing?

1 Answer 1

6

You need to link the legend item to a map item in your layout which is an instance of the QgsLayoutItemMap class. So if you have done something like:

map = QgsLayoutItemMap(layout)
layout.addItem(map)

link it with the legend before enabling the filtering:

legend.setLinkedMap(map) # pass a QgsLayoutItemMap object
legend.setLegendFilterByMapEnabled(True)
legend.refresh()

Alternatively, to collect checked layers from the project layer tree view and add those to your layout legend, you could do something like this:

lyrs_to_add = [l for l in QgsProject().instance().layerTreeRoot().children() if l.isVisible()]
legend = QgsLayoutItemLegend(layout)
legend.setTitle('Legend')
legend.setAutoUpdateModel(False)
group = legend.model().rootGroup()
group.clear()
for l in lyrs_to_add:
    if l.nodeType() == 0:
        subgroup = group.addGroup(l.name())
        checked = l.checkedLayers()
        for c in checked:
            subgroup.addLayer(c)
    elif l.nodeType() == 1:
        group.addLayer(l.layer())
layout.addItem(legend)
legend.adjustBoxSize()
legend.refresh()

This will maintain groups etc. but unfortunately it won't filter unchecked nodes for categorized or graduated layers (I still can't work out how to do that).

5
  • I completely misunderstood setLegendFilterByMapEnabled() so thank you for explaining that method. Also, this is amazing. You have really helped me out recently! Two questions I have: in your checked_lyrs list comprehension line, where did you get the .children() method from? I don't see it as a method in the QgsLayerTree class. I understand the children are the items in the Layer Tree. Or is this a generic method I can call on any object that contains multiple items? The same applies to: root.addLayer(lyr). Shouldn't .addLayer be a method of QgsLayerTree? Jan 31, 2019 at 15:44
  • Another question: in the legend.model().setRootGroup() line. .model is a method of QgsLayoutItemLegend class which "returns the legend model" (that isn't very descriptive). and .setRootGroup is a method of QgsLayerTreeModel class. How can these be chained together like that? Apologies for the questions but I'm just trying to understand as best I can. Jan 31, 2019 at 15:47
  • 1
    No problem @Erich Purpur. All your questions above which are causing your confusion are answered by class inheritance. I you look at the API Docs for a class (I find the C++ docs are actually more helpful for this), often you will see an inheritance diagram. Many classes inherit attributes and methods from other classes. So calling .children() on a QgsLayerTree object is possible because it is an inherited method from the QgsLayerTreeNode class. Likewise, addLayer() is an inherited method from QgsLayerTreeGroup and setRootGroup() is inherited from the QgsLayerTreeModel class
    – Ben W
    Feb 1, 2019 at 0:57
  • 1
    Link to C++ Docs: qgis.org/api/annotated.html Example of class inheritance diagram: qgis.org/api/classQgsLayerTree.html Also, if you scroll down the documentation you will often see the "Additional Inherited Members" for a class.
    – Ben W
    Feb 1, 2019 at 1:01
  • Great, thanks again. I've been looking only at the python documentation. I'll be sure to reference the c++ documentation in the future. Feb 1, 2019 at 13:06

Your Answer

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

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