1

I wish to create a field which automatically updates with the current timestamp when edits are made to a feature.

I am using QGIS 3.4 and I am testing this using a shapefile.

Following @Joseph's answer for this question I tried updating his script to work in QGIS 3.4 as per his instructions (if I followed them correctly, not guaranteed!) to this:

layer = qgis.utils.iface.activeLayer()

def update():
    field = layer.fields().lookupField('fieldName')
    e = QgsExpression( " $now " )
    e.prepare( layer.pendingFields() )
    for feat in layer.selectedFeatures():
        feat[field] = e.evaluate( feat )
        layer.updateFeature( feat )

layer.attributeValueChanged.connect(update)

However this returns the following error:

2018-11-29T11:13:00     WARNING    Traceback (most recent call last):
              File "", line 4, in update
             AttributeError: 'QgsVectorLayer' object has no attribute 'pendingFields'

What's wrong here?

Also will this work on geometry edits or only with attribute edits?

Will this also work for a SpatiaLite layer?

2

Replace pendingFields() by fields() should do the trick for your error. You may still have errors running your code in QGIS 3.X because there is no backward compatibility. You have to fix all API changes and it will works.

the pendingFields() methods has been removed in QGIS 3.X API and replaced by fields().

Also will this work on geometry edits or only with attribute edits?

To listen to geometry changes, you can connect to geometryChanged signal

Full code will be:

layer = qgis.utils.iface.activeLayer()

def update():
    field = layer.fields().lookupField('fieldName')
    e = QgsExpression( " $now " )
    for feat in layer.selectedFeatures():
        feat[field] = e.evaluate()
        layer.updateFeature( feat )

layer.attributeValueChanged.connect(update)
layer.geometryChanged.connect(update)

Will this also work for a SpatiaLite layer?

This would probably also works on SpatiaLite layers.

  • 1
    Your code works if you remove e.prepare( layer.fields() ) and change feat[field] = e.evaluate( feat ) to feat[field] = e.evaluate() – Joseph Nov 29 '18 at 11:43
  • Now when I make an edit QGIS crashes haha. Damnit. I'll keep trying. Thanks guys – TeddyTedTed Nov 29 '18 at 11:54
  • @Joseph , YoLecomte - Which versions of QGIS are ye using? I'm on 3.4.0 and it crashes when I make an edit with that script running. – TeddyTedTed Nov 29 '18 at 12:22
  • I doesn't test it for now. Will make a try later. No time for the moment... – YoLecomte Nov 29 '18 at 12:24
  • 2
    @TeddyTedTed - Also on 3.4.0 for Win7 64-bit. It works for me from the Python Console. Note that the layer needs to be editable and the field type correct (e.g. string-type) in order for the datestamp to be written successfully. This works on spatialite layers too. – Joseph Nov 29 '18 at 12:31

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.