[GIS] Adding dynamic text feedback for QGIS plugin

pyqgisqgis-plugins

I am building a plugin using Qt Designer which will initially allow users to select features for a chosen polygon layer and then when a feature is selected on the canvas, the area is printed out in some sort of display widget.

For comparison, the Coordinate Capture tool (shown on the left in the image below) allows users to select on canvas and then print the coordinates in the boxes shown.

Plugins

How could I connect selecting features on canvas to displaying the area in the text browser?


I am using the following guides for reference:


The following is what I have in code so far. If I move the code from print_area() to run(), I can print the total area in the text browser. But can't seem to connect it correctly so that whenever a layer is chosen from the combo box, the text browser get's updated.

def run(self):
    layers = self.iface.legendInterface().layers()
    layer_list = []
    for layer in layers:
        self.dockwidget.comboBox.clear()
        self.dockwidget.show()
        layer_list.append(layer.name())
        self.dockwidget.comboBox.addItems(layer_list)
        selectedLayerIndex = self.dockwidget.comboBox.currentIndex()
        selectedLayer = layers[selectedLayerIndex]

def print_area(self):
    for feat in selectedLayer.getFeatures():
        geom = feat.geometry()
        self.dockwidget.textBrowser.setText(str(geom.area()))

    selectedLayerIndex.selectionChanged.connect(run)

Best Answer

I would use a Line Edit widget.

Inside your run() function put something like:

self.selectedLayer = self.iface.activeLayer() # Adjust this to your situation
self.selectedLayer.selectionChanged.connect( self.printSelectedArea )

Then define your printSelectedArea function:

def printSelectedArea( self ):
  area=0
  for f in self.selectedLayer.selectedFeatures(): 
    area += f.geometry().area()
  self.dockwidget.txtArea.setText( str( area ) )

Note that this will print the selected area of your currently selected layer. You would need to adjust the code if you want to add areas across layers, which I didn't see from your question.

When a user chooses a layer in your comboBox you should disconnect the printSelectedArea slot from the previous selected layer and connect it to the new one. You could also disconnect the printSelectedArea slot from any SIGNAL when your plugin is closed or unload. Otherwise, you would end up messing printSelectedArea calls up.

Additionally, you would need to add conditionals to make sure there is a selectedLayer before calling selectedFeatures().