9

I'm using pyqgis within an standalone application. Now I wanted to create a custom expression to to use as filterExpression in rule of ruleBasedRendererV2. (I tried the renderer with existing functions before and everything worked fine!)

Custom qgisfunction (bitwise AND-function - as there is not such a function yet) looks like this:

from qgis.utils import qgsfunction

@qgsfunction(args="auto", group='Python')
def bitwise_and(value1, value2, feature, parent):
    return value1 & value2

I also tried to register it, via:

from qgis.core import QgsExpression
QgsExpression.registerFunction(bitwise_and) 

Testing the expression via:

expressionString = 'bitwise_and(2, 2) = 2'
exp = QgsExpression(expressionString)
if exp.hasParserError():
    print(exp.parserErrorString())

(Giving 2=2 so always True) works after registering function, and fails if not. But still, I can not use the expression within a rule...

Right now, the file containing the function lies on top in my project folder, which is automatically included to PATH, isn't it?! (According to Nathan Woodrow, file can be placed anywhere in PATH - see https://nathanw.net/2012/11/10/user-defined-expression-functions-for-qgis/).

UPDATE: Registering of function works so far, with code from above - now the problem lies in function itself...

UPDATE #2:

Very strange! Simple function do_nothing getting two arguments works fine in my code:

@qgsfunction(args="auto", group='Python')
def do_nothing(value1, value2, feature, parent):
    return value1

Using expression expString = 'do_nothing(2, 2) = 2'

UPDATE #3:

Simple change of do_nothing to add_one does not work any longer:

@qgsfunction(args="auto", group='Python')
def add_one(value1, value2, feature, parent):
    return value1 + 1

calling it via expString = 'add_one(2, 2) = 3'. That's why I think it has something to do with returning type?!

  • 1
    Copy your file in ~/.qgis2/python/expressions/ then reload QGIS and the function is available in the expression builder section python – ThomasG77 Jun 3 '16 at 1:57
  • Following your advice, function appears in QGIS function editor and I can use it as expected. But when trying to use it in my standalone application, function does not work! - I think, when QGIS starts, it somehow registers all files in expression folder, but I wonder how?! – Henhuy Jun 3 '16 at 7:12
  • Are you using the @qgsfunction function in your code, as in you define the function in code. You can can ignore the expressions folder if you are making your own script that is just for the main app – Nathan W Jun 3 '16 at 10:44
  • You are right - when registering of the function works as described above (for example do_nothing). But my original function bitwise_and does still not work. Now, I think it has something to do with the return type of the function, since do_nothing works, but add_one does not! – Henhuy Jun 4 '16 at 11:16
7

I finally solved the problem!

It was really a type-problem, as input values are defined as QVariant inside @qgsfunction. So, to get my code work I had to convert them into integers first. Apparently, QGIS takes care of type conversions itself...

Function looks like this now:

@qgsfunction(args="auto", group='Python')
def bitwise_and(value1, value2, feature, parent):
    return value1.toInt()[0] & value2.toInt()[0]

And if you have the function placed in your project folder, don't forget to register it first:

from qgis.core import QgsExpression
QgsExpression.registerFunction(bitwise_and) 

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.