2

I have a line shapefile in QGIS with several columns and the values for many of those columns could be automatically calculated and updated depending on certain other fiels.

Now, I came across the default value option in the layer properties and I tried to build a Python function that automatically generates the value, but for some reason I do not manage to automatically get the value from the field that will serve as the argument for the function.

So, after saving the function, I try the expression

defaultPrice("Type")

I just get an error, although this is how I would usually apply functions when I manually update a field (like lower("Type") or whatever).

So, I have the field "Type" which has the values Gardentrench, Asphalt, Brick Pavement, As Built, HDD, Crossing and Grass. I have another field "PricePerMe" where I assign the cost of the "Type" per Meter. Not even calculated, just the price per one meter.

This is the code that I wrote:

from qgis.core import *
from qgis.gui import *

@qgsfunction(args='auto', group='Custom')
def defaultPrice(Type, feature, parent):
    if Type == 'Gardentrench':
        price =  12.5
    elif Type == 'Grass':
        price =  15
    elif Type == 'As Built':
        price = 1
    elif Type == 'Asphalt':
        price =  30
    elif Type == 'Brick Pavement':
        price =  100
    elif Type == 'HDD':
        price =  250
    elif Type == 'Crossing':
        price =  90
    else:
        price = 0
    return price

In the expression field, I would like to trigger this function by

defaultPrice("Type")

and update this value. In the attribute table when I update a field value or values of a column, it does display me down a correct preview value, but after running it, there are no changes in the "Type" column:

enter image description here

In the default value expression editor I get this:

enter image description here

What am I doing wrong?

Looked at some examples that I found, but couldn't really apply any of them to my problem, although I am sure it's very trivial.

Edit: Quick note: I know how to use virtual fields and that would do also, but they are not saved in the shapefile, only in the project file and I would like to learn something new.

1
  • Field name might be type instead of Type.
    – Noura
    Mar 15, 2020 at 10:57

1 Answer 1

1

Your code runs fine here. Columns must be in double quoting like you do.

You must use the Field Calculator not the Expression editor for updating you table.

enter image description here

Your way of doing it is fine, if your just playing around. A problem like this should be based on table relations and not Python, where you have a separate table for the prices. A lot easier to maintain and keep prices updated, by your or a auto process.

BTW my type column is made and written in small letters, since I used to using PostgreSQL.

Update

In regard to your comment: The expression function does not run as a default value. If you look in Fields and Values it just says NULL when the Expression editor is opened from the Default value UI. I believe this is an error in QGIS.

But you should use a virtual field instead anyways. If you save a default style for your layer QGIS will regenerate the virtual field for you, when you open the table. It is dangerous using Default values since things (prices) could change. I never use Default values only virtual fields, actually I don't use any of it since it is possibly within relational databases also.

3
  • So there is no way to automatically make QGIS update that Price Field except with a Virtual Field? I was hoping to use this Default Value feature :)
    – Kai
    Mar 16, 2020 at 11:58
  • Made an update to answer.
    – Jakob
    Mar 16, 2020 at 12:45
  • Too bad but good to know. In the course of this issue I at least got to know the Python function feature that I never used before :D Using the virtual layer is certainly no problem, I just wanted something "more fixed" or "engraved" in the shapefile. And something that does that automatically :)
    – Kai
    Mar 16, 2020 at 12:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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