1

Is there an option for adding a "Layers" panel to a custom/standalone PyQGIS application (like the one available in QGIS) or do I need to construct my own using something along the lines of the QgsLayerTreeModel, QCheckBoxes and a parent QDock?

I see you can add some actions (zoom, pan, etc.) but have not found anything relating to panels.

Taras
  • 32,823
  • 4
  • 66
  • 137
user1650538
  • 373
  • 2
  • 10

1 Answers1

2

You can have a look at the example below. This example adds a QgsMapCanvas to a QMainWindow, loads a project, creates a QgsLayerTreeMapCanvasBridge and uses a QDockWidget to display a QgsLayerTreeView.

I created a simple project to show how it works. You also need to create a QgsLayerTreeModel, passing the projects layerTreeRoot() to the constructor, and set the model to the view. By setting the AllowNodeReorder and AllowNodeChangeVisibility flags on the model, allows the layers to be re-ordered by dragging and 'turned on or off'.

See gif below to see the result:

enter image description here

Full script is below (you may need to modify slightly to test e.g. obviously change the project path and layer name, and maybe the QgsApplication prefix path depending on your installation):

import sys
from qgis.core import QgsApplication, QgsProject, QgsRasterLayer, QgsLayerTreeModel
from qgis.gui import QgsMapCanvas, QgsLayerTreeMapCanvasBridge, QgsLayerTreeView
from PyQt5.QtWidgets import QApplication, QMainWindow, QDockWidget
from PyQt5.QtCore import Qt

class myWindow(QMainWindow):

def __init__(self):
    QMainWindow.__init__(self)

    self.setGeometry(250, 150, 1000, 750)
    self.canvas = QgsMapCanvas(self)
    self.setCentralWidget(self.canvas)
    self.project = QgsProject.instance()
    self.bridge = QgsLayerTreeMapCanvasBridge(self.project.layerTreeRoot(), self.canvas)
    self.bridge.setAutoSetupOnFirstLayer(False)
    self.project.read('C:\\Path\\To\\Project.qgz')
    self.layer = self.project.mapLayersByName('layer_name')[0]
    self.canvas.setExtent(self.layer.extent())
    self.canvas.zoomByFactor(1.1)
    self.canvas.refresh()

    # Section below relates to creating the 'layers panel'
    self.layers_widget = QDockWidget('Layers', self)
    self.view = QgsLayerTreeView(self.layers_widget)
    self.root = QgsProject.instance().layerTreeRoot()
    self.model = QgsLayerTreeModel(self.root)
    self.model.setFlag(QgsLayerTreeModel.AllowNodeReorder)
    self.model.setFlag(QgsLayerTreeModel.AllowNodeChangeVisibility)
    self.view.setModel(self.model)
    self.layers_widget.setWidget(self.view)
    self.addDockWidget(Qt.LeftDockWidgetArea, self.layers_widget)



def main(): app = QApplication([]) qgs = QgsApplication([], False) qgs.setPrefixPath("C:/OSGeo4W64/apps/qgis", True) qgs.initQgis()

w = myWindow()
w.show()
sys.exit(app.exec_())

if name == "main": main()

Reference: https://www.lutraconsulting.co.uk/blog/2015/01/30/qgis-layer-tree-api-part-3/

Ben W
  • 21,426
  • 3
  • 15
  • 39