13

I'd like to change the value of a user-defined project variable (can be manually edited in Project Settings | Variables) using the Python console. I tracked down the setVariable() function in the QgsExpressionContextScope class but haven't succeeded in actually changing the variable in the project settings. My code so far:

iface.mapCanvas().mapSettings().expressionContext().scope(0).setVariable('myvar',1)

I guess I'm getting lost in the different expression contexts ...

underdark
  • 84,148
  • 21
  • 231
  • 413

2 Answers2

12

Look at QgsExpressionContextUtils (https://qgis.org/api/classQgsExpressionContextUtils.html). The method you need is QgsExpressionContextUtils.setProjectVariable, e.g.

QgsExpressionContextUtils.setProjectVariable('myvar','hello world')
underdark
  • 84,148
  • 21
  • 231
  • 413
ndawson
  • 27,620
  • 3
  • 61
  • 85
  • What about deleting a variable? I didn't find method for it in QgsExpressionContextUtils – ismailsunni Jul 24 '17 at 15:39
  • There's no high level API to do this. Possibly you could get away with NULLING the variable (setting it to None), but if not, you need to use QgsExpressionContextUtils.setProjectVariables({} ) and reset the whole lot. You'd first need to check QgsExpressionContextUtils.projectScope() and create a dict of all the variables you want to keep. It's far from ideal - but would also be a trivial addition to the API if you wanted to get involved in QGIS development and send through a pull request on github... – ndawson Jul 24 '17 at 22:58
  • Thanks @ndawson, it works with your work around to reset with setProjectVariables(preserved_variables) I have checked the C++ code, I hope I can contribute for the functionality. – ismailsunni Jul 25 '17 at 02:06
  • 2
  • 2
    There is a new required parameter since QGIS 3.0. See an updated answer here: https://gis.stackexchange.com/questions/222494/how-to-read-user-defined-project-variables-using-python – TimD Jun 26 '20 at 03:57
6

In QGIS3, the API needs to pass QgsProject as the first argument.

It is: setProjectVariable(project: QgsProject, name: str, value: Any)

QgsExpressionContextUtils.setProjectVariable(QgsProject.instance(), 'myvar','hello world')

Zac
  • 517
  • 3
  • 10