14

I have written a custom function in the field calculator in QGIS. How do I distribute this function to other QGIS installations the best way? I can of course instruct the user what to type or copy / paste in, but that feels kind of kludgy.

Is there any way to distribute a custom function like a, or together with or as a part of a plugin? The latter would be great as the function is to be used together with a plugin I am writing.

3 Answers 3

17

You can ship them in your plugin.

Create a Python file called, for example, qgis_expression.py:

from qgis.utils import qgsfunction

@qgsfunction(
    args='auto', group='Your group', usesGeometry=False, referencedColumns=[], helpText='Define the help string here')
def your_expression(params, feature, parent):
    # UPDATE the qgsfunction above
    # ADD HERE THE EXPRESSION CODE THAT YOU WROTE IN QGIS.
    return 'your_result'

In the entry point of your plugin, in the file containing initGui and unload:

# Simply import the function, the decorator qgsfunction will register it in QGIS.
from qgis.core import QgsExpression
from .qgis_expression import your_expression


def unload(self):
    # Do not forget to unload your expression with the plugin
    QgsExpression.unregisterFunction(your_expression.name())
11

You can add your custom functions to your plugin. The main file of plugin should be like this:

from qgis.utils import iface, qgsfunction
from qgis.core import QgsExpression


#### YOUR CUSTOM FUNCTION ####
@qgsfunction(args='auto', group='customFunctions', register = False)
def custom_function1(values, feature, parent):
    #
    # CODE
    #
    # return

#############################

class customFunctions: # main class of plugin
    def __init__(self, iface):
        self.iface = iface

    def initGui(self):        
        ### REGISTER ###
        QgsExpression.registerFunction(custom_function1)        
        #####################

    def unload(self):        
        ### UNREGISTER ###
        QgsExpression.unregisterFunction('custom_function1')
        ##################
10

In the end I ended up combining Kadir's and etrimaille's answers and adding one crucial part.

I used etrimaille's idea of having the function in its own file and importing that into my plugin, as that fits better with the structure of the existing plugin. To have this to work, I needed to put the import statements into the file with the function in it.

from qgis.utils import iface, qgsfunction
from qgis.core import QgsExpression

@qgsfunction(
args='auto', group= (...)

When doing this, I also needed to add the name of the file with the function to the python_files: line in the pb_tool.cfg file. This was needed to have the file packaged and deployed.

(The plugin is based on the plugin builder, the entire source code can be found at https://github.com/sickel/altitudecorrector - the custom function is still (3rd march '20) just a dummy function)

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.