7

I am developing a standalone PyQGIS application.

The map display (canvas) does not pose any problems, but I do not know how to add a legend (layer tree) to the application. Do you have any pointers or recommended resource?

Germán Carrillo
  • 36,307
  • 5
  • 123
  • 178
BenMed
  • 109
  • 1
  • 4
  • What do you intend to do? Display a legend (i.e., symbology for all map layers), be able to alter layer status (e.g., set visibility, set layer order, and so on), or both? – Germán Carrillo Apr 06 '15 at 13:18
  • Here's what to do my application After analysis and processing, it must display a map with graduated symbols (5 classes). it must also display the legend (value of classes).

    I can view the map with graduated symbols on a canvas, but I still can not find how to add the legend.

    If there is a code example that can help me, thank you

    – BenMed Apr 06 '15 at 13:47

2 Answers2

11

To complement Luigi's answer, this is how you can use the Layer Tree View for adding a legend (also known as Table of Contents or ToC) to your application.

After you create your canvas in your standalone PyQGIS application, you need to create a QgsLayerTreeView. For that, you need a model, and for the model you need the layer tree root. Additionally, you need to use a QgsLayerTreeMapCanvasBridge to keep both map and tree in sync. All this is done with the following code snippet (taken from this Martin Dobias' post):

self.root = QgsProject.instance().layerTreeRoot()
self.bridge = QgsLayerTreeMapCanvasBridge(self.root, self.canvas)
self.model = QgsLayerTreeModel(self.root)
self.model.setFlag(QgsLayerTreeModel.AllowNodeReorder)
self.model.setFlag(QgsLayerTreeModel.AllowNodeRename)
self.model.setFlag(QgsLayerTreeModel.AllowNodeChangeVisibility)
self.model.setFlag(QgsLayerTreeModel.ShowLegend)
self.view = QgsLayerTreeView()
self.view.setModel(self.model)

Now, you might want to embed the view into a dock widget inside your application. To do so, you can write the following code right below the previous code:

self.LegendDock = QDockWidget( "Layers", self )
self.LegendDock.setObjectName( "layers" )
self.LegendDock.setAllowedAreas( Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea )
self.LegendDock.setWidget( self.view )
self.LegendDock.setContentsMargins ( 9, 9, 9, 9 )
self.addDockWidget( Qt.LeftDockWidgetArea, self.LegendDock )

When you run your application and load layers or alter any layer symbology, you should see changes reflected in your dock widget, this way:

enter image description here

I followed @kelly-thomas's first example from How to apply a graduated renderer in PyQGIS? for graduated symbols on Natural Earth Data.

Besides displaying your layers' symbology, the Layer Tree View allows you to rename layers, set layer visibility, and change layer order in the map canvas.


Note: Make sure you import the required modules from qgis.gui, qgis.PyQt.QtCore, and qgis.PyQt.QtWidgets (or simply do from xxxx import * for all three).

Germán Carrillo
  • 36,307
  • 5
  • 123
  • 178
  • I have successfully added the legend in my standalone Application. Thanks! – BenMed Apr 07 '15 at 09:47
  • That's great! You're welcome. – Germán Carrillo Apr 07 '15 at 12:15
  • 1
    I was going to answer this the other day then I though 'nah @gcarrillo will get it :P' – Nathan W Apr 08 '15 at 04:54
  • I strongly suggest to create styling in a different way: A) The simplest way, if you don't need to load layers or legend dinamically follow http://kartoza.com/how-to-load-a-qgis-project-in-python/ B) or create a style in QGIS Desctop on a similar layer and apply it using the method QgsVectorLayer.loadNamedStyle(...) – Luigi Pirelli Apr 08 '15 at 08:56
  • I think that it is a good idea to separate both approaches for more clarity. In the second approach, is it possible to create dynamically "a style" directly in the application ? – BenMed Apr 08 '15 at 09:50
  • @LuigiPirelli It would depend on the use case Luigi. The best part is that all options are now supported with this Layer Tree! – Germán Carrillo Apr 08 '15 at 12:03
  • @BenMed dynamically if you have sets of qml styles prepared to apply, or a base complex style, applied and then modified basing on some local parameters. – Luigi Pirelli Apr 08 '15 at 20:04
1

Follow this guide Lutra consulting qgis-layer-tree-api-part-3

Fezter
  • 21,867
  • 11
  • 68
  • 123
Luigi Pirelli
  • 2,013
  • 14
  • 19