[QGIS-Developer] Changing attributes of a newly created feature in Python form init code

Johannes Kröger (WhereGroup) johannes.kroeger at wheregroup.com
Fri Jan 12 05:04:18 PST 2024


It kinda was...

I have custom widgets on another tab of the form for letting the user 
set up some things and I calculate values for attributes from that. So 
it is not solvable with default values. Very good idea though, I wish it 
would have been such an easy solution :))

When I posted also did not realise that it is not just about newly added 
features but different for:

a) A newly added feature
b) A feature was added but not yet committed to the data source
c) An existing feature

In the end I solved it by looking at the feature ID differently:

```
     feature_id = feature.id()
     if feature_id == -9223372036854775808:
         # this feature was newly added in this "form session"
         edit_buffer = layer.editBuffer()
         added_feats = edit_buffer.addedFeatures()
         # get the id of the most recently added feature in the edit buffer
         feature_id = min(list(added_feats.keys()))
     # otherwise we are looking at an existing feature, committed or not
     ... # layer.changeAttributeValue(feature_id, ...)
```

This works fine even if multiple forms are opened at the same time and 
OK is pressed on them in a random order.

I wonder if there is a named constant(?) or enum for that 
-9223372036854775808 (-2**63) somewhere. It is used by any new feature 
at that point in time.
https://github.com/qgis/QGIS/blob/a3413a9a9365fbd52ba6b0e2a6b9e55acc634cd4/tests/src/python/test_qgsvectorlayereditbuffer.py#L470 
says "ID is NULL (-9223372036854775808)" but I bet there is a better way 
in PyQt of saying "minimal INT64 value" instead of pasting the full 
value into the code like I did?

Many thanks to Stefanos and Frank for their thoughts!
I had cross-posted to 
https://gis.stackexchange.com/questions/474014/changing-attributes-of-a-newly-created-feature-in-python-form-init-code 
and the user Matt gave me pointers into the right direction.

Feels super ugly and probably not the intended way to do this kind of 
thing but WORKSFORME, done ;)

Cheers, Hannes

On 10.01.24 21:06, Stefanos Natsis via QGIS-Developer wrote:
> Hi Hannes
>
> This looks like an XY problem case!
>
> If your actual goal is to:
> > Any pointers on how to properly update a new feature's attribute 
> fields,
> > that exist on a layer but are not shown the user with the QGIS' widgets
> > in the attribute form?
>
> then you simply need to set a Default Value for the field widget but 
> not add it to the drag and drop form designer. :)
>
> If you really want to do this using form init code, you cannot do it 
> using the form's feature object as it is actually copied 
> by QgsAttributeForm before being saved to the layer.
> You could connect to QgsAttributeForm::featureSaved() signal instead, 
> that emits the actual feature, but apparently the my_form_open 
> function is called twice: once when the form is loaded and once after 
> OK is clicked (bug??), so that would create the connection twice!
> To avoid this you could connect to QgsAttributeForm::featureSaved() 
> only after OK is clicked!
>
> Best
> Stefanos
>


More information about the QGIS-Developer mailing list