4

I try to write a Python script with PyQGIS to update automatically a field when a feature is added or when a geometry is changed. It's work well with the geometryChanged listener but not with the featureAdded listener : For a new feature the QgsFeatureId is negative before a commit (-2 for example) and it seems that changeAttribute does not like that :

Layer point: Feature -2 for attribute update not found.

How can I update a field automatically before a commit?

Here is my code :

#### variables ####
layerName = "point"
fieldName = "test"
## create layer object
layer = (QgsMapLayerRegistry.instance().mapLayersByName(layerName))[0]
## function updateField
def updateField(QgsFeatureId):
 field = layer.fieldNameIndex(fieldName)
 layer.dataProvider().changeAttributeValues({QgsFeatureId:{field:"updateTest"}})
 
## listeners
layer.geometryChanged.connect(updateField)
layer.featureAdded.connect(updateField)

I work with QGIS 2.14.4

Kadir Şahbaz
78.6k57 gold badges260 silver badges407 bronze badges
asked Jul 20, 2017 at 12:28
3
  • By the way, unless you definitely need to implement this by yourself in a script, you could use the AutoFields plugin, which handles automatic vector field updates for you. Commented Jul 21, 2017 at 12:04
  • Thanks, I tested your plugin, it works well but the attributes are not updated until you commit your edit change. Commented Jul 24, 2017 at 13:43
  • Right, they're not saved until you save. That something we could adjust for a next version. :) Commented Jul 24, 2017 at 14:09

1 Answer 1

4

Have a look at this post about listening to featureAdded in a safe way.

In your case, this should work:

layerName = "point1"
fieldName = "test"
addedFeatures = []
layer = (QgsMapLayerRegistry.instance().mapLayersByName(layerName))[0]
field = layer.fieldNameIndex(fieldName) 
def storeFeaturesIds(featId):
 addedFeatures.append(featId)
def updateAttributesAfterAdding():
 while addedFeatures:
 featureId = addedFeatures.pop()
 layer.beginEditCommand('Updating test field')
 layer.changeAttributeValue(featureId, field, "updateTest")
 layer.endEditCommand()
layer.featureAdded.connect(storeFeaturesIds)
layer.editCommandEnded.connect(updateAttributesAfterAdding)
answered Jul 20, 2017 at 16:59

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.