1

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 le featureAdded listener : For a new feature the QgsFeatureId is negativ 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

  • 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. – Germán Carrillo Jul 21 '17 at 12:04
  • Thanks, I tested your plugin, it works well but the attributes are not updated until you commit your edit change. – Maxime Bescu Jul 24 '17 at 13:43
  • Right, they're not saved until you save. That something we could adjust for a next version. :) – Germán Carrillo Jul 24 '17 at 14:09
0

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)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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