4

I would like to create and populate a virtual field in a QGIS vector layer attribute table using a python script. I think the easiest way to do this is to create a custom expression function, and, then use this function to populate the virtual field. How do I instantiate a custom expression function from within a python script? What I have tried with Python 3 from a Python IDE is:

    from qgis.core import *

@qgsfunction(args=0, group='Custom', usesGeometry=False)
def a_function():
    return "'Test'"

QgsExpression.registerFunction(a_function)
print(QgsExpression(a_function()).evaluate())

This returns a TypeError:

print(QgsExpression(a_function()).evaluate())
TypeError: 'QgsPyExpressionFunction' object is not callable

2 Answers 2

3

The following works, but, I don't know why:

from qgis.core import *
@qgsfunction(args='auto', group='Custom', usesGeometry=False)
def a_function(feature, parent):
    return 'Test'
print(QgsExpression('a_function()').evaluate())
1
  • Custom functions need to always take a feature and parent argument, which provide access to the feature's attributes, geometry, etc. and the expression which is being evaluated (see howtoinqgis.wordpress.com/2017/05/20/… ). Then QgsExpression parses and evaluates the expression 'after' it is invoked; it accepts a string to parse and evaluate. Your original invocation without the quotes around a_function() tried to evaluate its value rather than parsing it. (The @qgs decorator also modifies the definition)
    – Houska
    Feb 13, 2020 at 15:34
-1

Try this

from qgis.core import *

@qgsfunction(args=0, group='Custom', usesGeometry=False)
def a_function():

    QgsExpression.registerFunction(a_function)
    print(QgsExpression(a_function()).evaluate())
    return "'Test'"
1
  • I would like to call the function in an expression. In my example, the output of print(QgsExpression(a_function()).evaluate()) should be the string 'Test'. . In your provided answer the statement print(QgsExpression(a_function()).evaluate()) does not return anything. Jun 3, 2019 at 10:30

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.