4

I'm doing a little script that allows to add and modify project variables.

my current project

The problem is that you don't know what the variables are inside the project from this interface and you have to write them correctly or it will add a new one.

I would like to improve it to looks like that

from graphical modeller

were you can see all the variables in side the project, and modify them.

Any idea of how to appomplish that? I've looked at the QGIS docs but didn't find anything usefull, but I'm probably wrong.

This is part of my code:

 def initAlgorithm(self, config=None):
    self.addParameter(
        QgsProcessingParameterString(
            self.NAME,
            'Variable name'
        )
    )

    self.addParameter(
        QgsProcessingParameterString(
            self.VALUE,
            'Variable value'
        )
    )


def edit_variable(self, context, name, value):
    QgsExpressionContextUtils.setProjectVariable(context.project(), name, value)

def prepareAlgorithm(self, parameters, context, feedback):
    name = self.parameterAsString(
        parameters,
        self.NAME,
        context
    )
    value = self.parameterAsString(
        parameters,
        self.VALUE,
        context
    )
    if not name:
        raise QgsProcessingException('Variable name cannot be empty')

    QgsExpressionContextUtils.setProjectVariable(context.project(), name, value)
    feedback.pushInfo(f'Set variable {name} to {value}')

    return True

This is my idea of how to populate this object (perhaps by removing some of the unnecessary variables)

    def populate_list(self, context):
        project_scope = context.project()
        variables = project_scope.variableNames()
        for variable in variables:
           bla bla

1 Answer 1

5

You could use a QgsProcessingParameterMatrix and populate it with the project variables. This will give you an interactive table widget in the algorithm dialog.

Here is a rough example:

from qgis.PyQt.QtCore import QCoreApplication, QVariant
from qgis.core import (QgsProcessing, QgsProcessingAlgorithm,
                        QgsProcessingParameterMatrix,
                        QgsProject, QgsExpressionContextUtils)
                       
class ExAlgo(QgsProcessingAlgorithm):
    TABLE = "TABLE"
    OUTPUT = "OUTPUT"
 
    def __init__(self):
        super().__init__()
 
    def name(self):
        return "variables_table"
         
    def displayName(self):
        return "Variables table"
 
    def group(self):
        return "Examples"
 
    def groupId(self):
        return "examples"
 
    def shortHelpString(self):
        return "Example script using table parameter"
 
    def helpUrl(self):
        return "https://qgis.org"
         
    def createInstance(self):
        return type(self)()
   
    def initAlgorithm(self, config=None):
        var_map = []
        project_scope = QgsExpressionContextUtils.projectScope(QgsProject.instance())
        for var_name in project_scope.variableNames():
            var_map.append(var_name)
            var_map.append(project_scope.variable(var_name))
        self.addParameter(QgsProcessingParameterMatrix(self.TABLE,
                'Project Variables',
                headers=['Name', 'Value'],
                defaultValue=var_map))

 
    def processAlgorithm(self, parameters, context, feedback):
        variable_map = self.parameterAsMatrix(parameters, self.TABLE, context)
 
        return {self.OUTPUT: variable_map}

Resulting algorithm dialog:

enter image description here

Click the ellipsis button enter image description here on the right of the default parameter widget to open the table:

enter image description here

Another, slightly more involved option would be to use a custom widget wrapper class as described in this blog by Faunalia Adding a custom widget to a QGIS Processing script and use a QTableWidget for example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.