1

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)
  • 1
    I don't have a full answer, but the connection (between feature selection and area display) would be done using a Python signal. See there for a specific example and there for general info about PyQt signals. – ArMoraer Apr 11 '16 at 15:07
  • @ArMoraer - Thank you for the links, they look interesting! Will give them a thorough read :) – Joseph Apr 11 '16 at 15:09
3

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().

  • Thanks, will give this a go! Can I ask why choose a line edit instead of a text browser? – Joseph Apr 12 '16 at 14:12
  • 2
    Mainly because QTextBrowser is best suited for hypertext. For instance, you could print Internet links there and the user could interact and click on them. In this case you just need to print a 'raw' text line, which is what the QLineEdit is for. It's just about using the minimal widget that fulfils your requirement. A QTextBrowser would give much more than you need in this particular use case. – Germán Carrillo Apr 12 '16 at 14:24
  • 1
    Good to know, many thanks! Will see how far I get with this ;) – Joseph Apr 12 '16 at 14:27
  • Sorry but just a minor follow-up question: to disconnect the printSelectedArea slot, could I use something likeself.selectedLayer.selectionChanged.disconnect( self.selectedLayer, self.printSelectedArea )? – Joseph Apr 12 '16 at 15:22
  • 1
    You could use: self.selectedLayer.selectionChanged.disconnect(), which will disconnect any slot connected to that signal, or just pass the slot as argument: self.selectedLayer.selectionChanged.disconnect( printSelectedArea ). Non-selected layers should have no connections. – Germán Carrillo Apr 12 '16 at 15:34
1

If you select some features from map canvas, the following signal is emitted: selectionChanged

So you just need to create function which calculate area and connect it to this signal.

  • Thanks, I will take a look at this signal and see how I get on! – Joseph Apr 12 '16 at 8:47

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.