5

My PyQGIS script creates a number of layers, including one with a Graduated symbol renderer "DE Single", which splits my line symbols into 8 ranges e.g. -150 to -105.

I have PyQGIS code to access the "DE Single" layer and make it visible or invisible (checked/unchecked), but I cant work out how to write the PyQGIS to check/uncheck each of the ranges individually.

"DE Single" is constructed by the deSingle object and the constructed layer is called layer line.

With the PyQGIS as follows:

layer = root.findLayer(deSingle.layerLine.id())    
layer.setItemVisibilityChecked(False)

I can select the group node of all the 8 ranges, but I can't work out how to get to each of the children, e.g. only uncheck the range layer -75 to -70 etc.

Table Of Contents - Tree

If I add the code:

layer = QgsProject.instance().mapLayersByName('DE Single')[0]

ranges_to_uncheck = ['-75 to -70',
                    '-95 to -85'] # Add more ranges as you like

tree_view = iface.layerTreeView()

model = tree_view.layerTreeModel()

layer_tree_layer = model.rootGroup().findLayer(layer.id())

# If the code in your question was working you could try this..
#layer_tree_layer = model.rootGroup().findLayer(deSingle.layerLine.id()) 

nodes = model.layerLegendNodes(layer_tree_layer)

for n in nodes:
    if n.data(Qt.DisplayRole) in ranges_to_uncheck:
        # Set unchecked
        n.setData(0, Qt.CheckStateRole)
        # To set checked...
        #n.setData(2, Qt.CheckStateRole)

I get:

IndexError: list index out of range on the first line...

on the:

layer = QgsProject.instance().mapLayersByName('DE Single')[0]

So if I replace the find with:

root = QgsProject.instance().layerTreeRoot()
layer = root.findLayer(deSingle.layerLine.id()) 

and now the code addition becomes:

root = QgsProject.instance().layerTreeRoot()
layer = root.findLayer(deSingle.layerLine.id())   

ranges_to_uncheck = ['-75 to -70',
                    '-95 to -85'] # Add more ranges as you like

tree_view = iface.layerTreeView()

model = tree_view.layerTreeModel()

layer_tree_layer = model.rootGroup().findLayer(layer.id())

# If the code in your question was working you could try this..
#layer_tree_layer = model.rootGroup().findLayer(deSingle.layerLine.id()) 

nodes = model.layerLegendNodes(layer_tree_layer)

for n in nodes:
    if n.data(Qt.DisplayRole) in ranges_to_uncheck:
        # Set unchecked
        n.setData(0, Qt.CheckStateRole)
        # To set checked...
        #n.setData(2, Qt.CheckStateRole)

on the:

layer_tree_layer = model.rootGroup().findLayer(layer.id())

line I get:

AttributeError: 'QgsLayerTreeLayer' object has no attribute 'id'

any ideas please?

2
  • I have updated my answer. The commented line in my answer was meant as the alternative way to get your QgsLayerTreeLayer object.
    – Ben W
    Commented Nov 22, 2022 at 4:06
  • Hey thank you so much , this worked perfectly. I had no idea that this is how the API works. Its not obviously in the cookbook? unless I missed something. The ranges, are not really child layers as I thought?. I have updated my class that creates the graduated renderer to include some methods to take an index and created the range labels needed. Awesome thanks again!.
    – paulQGIS
    Commented Nov 23, 2022 at 0:45

1 Answer 1

5

The snippet below should work:

ranges_to_uncheck = ['-75 to -70',
                    '-95 to -85'] # Add more ranges as you like

tree_view = iface.layerTreeView()

model = tree_view.layerTreeModel()

layer_tree_layer = model.rootGroup().findLayer(deSingle.layerLine.id()) 

nodes = model.layerLegendNodes(layer_tree_layer)

for n in nodes:
    if n.data(Qt.DisplayRole) in ranges_to_uncheck:
        # Set unchecked
        n.setData(0, Qt.CheckStateRole)
        # To set checked...
        #n.setData(2, Qt.CheckStateRole)

Example:

enter image description here

1
  • Thanks for the suggestion.
    – paulQGIS
    Commented Nov 22, 2022 at 1:39

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.