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

1 Answer 1

5

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)
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
    – TrevP
    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/…
    – tbob
    Commented May 31, 2022 at 17:10
  • Nevermind, My question was answered.
    – tbob
    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.
    – Ben W
    Commented Jun 1, 2022 at 2:03

Your Answer

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

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