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)
2
  • 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, 2016 at 15:07
  • @ArMoraer - Thank you for the links, they look interesting! Will give them a thorough read :)
    – Joseph
    Apr 11, 2016 at 15:09

2 Answers 2

4

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

5
  • Thanks, will give this a go! Can I ask why choose a line edit instead of a text browser?
    – Joseph
    Apr 12, 2016 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. Apr 12, 2016 at 14:24
  • 1
    Good to know, many thanks! Will see how far I get with this ;)
    – Joseph
    Apr 12, 2016 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, 2016 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. Apr 12, 2016 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.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.