4

I am following a tutorial where I am trying to learn how to use PyQGIS to programmatically accept a user's feature selection from the map canvas of QGIS by mouse click. I have encountered a problem with the following code snippet where, as I understand it 'setSelectedFeatures' is no longer an attribute for a QgsVectorLayer.

I have some other posts that suggest the current method in PyQGIS is to use 'selectByIds' but cannot work out how to set up the code to incorporate that correctly, despite looking through the documentation (pygqis documentation).

Has anyone dealt with this type of functionality and could offer some guidance?

 if len(found_features) > 0:
 layer = found_features[0].mLayer
 feature = found_features[0].mFeature
 layer.setSelectedFeatures([feature.id()])
 else:
 self.layer.removeSelection()
PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
asked Aug 11, 2020 at 12:18
0

1 Answer 1

6

You haven't specified or linked to the tutorial you are following, but I'm guessing you are doing something like my example below, sub-classing QgsMapToolIdentifyFeature.

To use the selectByIds() method you just need to pass a list of integers containing the feature id numbers you want to select. You can also pass an optional argument to set the selection behaviour (SetSelection is the default). See the documentation for the complete list of options.

You can run my example below from the Python console and get an idea of example usage.

class selectTool(QgsMapToolIdentifyFeature):
 
 def __init__(self, iface):
 self.iface = iface
 self.canvas = self.iface.mapCanvas()
 self.layer = self.iface.activeLayer()
 QgsMapToolIdentifyFeature.__init__(self, self.canvas, self.layer)
 self.iface.currentLayerChanged.connect(self.active_changed)
 
 def active_changed(self, layer):
 self.layer.removeSelection()
 if isinstance(layer, QgsVectorLayer) and layer.isSpatial():
 self.layer = layer
 self.setLayer(self.layer)
 
 def canvasPressEvent(self, event):
 found_features = self.identify(event.x(), event.y(), [self.layer], QgsMapToolIdentify.TopDownAll)
 self.layer.selectByIds([f.mFeature.id() for f in found_features], QgsVectorLayer.AddToSelection)
 
 def deactivate(self):
 self.layer.removeSelection()
 
 
t = selectTool(iface)
iface.mapCanvas().setMapTool(t)
answered Aug 12, 2020 at 5:33
4
  • Thanks for this Ben. This allows me to select features. I'll need to do a bit more work to fully understand what is going on and then extract details of those features out to, for example, a new temporary layer. Thanks Commented Aug 12, 2020 at 9:50
  • Ben, I wonder if you might know why this solution is not working for me? I posted a question about it gis.stackexchange.com/questions/432445/… Commented May 31, 2022 at 17:10
  • Nevermind, My question was answered. Commented May 31, 2022 at 17:33
  • @tbob, yes. I recommend to do some studying on object scope and ownership in pyqt. When you create an instance of a class inside another class, you need to declare it as an instance attribute to ensure the object does not go out of scope when a function returns. Commented Jun 1, 2022 at 2:03

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.