6

I would like to change the background-color (or font color) of some items in the TOC of QGIS:

Example-Mockup:

enter image description here

I tried several ways but nothing did the trick so far:

layer_list = QgsProject.instance().layerTreeRoot().children() 
for lyr in layer_list:        
    if isinstance(lyr, QgsLayerTreeGroup):
        lyr.setProperty("background-color","red")
        #lyr.setBackgroundColor(0, QtGui.QColor('green'))
        #lyr.setStyleSheet("background-color: green;")


    elif isinstance(lyr,QgsLayerTreeLayer):
        if lyr.name()=='Verteiler':
            lyr.setProperty("background-color","red")
            #lyr.setBackgroundColor(0, QtGui.QColor('green'))
            #lyr.setStyleSheet("background-color: green;")

I can't use a generic stylesheet like the ones used in the UI-themes, as the background-color should only be changed for some of my layers.

Is this possible?

edit1:

I found one way to change the style of layertree-items in general:

from PyQt4.QtGui import QApplication
QApplication.instance().setStyleSheet("QTreeView::item {color:green;}" );

Perhaps it would be possible to assign custom properties to some items of the TOC to be able to style only the wanted items.

  • The bounty reason is "Canonical answer required" – markgraeflerland Oct 2 '18 at 6:38
1
+100

Sorry to say this is almost impossible.

The way Qt supports conditional styling with stylesheets is by using QObject::setObjectName (see doc) which you cannot do on a tree view item.

Your code does not work because layer tree nodes are not GUI items (more over, this would be cancelled any time the legend view is refreshed, which happen very often).

The Qt docs describes how customizing tree views with CSS but it cannot be layer-specific as you require.

There would be only 2 options, as far as I see:

  1. Code that possibility in QGIS core by creating a new custom property on layer tree node (could be called background-color) and would be used for painting the color (in the QgsLayerTreeModel::data)

  2. Replace the model of the layer tree view with your own customized model. You'd have to inherit the core model (QgisApp return a non-const pointer to the layer tree view) and reimplement data (which is not virtual, so I am not 100% sure it would work). That road is very risky and sounds much more like a hack and I would discourage any plugin to follow that road as it might end to bad user experience in QGIS.

Option 1 would definitely be the way to go, but that means adding this in QGIS core (need to be accepted, you'd have to wait for next release for which new features are accepted: QGIS 3.6 in roughly 5 months).


Another approach would be to use layer indicators. You can add them on the layer tree using

qgis.utils.iface.layerTreeView().addIndicator(node, indicator) 

See the docs of Python API for QgsVectorLayerTree and QgsVectorLayerTreeIndicator

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.