1

I'm working on a plugin for QGIS 3 and I'm fighting with the QgsFieldExpressionWidget widget.

I don't know how how to evaluate the expression added in the box and get the corresponding features as a python list.

Within the plugin I would like to write a function to call that is able to know if in the QgsFieldExpressionWidget is a simple field (without expression) or a expression that has to be evaluated.

No problem for the first part, but API changed for the QgsFieldExpression and I'm not able to follow the instruction of the pyqgis cookbook.

This is the function I'm trying to write:

 def getFields(lay, exp):

    # vector layer from the combobox
    vl = lay.currentLayer()
    # vector field (or expression)
    field = exp.currentText()

    data = []

    # get the data from the layer
    # no expression
    if not exp.currentField()[1]:
        for i in vl.getFeatures():
            data.append(i[field])

    # if expression is selected

    # this is the piece of code that is not working for QGIS 3

    else:
        # expression name
        fil = exp.currentField()[0]
        # expr = QgsExpression(fil)
        # for i in vl.getFeatures():
            # data.append(expr.evaluate(i, vl.pendingFields()))


    return data
  • Which is the returned error? – mgri May 11 '17 at 9:37
  • This is the error: TypeError: QgsExpression.evaluate(): arguments did not match any overloaded call: overload 1: too many arguments overload 2: argument 1 has unexpected type 'QgsFeature' – matteo May 11 '17 at 10:00
  • After a quick test, it seems to work using evaluate() without any argument inside. Can you confirm it? – mgri May 11 '17 at 10:57
  • I can confirm I don't have any error, but the data list is a list of None after the evaluation of the expression. BTW: exp.isValid() returns True – matteo May 11 '17 at 12:19
  • It is still unclear to me which operation you are doing. However, I reproduced your issue by creating a new field storing some simple expressions. Then, I looped over the features and used expr = QgsExpression(str(i['field_name'])) and then value = expr.evaluate() (both inside the loop) and it printed the proper result (when there was an expression in the field). Maybe you need to convert the expression to a string before passing it? – mgri May 11 '17 at 12:51
1

Perhaps try the method posted in your other question using the QgsExpressionContext and QgsExpressionContextScope classes:

def getFields(lay, exp):
    vl = lay.currentLayer()
    field = exp.currentText()

    context = QgsExpressionContext()
    scope = QgsExpressionContextScope()
    data = []

    if not exp.currentField()[1]:
        for i in vl.getFeatures():
            data.append(i[field])
    else:
        fil = exp.currentField()[0]
        for i in vl.getFeatures():
            scope.setFeature(i)
            context.appendScope(scope)
            exp = QgsExpression(fil)
            data.append(exp.evaluate(context))

    return data

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.