2

I am working on a plugin 'Stripchartdrawer' current commit https://github.com/sickel/qgisstripchart/tree/ba3afd7184e33331b5af38111e91dbb9b6a2d1c0.

One of the features in this plugin is to be able to visually select features in a layer based on the value of a field by clicking or dragging in the chart. There are two cases when this kind of selection does not work. One is if the layer does not have a unique id field, if so, I am able to give a warning.

The other case is if the layer is not activated, i.e. checked in the layer panel, I would like to give a warning in that case as well if it seems as the user tries to select data, but how can I find out if the layer is activated?

In my mousereleaseevent I am doing

self.layer.select(selectedids)

Where selectedids is one or more ids that I am to select.

What I want to achieve is something like (pseudocode:)

if self.layer.isActive():
   self.layer.select(selectedids)
else:
   self.iface.messagebar.pushmessage('Warning',(...))

But what is the real "isActive()"?

I am not 100% sure about the nomenclature here. a layer can be not visible either because it is not checked in the layer panel, if the view is outside the extent of the layer or if the layer is covered with another layer, one layer at a time can be activated, ie eg being the layer "Select features by plygon" will operate on. I want to be able to check if a layer is checked (no pun intended) and do not care if it is activated as described above.

2
  • For questions that involve code we ask that you show us where you are stuck with your own code by including a code snippet in your question.
    – PolyGeo
    Commented Nov 7, 2019 at 22:22
  • 3
    You could check if the node itself is checked using if QgsProject.instance().layerTreeRoot().findLayer(QgsProject.instance().mapLayersByName( self.layer.name() )[0].id()).isVisible():; #Do something
    – Joseph
    Commented Nov 8, 2019 at 10:58

1 Answer 1

2

The visibility status of a QGIS map layer is not stored with the map layer object itself but depends on the state in the layer tree.

You can access the layer tree via QgsProject.instance().layerTreeRoot(), then search for the corresponding element in the tree using its .findLayer() method and finally check the .isVisible() status of that element.

Note: In the layer tree there are LayerTreeLayer objects not QgsMapLayer objects nor instances of inherited classes of QgsMapLayer (such as QgsVectorLayer or QgsRasterLayer. This can be confusing because both are some kinds of "layers".

A full example:

# have a map layer (QgsMapLayer or child class), maybe like this:
layer = QgsProject.instance().mapLayersByName("world")[0]

# get access to the QgsLayerTree
layer_tree_root = QgsProject.instance().layerTreeRoot()  # QgsLayerTree

# find the layer tree layer corresponding to the map layer
layer_tree_layer = layer_tree_root.findLayer(layer_id)  # QgsLayerTreeLayer

# check the visibility status
layer_is_visible = layer_tree_layer.isVisible()

Or as a function that takes a layer and returns True or False:

def is_layer_visible(layer: QgsMapLayer):
    """Checks if the layer is currently set visible in the layer tree.
    
    >>> is_layer_visible(iface.activeLayer())
    True
    
    Args:
        layer (QgsMapLayer): The layer to check
        
    Returns:
        True if the layer is currently set visible
    """
    layer_tree_root = QgsProject.instance().layerTreeRoot()
    layer_tree_layer = layer_tree_root.findLayer(layer)
    return layer_tree_layer.isVisible()

Example usages:

is_layer_visible(iface.activeLayer())
is_layer_visible(QgsProject.instance().mapLayersByName("world")[0])

Thanks to @Joseph for posting code in a comment, I used it to write this answer.

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.