PyQGIS – How to Get Value of Variable in Custom Python Expression Function

expressionpyqgisqgis-custom-function

I am writing a custom python expression function to return the value of a variable. By variable, I mean the layer, project, or global variables. I looked at this answer https://gis.stackexchange.com/a/189815/94852 and came up with the following code.

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

@qgsfunction(args='auto', group='Custom')
def env(var_name, feature, parent):
    """ Returns the value of the variable 'var_name' 
    Example usage: env('user_full_name') """

    active_layer = iface.activeLayer()

    if QgsExpressionContextScope.hasVariable(QgsExpressionContextUtils.layerScope(active_layer), var_name):
        return QgsExpressionContextScope.variable(QgsExpressionContextUtils.layerScope(active_layer), var_name)

    elif QgsExpressionContextScope.hasVariable(QgsExpressionContextUtils.projectScope(), var_name):
        return QgsExpressionContextScope.variable(QgsExpressionContextUtils.projectScope(), var_name)

    elif QgsExpressionContextScope.hasVariable(QgsExpressionContextUtils.globalScope(), var_name):
        return QgsExpressionContextScope.variable(QgsExpressionContextUtils.globalScope(), var_name)

    else:
        return ""

I am wondering if there is a better way to do it with fewer lines of code, and if there exists a simpler function getProjectVariable() similar to setProjectVariable(), since I have not been able to find any.

I know I can access the variables directly in the expression engine as well, but I would like to be able to retrieve the value within the python function and further do something with it.


Slightly modified the code, but it will still be nice to know if there is a single function that can return values of any variable, whether layer, project or global.

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

@qgsfunction(args='auto', group='Custom')
def env1(var_name, feature, parent):
    """ Returns the value of the variable 'var_name' 
        Example usage: env('user_full_name') """
    active_layer = iface.activeLayer()
    return QgsExpressionContextScope.variable(QgsExpressionContextUtils.layerScope(active_layer), var_name) \
         or QgsExpressionContextScope.variable(QgsExpressionContextUtils.projectScope(), var_name) \
         or QgsExpressionContextScope.variable(QgsExpressionContextUtils.globalScope(), var_name)

Best Answer

Not completely sure but I think you could shorten your code again ever so slightly by just calling QgsExpressionContextUtils for the project and global scopes:

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

@qgsfunction(args='auto', group='Custom')
def env1(var_name, feature, parent):
    """ Returns the value of the variable 'var_name' 
        Example usage: env('user_full_name') """
    active_layer = iface.activeLayer()
    return QgsExpressionContextScope.variable(QgsExpressionContextUtils.layerScope(active_layer), var_name) \
         or QgsExpressionContextUtils.projectScope().variable(var_name) \
         or QgsExpressionContextUtils.globalScope().variable(var_name)
Related Question