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– Simran2017年07月05日 13:54:38 +00:00Commented Jul 5, 2017 at 13:54
2 Answers 2
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)
If I understand correctly, you want to get the most specific value of the variable, in case it has been defined in several scopes (e.g. as project variable and layer variable). As you are using @qgsfunction
, the QgsExpressionContext can be provided as a the last argument of your function:
@qgsfunction(args='auto', group='Custom')
def env2(var_name, feature, parent, context):
return context.variable(var_name)
Explore related questions
See similar questions with these tags.