14

I have a signal setup for a feature deletion event on a layer:

self.layer.featureDeleted.connect(self.feature_deleted)

When I try and grab an attribute from the deleted feature on the slot, a StopIteration error is thrown (i.e it cannot retrieve the feature).

I would have thought I should still be able to retrieve attributes from a deleted feature before the changes to the layer are committed? Otherwise I don't see what use the fid parameter is.

def feature_deleted(self, fid):
    feature = self.layer.getFeatures(QgsFeatureRequest().setFilterFid(int(fid))).next()
    idx = self.layer.fieldNameIndex('my_attribute')
    print feature.attributes()[idx]

How can I access the attributes of a deleted feature (before the changes to the layer are committed)?

3
  • 1
    It seems that deleted features aren't stored anywhere ... except in the original version of your layer ... so ... maybe open it twice and then use the deletedFeatureIds returned by the edit buffer of the layer u're modifying ? I only found that attribute value changes or geometry changes are stored ... not deleted features (only their featureIds are...)
    – Snaileater
    Jul 31, 2015 at 17:52
  • @snaileater Copying the layer will be an expensive operation in my case. I will try and record the attributes of features as they are selected and compare them to those left once the changes are committed.
    – Matt
    Aug 2, 2015 at 19:27
  • @Matt Maybe this posting on the mailing list will help: lists.osgeo.org/pipermail/qgis-developer/2015-May/037823.html
    – eftas
    Jul 8, 2016 at 9:54

1 Answer 1

5

There would be two moments where you can still get features that are to be deleted:

  1. When you delete them in an edit session but have not committed or saved changes (i.e., you could still rollback).

    layer = iface.activeLayer()
    idx = layer.fieldNameIndex( 'my_attribute' )
    def feature_deleted( fid ):
        feature = layer.dataProvider().getFeatures( QgsFeatureRequest( fid ) ).next()
        print feature.id(), feature.attributes()[idx]
    
    layer.featureDeleted.connect( feature_deleted )
    
  2. Right before deleted features are committed (i.e., you've just clicked on the Save Layer Edits button or you've just called layer.commitChanges()).

    layer = iface.activeLayer()
    idx = layer.fieldNameIndex( 'my_attribute' )
    def features_deleted():
        if layer.editBuffer():
           ids = layer.editBuffer().deletedFeatureIds()
           for feature in layer.dataProvider().getFeatures( QgsFeatureRequest().setFilterFids( ids ) ):
               print feature.id(), feature.attributes()[idx]
    
    layer.beforeCommitChanges.connect( features_deleted )
    
1
  • This is a good solution but doesn't seem to work for postGis layers. It appears to me they handle the editing buffer fundamentally different. I get a stop iteration error even though the layer is still in edit mode. Any suggestions there? Dec 22, 2016 at 20:59

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.