I'm using QGIS 3.2. I have 4 fields ("kk1"-"kk4") where at least one of the fields contains a number (real). I want to calculate the mean of these 1-4 fields and save the result (the average) in another field called "mkviskrans". I calculate the average (based on this answer) of these 1-4 fields using this function in the Function Editor window in the Layer Properties:
@qgsfunction(args=-1, group='Custom') def mean_col(cols, feature, parent): vals = [feature[i] for i in cols if feature[i] is not None] return sum(vals)/float(len(vals))
and calling the function from the Expression window in the widget's Default value option in Layer Properties:
UPDATE: I tried
return 2.3instead of
return sum(vals)/float(len(vals)). In this case the attribute table is updated automatically with the value 2.3. This indicates that the values typed in by the user in "kk1"-"kk4" actually have to be updated/evaluated/"commited" before returning the mean value, i.e.the division-expression will always return "None"? I have tried to update the feature/field values of "kk1"-"kk4" before return, but without any luck so far.
However, the mean value does not automatically appear in the "mkviskrans" "Text Edit" widget (alias "Midlere kvistkransavstand (dm)"): Nor in the attribute table: When I click in a cell in the attribute table, then the mean value appears: Is it possible to get/show/save the value "on the fly"? I have tried different variants of update and/or commit within the function:
@qgsfunction(args=-1, group='Custom') def mean_col(cols, feature, parent): layer = qgis.utils.iface.activeLayer() fieldIndex = layer.fields().indexFromName( 'mkviskrans' ) vals = [feature[i] for i in cols if feature[i] is not None] """return sum(vals)/float(len(vals))""" mv = sum(vals)/float(len(vals)) layer.changeAttributeValue(feature.id(), fieldIndex, mv) layer.commitChanges()
If I save the edits without clicking in a cell in the attribute table, the average (the field "mkvistkrans") will not contain any mean values.
(I may of course calculate the mean values after the field work, but I want the user to see the mean value "on the fly" - if possible.)