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()
1 Answer 1
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)
-
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. ThanksTrevP– TrevP2020年08月12日 09:50:17 +00:00Commented 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– tbob2022年05月31日 17:10:20 +00:00Commented May 31, 2022 at 17:10
-
Nevermind, My question was answered.tbob– tbob2022年05月31日 17:33:30 +00:00Commented 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– Ben W2022年06月01日 02:03:32 +00:00Commented Jun 1, 2022 at 2:03