I have a routine to create a layer with 6 categories (see 1st graph) based on the values of the attributes. Is there a way I can hide the categories (see the 2nd graph) using Python code? enter image description here

def mapRange(layerName, fieldName):

    layerCat = QgsProject.instance().mapLayersByName(layerName)[0]

    values = (
    ('0.0-0.2', 0.0, 0.2, 'red'),
    ('0.2-0.4', 0.2, 0.4, 'orange'),
    ('0.4-0.6', 0.4, 0.6, 'yellow'),
    ('0.6-0.8', 0.6, 0.8, 'green'),
    ('0.8-1.0', 0.8, 1.0, 'blue'),
    ('Dry', -9999, -0.001, 'gray'))

    # create a category for each item in values
    ranges = []
    for label, lower, upper, color in values:
        symbol = QgsSymbol.defaultSymbol(layerCat.geometryType())
        layer_style = {}
        layer_style['color'] = color
        layer_style['color_border'] = color
        symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style)
        if symbol_layer is not None:
            symbol.changeSymbolLayer(0, symbol_layer)

        rng = QgsRendererRange(lower, upper, symbol, label)

    #create the renderer and assign it to a layer
    renderer = QgsGraduatedSymbolRenderer(fieldName, ranges)
  • So you want to programmatically collapse the legend in the table of contents? – alphabetasoup Jul 18 '19 at 0:10
  • Yes. I have many of these layers created in each simulation run, and just want to open the legend of the layer of interest. – RRCH Jul 18 '19 at 3:11

Here is a minimal example of how to access layer tree objects such as QgsLayerTreeLayer or QgsLayerTreeGroup. These inherit the method setExpanded() from the QgsLayerTreeNode base class. So you can do the following:

layer_name = 'Name_of_your_layer'
p = QgsProject().instance()
r = p.layerTreeRoot()
c = r.children()
ll = [l for l in c if l.name() == layer_name][0]
ll.setExpanded(False) #Pass boolean value (True or False) to expand or collapse legend nodes

You can also use the isExpanded() method to check if layer tree items are already expanded or not. In this way, you could collapse all items like:

for l in c:
    if l.isExpanded():

And expand all:

for l in c:
    if not l.isExpanded():

Thanks, Ben. Your answer really helps. I modified your code a little because the layers of interest are under a group.

from qgis.core import QgsLayerTreeLayer, QgsLayerTreeGroup
group_name = "simResultsGroup"
layer_name = "simResults"
p = QgsProject().instance()
r = p.layerTreeRoot()
c = r.children()

for l in c:
    if l.name() == group_name:
        for aLayer in l.findLayers():
            if aLayer.isExpanded():

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.