Created
February 10, 2021 15:40
-
-
Save jdlom/5b9709a70503e359d9143ff03adf14c7 to your computer and use it in GitHub Desktop.
Gist created by PyQGIS Console
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
POC from https://gis.stackexchange.com/questions/385525/qgis-how-to-invert-the-values-in-a-layout-legend/386746?noredirect=1#comment633627_386746 | |
Based on Ben W answer | |
Does not work for every legend | |
""" | |
class InvertStyleConfigWidget(QgsMapLayerConfigWidget): | |
""" | |
Emulates the QGS Layer Property Dialogs "Information" page | |
""" | |
def __init__(self, layer: QgsMapLayer, canvas: QgsMapCanvas, parent=None): | |
super().__init__(layer, canvas, parent=parent) | |
self.setLayout(QVBoxLayout()) | |
self.invertButton : QPushButton = QPushButton('Invert legend') | |
self.layer = layer | |
self.layout().addWidget(self.invertButton) | |
self.layout().setAlignment(Qt.AlignTop) | |
self.invertButton.clicked.connect(self.invert_legend) | |
def invert_legend(self): | |
root = QgsProject.instance().layerTreeRoot() | |
model = QgsLegendModel(root) | |
layer_node=root.findLayer( self.layer.id()) | |
view_model = iface.layerTreeView().layerTreeModel() | |
order_property = layer_node.customProperty('legend/node-order') | |
if order_property: | |
current_order = [ int(i) for i in order_property.split(',')] | |
else: | |
current_order = [ int(i) for i in range(model.legendRootRowCount(layer_node))] | |
QgsMapLayerLegendUtils.setLegendNodeOrder(layer_node, current_order[::-1]) | |
view_model.refreshLayerLegend(layer_node) | |
def shouldTriggerLayerRepaint(self): | |
return False | |
def apply(self): | |
pass | |
class InvertStyleConfigWidgetFactory(QgsMapLayerConfigWidgetFactory): | |
def __init__(self, title='Invert Legend', icon=QIcon(':images/themes/default/mActionSharingImport.svg')): | |
super(InvertStyleConfigWidgetFactory, self).__init__(title, icon) | |
self.setSupportLayerPropertiesDialog(True) | |
self.setSupportsStyleDock(True) | |
def createWidget(self, layer, canvas, dockWidget=False, parent=None): | |
return InvertStyleConfigWidget(layer, canvas, parent=parent) | |
def supportLayerPropertiesDialog(self): | |
"""For some reasons it does not work with raster layer""" | |
return True | |
def supportsStyleDock(self): | |
return True | |
def supportsLayer(self, layer): | |
return True | |
#iface.unregisterMapLayerConfigWidgetFactory(factory) | |
factory = InvertStyleConfigWidgetFactory() | |
iface.registerMapLayerConfigWidgetFactory(factory) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi @jdlom,
Just letting you know that I have discovered an annoying issue which is apparently caused by setting a legend node order on a QgsLayerTreeLayer in the main layer tree view. After setting a new node order on a layer with e.g. 5 nodes, if you then go back into the symbology dialog and increase the number of classes and apply the new render settings, only 5 nodes are shown in the legend! One must either manually run: QgsMapLayerLegendUtils.setLegendNodeOrder(layer_node, ...) and pass an order list which contains the new number of nodes or remove and reload the layer. I have searched but not yet found a simple solution. It seems that in the source code, this method is only used on layout legends. For the time being, I have removed the part in my stack exchange answer about updating the TOC.
Regards