2

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)
  • Just to add on, QGIS variables can be easily accessed from the Expressions tab using the following syntax: @variable_name or var('variable_name'). – Simran Jul 5 '17 at 13:54
3

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)

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.