mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-17 00:04:02 -04:00
[processing][API] Add API to QgsProcessingGuiRegistry and QgsProcessingParameterWidgetFactoryInterface
to handle creation of parameter definition widgets Previously, these configuration widgets were all hardcoded into the Python modeler dialog. This prevented 3rd party, plugin provided, parameters from ever being full first class citizens in QGIS, as there was no way to allow their use as inputs to user created models to be customised. Now, the registry is responsible for creating the configuration widget, allowing for 3rd party parameter types to provide their own customised configuration widgets. Refs #26493
This commit is contained in:
parent
b0d7c2927e
commit
10d6a8a122
@ -123,6 +123,33 @@ handles the given ``parameter``, ``None`` will be returned.
|
||||
.. seealso:: :py:func:`addParameterWidgetFactory`
|
||||
|
||||
.. versionadded:: 3.4
|
||||
%End
|
||||
|
||||
QgsProcessingAbstractParameterDefinitionWidget *createParameterDefinitionWidget( const QString &type,
|
||||
QgsProcessingContext &context,
|
||||
const QgsProcessingParameterWidgetContext &widgetContext,
|
||||
const QgsProcessingParameterDefinition *definition = 0,
|
||||
const QgsProcessingAlgorithm *algorithm = 0 ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new parameter definition widget allowing for configuration of an instance of
|
||||
a specific parameter ``type``.
|
||||
|
||||
The ``context`` argument must specify a Processing context, which will be used
|
||||
by the widget to evaluate existing ``definition`` properties such as default values. Similarly,
|
||||
the ``widgetContext`` argument specifies the wider GUI context in which the widget
|
||||
will be used.
|
||||
|
||||
The optional ``definition`` argument may specify an existing parameter definition which
|
||||
will be reflected in the initial state of the returned widget. If ``definition`` is ``None``,
|
||||
then the returned widget will use default settings instead.
|
||||
|
||||
Additionally, the optional ``algorithm`` parameter may be used to specify the algorithm or model
|
||||
associated with the parameter.
|
||||
|
||||
If ``None`` is returned for a particular parameter ``type``,
|
||||
it indicates that the parameter type cannot be configured via GUI.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
};
|
||||
|
@ -0,0 +1,154 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/processing/qgsprocessingparameterdefinitionwidget.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsProcessingAbstractParameterDefinitionWidget : QWidget
|
||||
{
|
||||
%Docstring
|
||||
Abstract base class for widgets which allow users to specify the properties of a
|
||||
Processing parameter.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsprocessingparameterdefinitionwidget.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsProcessingAbstractParameterDefinitionWidget( QgsProcessingContext &context,
|
||||
const QgsProcessingParameterWidgetContext &widgetContext,
|
||||
const QgsProcessingParameterDefinition *definition = 0,
|
||||
const QgsProcessingAlgorithm *algorithm = 0, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Creates a new QgsProcessingAbstractParameterDefinitionWidget, with the specified ``parent`` widget.
|
||||
|
||||
The ``context`` argument must specify a Processing context, which will be used
|
||||
by the widget to evaluate existing ``definition`` properties such as default values. Similarly,
|
||||
the ``widgetContext`` argument specifies the wider GUI context in which the widget
|
||||
will be used.
|
||||
|
||||
The optional ``definition`` argument may be used to provide a parameter definition to use
|
||||
to initially populate the widget's state.
|
||||
|
||||
Additionally, the optional ``algorithm`` parameter may be used to specify the algorithm or model
|
||||
associated with the parameter.
|
||||
%End
|
||||
|
||||
virtual QgsProcessingParameterDefinition *createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const = 0 /Factory/;
|
||||
%Docstring
|
||||
Returns a new instance of a parameter definition, using the current settings defined in the dialog.
|
||||
|
||||
Common properties for parameters, including the ``name``, ``description``, and parameter ``flags`` are passed to the
|
||||
method. Subclass implementations must use these properties when crafting a parameter definition which
|
||||
also respects the additional properties specific to the parameter type handled by the widget sublass.
|
||||
%End
|
||||
};
|
||||
|
||||
|
||||
class QgsProcessingParameterDefinitionWidget: QWidget
|
||||
{
|
||||
%Docstring
|
||||
A widget which allow users to specify the properties of a Processing parameter.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsprocessingparameterdefinitionwidget.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsProcessingParameterDefinitionWidget( const QString &type,
|
||||
QgsProcessingContext &context,
|
||||
const QgsProcessingParameterWidgetContext &widgetContext,
|
||||
const QgsProcessingParameterDefinition *definition = 0,
|
||||
const QgsProcessingAlgorithm *algorithm = 0,
|
||||
QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsProcessingParameterDefinitionWidget, for a parameter of the
|
||||
specified ``type``.
|
||||
|
||||
The ``context`` argument must specify a Processing context, which will be used
|
||||
by the widget to evaluate existing ``definition`` properties such as default values. Similarly,
|
||||
the ``widgetContext`` argument specifies the wider GUI context in which the widget
|
||||
will be used.
|
||||
|
||||
The optional ``definition`` argument may be used to provide a parameter definition to use
|
||||
to initially populate the widget's state.
|
||||
|
||||
Additionally, the optional ``algorithm`` parameter may be used to specify the algorithm or model
|
||||
associated with the parameter.
|
||||
%End
|
||||
|
||||
QgsProcessingParameterDefinition *createParameter( const QString &name = QString() ) const /Factory/;
|
||||
%Docstring
|
||||
Returns a new instance of a parameter definition, using the current settings defined in the dialog.
|
||||
|
||||
The ``name`` parameter specifies the name for the newly created parameter.
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
class QgsProcessingParameterDefinitionDialog: QDialog
|
||||
{
|
||||
%Docstring
|
||||
A dialog which allow users to specify the properties of a Processing parameter.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsprocessingparameterdefinitionwidget.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsProcessingParameterDefinitionDialog( const QString &type,
|
||||
QgsProcessingContext &context,
|
||||
const QgsProcessingParameterWidgetContext &widgetContext,
|
||||
const QgsProcessingParameterDefinition *definition = 0,
|
||||
const QgsProcessingAlgorithm *algorithm = 0,
|
||||
QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsProcessingParameterDefinitionDialog, for a parameter of the
|
||||
specified ``type``.
|
||||
|
||||
The ``context`` argument must specify a Processing context, which will be used
|
||||
by the widget to evaluate existing ``definition`` properties such as default values. Similarly,
|
||||
the ``widgetContext`` argument specifies the wider GUI context in which the widget
|
||||
will be used.
|
||||
|
||||
The optional ``definition`` argument may be used to provide a parameter definition to use
|
||||
to initially populate the dialog's state.
|
||||
|
||||
Additionally, the optional ``algorithm`` parameter may be used to specify the algorithm or model
|
||||
associated with the parameter.
|
||||
%End
|
||||
|
||||
QgsProcessingParameterDefinition *createParameter( const QString &name = QString() ) const /Factory/;
|
||||
%Docstring
|
||||
Returns a new instance of a parameter definition, using the current settings defined in the dialog.
|
||||
|
||||
The ``name`` parameter specifies the name for the newly created parameter.
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/gui/processing/qgsprocessingparameterdefinitionwidget.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -389,6 +389,36 @@ to resolve parameter values which are context dependent. The context must
|
||||
last for the lifetime of the widget.
|
||||
|
||||
.. seealso:: :py:func:`createWidgetWrapper`
|
||||
%End
|
||||
|
||||
virtual QgsProcessingAbstractParameterDefinitionWidget *createParameterDefinitionWidget(
|
||||
QgsProcessingContext &context,
|
||||
const QgsProcessingParameterWidgetContext &widgetContext,
|
||||
const QgsProcessingParameterDefinition *definition = 0,
|
||||
const QgsProcessingAlgorithm *algorithm = 0 ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new parameter definition widget allowing for configuration of an instance of
|
||||
the parameter type handled by this factory.
|
||||
|
||||
The ``context`` argument must specify a Processing context, which will be used
|
||||
by the widget to evaluate existing ``definition`` properties such as default values. Similarly,
|
||||
the ``widgetContext`` argument specifies the wider GUI context in which the widget
|
||||
will be used.
|
||||
|
||||
The optional ``definition`` argument may specify a parameter definition which
|
||||
should be reflected in the initial state of the returned widget. Subclasses must
|
||||
ensure that they correctly handle both the case when a initial ``definition`` is
|
||||
passed, or when ``definition`` is ``None`` (in which case sensible defaults should
|
||||
be shown in the returned widget).
|
||||
|
||||
Additionally, the optional ``algorithm`` parameter may be used to specify the algorithm or model
|
||||
associated with the parameter.
|
||||
|
||||
If a factory subclass returns ``None`` for this method (i.e. as the base class implemention does),
|
||||
it indicates that the parameter type cannot be configured via GUI. In this case the parameter
|
||||
type will not be configurable when users add it as an input to their graphical models.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
@ -340,6 +340,7 @@
|
||||
%Include auto_generated/processing/qgsprocessingmaplayercombobox.sip
|
||||
%Include auto_generated/processing/qgsprocessingmodelerparameterwidget.sip
|
||||
%Include auto_generated/processing/qgsprocessingmultipleselectiondialog.sip
|
||||
%Include auto_generated/processing/qgsprocessingparameterdefinitionwidget.sip
|
||||
%Include auto_generated/processing/qgsprocessingrecentalgorithmlog.sip
|
||||
%Include auto_generated/processing/qgsprocessingtoolboxmodel.sip
|
||||
%Include auto_generated/processing/qgsprocessingtoolboxtreeview.sip
|
||||
|
@ -86,7 +86,9 @@ from qgis.gui import (QgsMessageBar,
|
||||
QgsFilterLineEdit,
|
||||
QgsProcessingToolboxTreeView,
|
||||
QgsProcessingToolboxProxyModel,
|
||||
QgsVariableEditorWidget)
|
||||
QgsProcessingParameterDefinitionDialog,
|
||||
QgsVariableEditorWidget,
|
||||
QgsProcessingParameterWidgetContext)
|
||||
from processing.gui.HelpEditionDialog import HelpEditionDialog
|
||||
from processing.gui.AlgorithmDialog import AlgorithmDialog
|
||||
from processing.modeler.ModelerParameterDefinitionDialog import ModelerParameterDefinitionDialog
|
||||
@ -96,6 +98,7 @@ from processing.modeler.ModelerScene import ModelerScene
|
||||
from processing.modeler.ProjectProvider import PROJECT_PROVIDER_ID
|
||||
from processing.script.ScriptEditorDialog import ScriptEditorDialog
|
||||
from processing.core.ProcessingConfig import ProcessingConfig
|
||||
from processing.tools.dataobjects import createContext
|
||||
from qgis.utils import iface
|
||||
|
||||
|
||||
@ -787,18 +790,59 @@ class ModelerDialog(BASE, WIDGET):
|
||||
param = item.data(0, Qt.UserRole)
|
||||
self.addInputOfType(param)
|
||||
|
||||
def create_widget_context(self):
|
||||
"""
|
||||
Returns a new widget context for use in the model editor
|
||||
"""
|
||||
widget_context = QgsProcessingParameterWidgetContext()
|
||||
widget_context.setProject(QgsProject.instance())
|
||||
if iface is not None:
|
||||
widget_context.setMapCanvas(iface.mapCanvas())
|
||||
widget_context.setModel(self.model)
|
||||
return widget_context
|
||||
|
||||
def autogenerate_parameter_name(self, parameter):
|
||||
"""
|
||||
Automatically generates and sets a new parameter's name, based on the parameter's
|
||||
description and ensuring that it is unique for the model.
|
||||
"""
|
||||
validChars = \
|
||||
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
|
||||
safeName = ''.join(c for c in parameter.description() if c in validChars)
|
||||
name = safeName.lower()
|
||||
i = 2
|
||||
while self.model.parameterDefinition(name):
|
||||
name = safeName.lower() + str(i)
|
||||
i += 1
|
||||
parameter.setName(safeName)
|
||||
|
||||
def addInputOfType(self, paramType, pos=None):
|
||||
dlg = ModelerParameterDefinitionDialog(self.model, paramType)
|
||||
dlg.exec_()
|
||||
if dlg.param is not None:
|
||||
new_param = None
|
||||
if ModelerParameterDefinitionDialog.use_legacy_dialog(paramType=paramType):
|
||||
dlg = ModelerParameterDefinitionDialog(self.model, paramType)
|
||||
if dlg.exec_():
|
||||
new_param = dlg.param
|
||||
else:
|
||||
# yay, use new API!
|
||||
context = createContext()
|
||||
widget_context = self.create_widget_context()
|
||||
dlg = QgsProcessingParameterDefinitionDialog(type=paramType,
|
||||
context=context,
|
||||
widgetContext=widget_context,
|
||||
algorithm=self.model)
|
||||
if dlg.exec_():
|
||||
new_param = dlg.createParameter()
|
||||
self.autogenerate_parameter_name(new_param)
|
||||
|
||||
if new_param is not None:
|
||||
if pos is None:
|
||||
pos = self.getPositionForParameterItem()
|
||||
if isinstance(pos, QPoint):
|
||||
pos = QPointF(pos)
|
||||
component = QgsProcessingModelParameter(dlg.param.name())
|
||||
component.setDescription(dlg.param.name())
|
||||
component = QgsProcessingModelParameter(new_param.name())
|
||||
component.setDescription(new_param.name())
|
||||
component.setPosition(pos)
|
||||
self.model.addModelParameter(dlg.param, component)
|
||||
self.model.addModelParameter(new_param, component)
|
||||
self.repaintModel()
|
||||
# self.view.ensureVisible(self.scene.getLastParameterItem())
|
||||
self.hasChanged = True
|
||||
|
@ -1,4 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
***************************************************************************
|
||||
@ -33,9 +34,16 @@ from qgis.core import (QgsProcessingParameterDefinition,
|
||||
QgsProcessingModelParameter,
|
||||
QgsProcessingModelOutput,
|
||||
QgsProcessingModelChildAlgorithm,
|
||||
QgsProcessingModelAlgorithm)
|
||||
QgsProcessingModelAlgorithm,
|
||||
QgsProject)
|
||||
from qgis.gui import (
|
||||
QgsProcessingParameterDefinitionDialog,
|
||||
QgsProcessingParameterWidgetContext
|
||||
)
|
||||
from processing.modeler.ModelerParameterDefinitionDialog import ModelerParameterDefinitionDialog
|
||||
from processing.modeler.ModelerParametersDialog import ModelerParametersDialog
|
||||
from processing.tools.dataobjects import createContext
|
||||
from qgis.utils import iface
|
||||
|
||||
pluginPath = os.path.split(os.path.dirname(__file__))[0]
|
||||
|
||||
@ -227,16 +235,45 @@ class ModelerGraphicItem(QGraphicsItem):
|
||||
'The selected algorithm depends on other currently non-active algorithms.\n'
|
||||
'Activate them them before trying to activate it.')
|
||||
|
||||
def create_widget_context(self):
|
||||
"""
|
||||
Returns a new widget context for use in the model editor
|
||||
"""
|
||||
widget_context = QgsProcessingParameterWidgetContext()
|
||||
widget_context.setProject(QgsProject.instance())
|
||||
if iface is not None:
|
||||
widget_context.setMapCanvas(iface.mapCanvas())
|
||||
widget_context.setModel(self.model)
|
||||
return widget_context
|
||||
|
||||
def editElement(self):
|
||||
if isinstance(self.element, QgsProcessingModelParameter):
|
||||
dlg = ModelerParameterDefinitionDialog(self.model,
|
||||
param=self.model.parameterDefinition(self.element.parameterName()))
|
||||
if dlg.exec_() and dlg.param is not None:
|
||||
existing_param = self.model.parameterDefinition(self.element.parameterName())
|
||||
new_param = None
|
||||
if ModelerParameterDefinitionDialog.use_legacy_dialog(param=existing_param):
|
||||
# boo, old api
|
||||
dlg = ModelerParameterDefinitionDialog(self.model,
|
||||
param=existing_param)
|
||||
if dlg.exec_():
|
||||
new_param = dlg.param
|
||||
else:
|
||||
# yay, use new API!
|
||||
context = createContext()
|
||||
widget_context = self.create_widget_context()
|
||||
dlg = QgsProcessingParameterDefinitionDialog(type=existing_param.type(),
|
||||
context=context,
|
||||
widgetContext=widget_context,
|
||||
definition=existing_param,
|
||||
algorithm=self.model)
|
||||
if dlg.exec_():
|
||||
new_param = dlg.createParameter(existing_param.name())
|
||||
|
||||
if new_param is not None:
|
||||
self.model.removeModelParameter(self.element.parameterName())
|
||||
self.element.setParameterName(dlg.param.name())
|
||||
self.element.setDescription(dlg.param.name())
|
||||
self.model.addModelParameter(dlg.param, self.element)
|
||||
self.text = dlg.param.description()
|
||||
self.element.setParameterName(new_param.name())
|
||||
self.element.setDescription(new_param.name())
|
||||
self.model.addModelParameter(new_param, self.element)
|
||||
self.text = new_param.description()
|
||||
self.scene.dialog.repaintModel()
|
||||
elif isinstance(self.element, QgsProcessingModelChildAlgorithm):
|
||||
elemAlg = self.element.algorithm()
|
||||
|
@ -79,6 +79,49 @@ from processing.modeler.exceptions import UndefinedParameterException
|
||||
|
||||
class ModelerParameterDefinitionDialog(QDialog):
|
||||
|
||||
@staticmethod
|
||||
def use_legacy_dialog(param=None, paramType=None):
|
||||
if paramType in (parameters.PARAMETER_BOOLEAN,
|
||||
parameters.PARAMETER_TABLE_FIELD,
|
||||
parameters.PARAMETER_BAND,
|
||||
parameters.PARAMETER_LAYOUTITEM,
|
||||
parameters.PARAMETER_VECTOR,
|
||||
parameters.PARAMETER_TABLE,
|
||||
parameters.PARAMETER_MULTIPLE,
|
||||
parameters.PARAMETER_NUMBER,
|
||||
parameters.PARAMETER_DISTANCE,
|
||||
parameters.PARAMETER_SCALE,
|
||||
parameters.PARAMETER_EXPRESSION,
|
||||
parameters.PARAMETER_STRING,
|
||||
parameters.PARAMETER_FILE,
|
||||
parameters.PARAMETER_POINT,
|
||||
parameters.PARAMETER_CRS,
|
||||
parameters.PARAMETER_ENUM,
|
||||
parameters.PARAMETER_MATRIX):
|
||||
return True
|
||||
elif isinstance(param, (QgsProcessingParameterBoolean,
|
||||
QgsProcessingParameterField,
|
||||
QgsProcessingParameterBand,
|
||||
QgsProcessingParameterLayoutItem,
|
||||
QgsProcessingParameterFeatureSource,
|
||||
QgsProcessingParameterVectorLayer,
|
||||
QgsProcessingParameterMultipleLayers,
|
||||
QgsProcessingParameterNumber,
|
||||
QgsProcessingParameterDistance,
|
||||
QgsProcessingParameterScale,
|
||||
QgsProcessingParameterExpression,
|
||||
QgsProcessingParameterString,
|
||||
QgsProcessingParameterFile,
|
||||
QgsProcessingParameterPoint,
|
||||
QgsProcessingParameterCrs,
|
||||
QgsProcessingParameterEnum,
|
||||
QgsProcessingParameterMatrix,
|
||||
QgsProcessingDestinationParameter)):
|
||||
return True
|
||||
|
||||
# yay, use new API!
|
||||
return False
|
||||
|
||||
def __init__(self, alg, paramType=None, param=None):
|
||||
self.alg = alg
|
||||
self.paramType = paramType
|
||||
|
@ -205,6 +205,7 @@ SET(QGIS_GUI_SRCS
|
||||
processing/qgsprocessingmatrixparameterdialog.cpp
|
||||
processing/qgsprocessingmodelerparameterwidget.cpp
|
||||
processing/qgsprocessingmultipleselectiondialog.cpp
|
||||
processing/qgsprocessingparameterdefinitionwidget.cpp
|
||||
processing/qgsprocessingrecentalgorithmlog.cpp
|
||||
processing/qgsprocessingtoolboxmodel.cpp
|
||||
processing/qgsprocessingtoolboxtreeview.cpp
|
||||
@ -780,6 +781,7 @@ SET(QGIS_GUI_MOC_HDRS
|
||||
processing/qgsprocessingmatrixparameterdialog.h
|
||||
processing/qgsprocessingmodelerparameterwidget.h
|
||||
processing/qgsprocessingmultipleselectiondialog.h
|
||||
processing/qgsprocessingparameterdefinitionwidget.h
|
||||
processing/qgsprocessingrecentalgorithmlog.h
|
||||
processing/qgsprocessingtoolboxmodel.h
|
||||
processing/qgsprocessingtoolboxtreeview.h
|
||||
|
@ -130,3 +130,15 @@ QgsProcessingModelerParameterWidget *QgsProcessingGuiRegistry::createModelerPara
|
||||
return mParameterWidgetFactories.value( parameterType )->createModelerWidgetWrapper( model, childId, parameter, context );
|
||||
}
|
||||
|
||||
QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingGuiRegistry::createParameterDefinitionWidget( const QString &type,
|
||||
QgsProcessingContext &context,
|
||||
const QgsProcessingParameterWidgetContext &widgetContext,
|
||||
const QgsProcessingParameterDefinition *definition,
|
||||
const QgsProcessingAlgorithm *algorithm )
|
||||
{
|
||||
if ( !mParameterWidgetFactories.contains( type ) )
|
||||
return nullptr;
|
||||
|
||||
return mParameterWidgetFactories.value( type )->createParameterDefinitionWidget( context, widgetContext, definition, algorithm );
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ class QgsProcessingAlgorithm;
|
||||
class QgsProcessingAlgorithmConfigurationWidget;
|
||||
class QgsProcessingAlgorithmConfigurationWidgetFactory;
|
||||
class QgsProcessingModelerParameterWidget;
|
||||
class QgsProcessingParameterWidgetContext;
|
||||
|
||||
/**
|
||||
* The QgsProcessingGuiRegistry is a home for widgets for processing
|
||||
@ -138,6 +139,33 @@ class GUI_EXPORT QgsProcessingGuiRegistry
|
||||
const QString &childId,
|
||||
const QgsProcessingParameterDefinition *parameter, QgsProcessingContext &context ) SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Creates a new parameter definition widget allowing for configuration of an instance of
|
||||
* a specific parameter \a type.
|
||||
*
|
||||
* The \a context argument must specify a Processing context, which will be used
|
||||
* by the widget to evaluate existing \a definition properties such as default values. Similarly,
|
||||
* the \a widgetContext argument specifies the wider GUI context in which the widget
|
||||
* will be used.
|
||||
*
|
||||
* The optional \a definition argument may specify an existing parameter definition which
|
||||
* will be reflected in the initial state of the returned widget. If \a definition is NULLPTR,
|
||||
* then the returned widget will use default settings instead.
|
||||
*
|
||||
* Additionally, the optional \a algorithm parameter may be used to specify the algorithm or model
|
||||
* associated with the parameter.
|
||||
*
|
||||
* If NULLPTR is returned for a particular parameter \a type,
|
||||
* it indicates that the parameter type cannot be configured via GUI.
|
||||
*
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
QgsProcessingAbstractParameterDefinitionWidget *createParameterDefinitionWidget( const QString &type,
|
||||
QgsProcessingContext &context,
|
||||
const QgsProcessingParameterWidgetContext &widgetContext,
|
||||
const QgsProcessingParameterDefinition *definition = nullptr,
|
||||
const QgsProcessingAlgorithm *algorithm = nullptr ) SIP_FACTORY;
|
||||
|
||||
private:
|
||||
|
||||
QList <QgsProcessingAlgorithmConfigurationWidgetFactory *> mAlgorithmConfigurationWidgetFactories;
|
||||
|
149
src/gui/processing/qgsprocessingparameterdefinitionwidget.cpp
Normal file
149
src/gui/processing/qgsprocessingparameterdefinitionwidget.cpp
Normal file
@ -0,0 +1,149 @@
|
||||
/***************************************************************************
|
||||
qgsprocessingparameterdefinitionwidget.cpp
|
||||
------------------------------------------
|
||||
begin : July 2019
|
||||
copyright : (C) 2019 by Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "qgsprocessingparameterdefinitionwidget.h"
|
||||
#include "qgsgui.h"
|
||||
#include "qgsprocessingguiregistry.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsprocessingregistry.h"
|
||||
#include "qgsprocessingparametertype.h"
|
||||
#include <QVBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QCheckBox>
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
|
||||
QgsProcessingAbstractParameterDefinitionWidget::QgsProcessingAbstractParameterDefinitionWidget( QgsProcessingContext &,
|
||||
const QgsProcessingParameterWidgetContext &,
|
||||
const QgsProcessingParameterDefinition *,
|
||||
const QgsProcessingAlgorithm *, QWidget *parent )
|
||||
: QWidget( parent )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// QgsProcessingParameterDefinitionWidget
|
||||
//
|
||||
|
||||
QgsProcessingParameterDefinitionWidget::QgsProcessingParameterDefinitionWidget( const QString &type,
|
||||
QgsProcessingContext &context,
|
||||
const QgsProcessingParameterWidgetContext &widgetContext,
|
||||
const QgsProcessingParameterDefinition *definition,
|
||||
const QgsProcessingAlgorithm *algorithm, QWidget *parent )
|
||||
: QWidget( parent )
|
||||
, mType( type )
|
||||
{
|
||||
mDefinitionWidget = QgsGui::instance()->processingGuiRegistry()->createParameterDefinitionWidget( type, context, widgetContext, definition, algorithm );
|
||||
|
||||
QVBoxLayout *vlayout = new QVBoxLayout();
|
||||
|
||||
QLabel *label = new QLabel( tr( "Description" ) );
|
||||
vlayout->addWidget( label );
|
||||
mDescriptionLineEdit = new QLineEdit();
|
||||
vlayout->addWidget( mDescriptionLineEdit );
|
||||
|
||||
if ( definition )
|
||||
{
|
||||
mDescriptionLineEdit->setText( definition->description() );
|
||||
}
|
||||
|
||||
if ( mDefinitionWidget )
|
||||
vlayout->addWidget( mDefinitionWidget );
|
||||
|
||||
vlayout->addSpacing( 20 );
|
||||
mRequiredCheckBox = new QCheckBox( tr( "Mandatory" ) );
|
||||
if ( definition )
|
||||
mRequiredCheckBox->setChecked( !( definition->flags() & QgsProcessingParameterDefinition::FlagOptional ) );
|
||||
else
|
||||
mRequiredCheckBox->setChecked( true );
|
||||
vlayout->addWidget( mRequiredCheckBox );
|
||||
|
||||
mAdvancedCheckBox = new QCheckBox( tr( "Advanced" ) );
|
||||
if ( definition )
|
||||
mAdvancedCheckBox->setChecked( definition->flags() & QgsProcessingParameterDefinition::FlagAdvanced );
|
||||
else
|
||||
mAdvancedCheckBox->setChecked( false );
|
||||
vlayout->addWidget( mAdvancedCheckBox );
|
||||
|
||||
vlayout->addStretch();
|
||||
setLayout( vlayout );
|
||||
}
|
||||
|
||||
QgsProcessingParameterDefinition *QgsProcessingParameterDefinitionWidget::createParameter( const QString &name ) const
|
||||
{
|
||||
std::unique_ptr< QgsProcessingParameterDefinition > param;
|
||||
QgsProcessingParameterDefinition::Flags flags = nullptr;
|
||||
|
||||
if ( !mRequiredCheckBox->isChecked() )
|
||||
flags |= QgsProcessingParameterDefinition::FlagOptional;
|
||||
if ( mAdvancedCheckBox->isChecked() )
|
||||
flags |= QgsProcessingParameterDefinition::FlagAdvanced;
|
||||
|
||||
if ( mDefinitionWidget )
|
||||
{
|
||||
// if a specific definition widget exists, get it to create the parameter (since it will know
|
||||
// how to set all the additional properties of that parameter, which we don't)
|
||||
param.reset( mDefinitionWidget->createParameter( name, mDescriptionLineEdit->text(), flags ) );
|
||||
}
|
||||
else if ( QgsApplication::processingRegistry()->parameterType( mType ) )
|
||||
{
|
||||
// otherwise, just create a default version of the parameter
|
||||
param.reset( QgsApplication::processingRegistry()->parameterType( mType )->create( name ) );
|
||||
if ( param )
|
||||
{
|
||||
param->setDescription( mDescriptionLineEdit->text() );
|
||||
param->setFlags( flags );
|
||||
}
|
||||
}
|
||||
|
||||
return param.release();
|
||||
}
|
||||
|
||||
//
|
||||
// QgsProcessingParameterDefinitionDialog
|
||||
//
|
||||
|
||||
QgsProcessingParameterDefinitionDialog::QgsProcessingParameterDefinitionDialog( const QString &type,
|
||||
QgsProcessingContext &context,
|
||||
const QgsProcessingParameterWidgetContext &widgetContext,
|
||||
const QgsProcessingParameterDefinition *definition,
|
||||
const QgsProcessingAlgorithm *algorithm,
|
||||
QWidget *parent )
|
||||
: QDialog( parent )
|
||||
{
|
||||
QVBoxLayout *vLayout = new QVBoxLayout();
|
||||
mWidget = new QgsProcessingParameterDefinitionWidget( type, context, widgetContext, definition, algorithm );
|
||||
vLayout->addWidget( mWidget );
|
||||
QDialogButtonBox *bbox = new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Ok );
|
||||
connect( bbox, &QDialogButtonBox::accepted, this, &QgsProcessingParameterDefinitionDialog::accept );
|
||||
connect( bbox, &QDialogButtonBox::rejected, this, &QgsProcessingParameterDefinitionDialog::reject );
|
||||
vLayout->addWidget( bbox );
|
||||
setLayout( vLayout );
|
||||
setWindowTitle( definition ? tr( "%1 Parameter Definition" ).arg( definition->description() )
|
||||
: QgsApplication::processingRegistry()->parameterType( type ) ? tr( "%1 Parameter Definition" ).arg( QgsApplication::processingRegistry()->parameterType( type )->name() ) :
|
||||
tr( "Parameter Definition" ) );
|
||||
setObjectName( QStringLiteral( "QgsProcessingParameterDefinitionDialog" ) );
|
||||
QgsGui::enableAutoGeometryRestore( this );
|
||||
}
|
||||
|
||||
QgsProcessingParameterDefinition *QgsProcessingParameterDefinitionDialog::createParameter( const QString &name ) const
|
||||
{
|
||||
return mWidget->createParameter( name );
|
||||
}
|
175
src/gui/processing/qgsprocessingparameterdefinitionwidget.h
Normal file
175
src/gui/processing/qgsprocessingparameterdefinitionwidget.h
Normal file
@ -0,0 +1,175 @@
|
||||
/***************************************************************************
|
||||
qgsprocessingparameterdefinitionwidget.h
|
||||
----------------------------------------
|
||||
begin : July 2019
|
||||
copyright : (C) 2019 by Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef QGSPROCESSINGPARAMETERDEFINITIONWIDGET_H
|
||||
#define QGSPROCESSINGPARAMETERDEFINITIONWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDialog>
|
||||
|
||||
#include "qgis_gui.h"
|
||||
#include "qgis_sip.h"
|
||||
#include "qgsprocessingparameters.h"
|
||||
|
||||
class QgsProcessingParameterWidgetContext;
|
||||
class QLineEdit;
|
||||
class QCheckBox;
|
||||
|
||||
/**
|
||||
* Abstract base class for widgets which allow users to specify the properties of a
|
||||
* Processing parameter.
|
||||
*
|
||||
* \ingroup gui
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
class GUI_EXPORT QgsProcessingAbstractParameterDefinitionWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a new QgsProcessingAbstractParameterDefinitionWidget, with the specified \a parent widget.
|
||||
*
|
||||
* The \a context argument must specify a Processing context, which will be used
|
||||
* by the widget to evaluate existing \a definition properties such as default values. Similarly,
|
||||
* the \a widgetContext argument specifies the wider GUI context in which the widget
|
||||
* will be used.
|
||||
*
|
||||
* The optional \a definition argument may be used to provide a parameter definition to use
|
||||
* to initially populate the widget's state.
|
||||
*
|
||||
* Additionally, the optional \a algorithm parameter may be used to specify the algorithm or model
|
||||
* associated with the parameter.
|
||||
*/
|
||||
QgsProcessingAbstractParameterDefinitionWidget( QgsProcessingContext &context,
|
||||
const QgsProcessingParameterWidgetContext &widgetContext,
|
||||
const QgsProcessingParameterDefinition *definition = nullptr,
|
||||
const QgsProcessingAlgorithm *algorithm = nullptr, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Returns a new instance of a parameter definition, using the current settings defined in the dialog.
|
||||
*
|
||||
* Common properties for parameters, including the \a name, \a description, and parameter \a flags are passed to the
|
||||
* method. Subclass implementations must use these properties when crafting a parameter definition which
|
||||
* also respects the additional properties specific to the parameter type handled by the widget sublass.
|
||||
*/
|
||||
virtual QgsProcessingParameterDefinition *createParameter( const QString &name, const QString &description, QgsProcessingParameterDefinition::Flags flags ) const = 0 SIP_FACTORY;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A widget which allow users to specify the properties of a Processing parameter.
|
||||
*
|
||||
* \ingroup gui
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
class GUI_EXPORT QgsProcessingParameterDefinitionWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsProcessingParameterDefinitionWidget, for a parameter of the
|
||||
* specified \a type.
|
||||
*
|
||||
* The \a context argument must specify a Processing context, which will be used
|
||||
* by the widget to evaluate existing \a definition properties such as default values. Similarly,
|
||||
* the \a widgetContext argument specifies the wider GUI context in which the widget
|
||||
* will be used.
|
||||
*
|
||||
* The optional \a definition argument may be used to provide a parameter definition to use
|
||||
* to initially populate the widget's state.
|
||||
*
|
||||
* Additionally, the optional \a algorithm parameter may be used to specify the algorithm or model
|
||||
* associated with the parameter.
|
||||
*
|
||||
*/
|
||||
QgsProcessingParameterDefinitionWidget( const QString &type,
|
||||
QgsProcessingContext &context,
|
||||
const QgsProcessingParameterWidgetContext &widgetContext,
|
||||
const QgsProcessingParameterDefinition *definition = nullptr,
|
||||
const QgsProcessingAlgorithm *algorithm = nullptr,
|
||||
QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Returns a new instance of a parameter definition, using the current settings defined in the dialog.
|
||||
*
|
||||
* The \a name parameter specifies the name for the newly created parameter.
|
||||
*/
|
||||
QgsProcessingParameterDefinition *createParameter( const QString &name = QString() ) const SIP_FACTORY;
|
||||
|
||||
private:
|
||||
|
||||
QString mType;
|
||||
QgsProcessingAbstractParameterDefinitionWidget *mDefinitionWidget = nullptr;
|
||||
QLineEdit *mDescriptionLineEdit = nullptr;
|
||||
QCheckBox *mRequiredCheckBox = nullptr;
|
||||
QCheckBox *mAdvancedCheckBox = nullptr;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* A dialog which allow users to specify the properties of a Processing parameter.
|
||||
*
|
||||
* \ingroup gui
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
class GUI_EXPORT QgsProcessingParameterDefinitionDialog: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsProcessingParameterDefinitionDialog, for a parameter of the
|
||||
* specified \a type.
|
||||
*
|
||||
* The \a context argument must specify a Processing context, which will be used
|
||||
* by the widget to evaluate existing \a definition properties such as default values. Similarly,
|
||||
* the \a widgetContext argument specifies the wider GUI context in which the widget
|
||||
* will be used.
|
||||
*
|
||||
* The optional \a definition argument may be used to provide a parameter definition to use
|
||||
* to initially populate the dialog's state.
|
||||
*
|
||||
* Additionally, the optional \a algorithm parameter may be used to specify the algorithm or model
|
||||
* associated with the parameter.
|
||||
*
|
||||
*/
|
||||
QgsProcessingParameterDefinitionDialog( const QString &type,
|
||||
QgsProcessingContext &context,
|
||||
const QgsProcessingParameterWidgetContext &widgetContext,
|
||||
const QgsProcessingParameterDefinition *definition = nullptr,
|
||||
const QgsProcessingAlgorithm *algorithm = nullptr,
|
||||
QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Returns a new instance of a parameter definition, using the current settings defined in the dialog.
|
||||
*
|
||||
* The \a name parameter specifies the name for the newly created parameter.
|
||||
*/
|
||||
QgsProcessingParameterDefinition *createParameter( const QString &name = QString() ) const SIP_FACTORY;
|
||||
|
||||
private:
|
||||
|
||||
QgsProcessingParameterDefinitionWidget *mWidget = nullptr;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // QGSPROCESSINGPARAMETERDEFINITIONWIDGET_H
|
@ -315,6 +315,13 @@ QgsProcessingModelerParameterWidget *QgsProcessingParameterWidgetFactoryInterfac
|
||||
return widget.release();
|
||||
}
|
||||
|
||||
QgsProcessingAbstractParameterDefinitionWidget *QgsProcessingParameterWidgetFactoryInterface::createParameterDefinitionWidget( QgsProcessingContext &,
|
||||
const QgsProcessingParameterWidgetContext &, const QgsProcessingParameterDefinition *,
|
||||
const QgsProcessingAlgorithm * )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QString QgsProcessingParameterWidgetFactoryInterface::modelerExpressionFormatString() const
|
||||
{
|
||||
return QString();
|
||||
|
@ -37,6 +37,7 @@ class QgsVectorLayer;
|
||||
class QgsProcessingModelAlgorithm;
|
||||
class QgsMapCanvas;
|
||||
class QgsProcessingAlgorithm;
|
||||
class QgsProcessingAbstractParameterDefinitionWidget;
|
||||
|
||||
/**
|
||||
* \class QgsProcessingContextGenerator
|
||||
@ -452,6 +453,36 @@ class GUI_EXPORT QgsProcessingParameterWidgetFactoryInterface
|
||||
const QgsProcessingParameterDefinition *parameter,
|
||||
QgsProcessingContext &context );
|
||||
|
||||
/**
|
||||
* Creates a new parameter definition widget allowing for configuration of an instance of
|
||||
* the parameter type handled by this factory.
|
||||
*
|
||||
* The \a context argument must specify a Processing context, which will be used
|
||||
* by the widget to evaluate existing \a definition properties such as default values. Similarly,
|
||||
* the \a widgetContext argument specifies the wider GUI context in which the widget
|
||||
* will be used.
|
||||
*
|
||||
* The optional \a definition argument may specify a parameter definition which
|
||||
* should be reflected in the initial state of the returned widget. Subclasses must
|
||||
* ensure that they correctly handle both the case when a initial \a definition is
|
||||
* passed, or when \a definition is NULLPTR (in which case sensible defaults should
|
||||
* be shown in the returned widget).
|
||||
*
|
||||
* Additionally, the optional \a algorithm parameter may be used to specify the algorithm or model
|
||||
* associated with the parameter.
|
||||
*
|
||||
* If a factory subclass returns NULLPTR for this method (i.e. as the base class implemention does),
|
||||
* it indicates that the parameter type cannot be configured via GUI. In this case the parameter
|
||||
* type will not be configurable when users add it as an input to their graphical models.
|
||||
*
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
virtual QgsProcessingAbstractParameterDefinitionWidget *createParameterDefinitionWidget(
|
||||
QgsProcessingContext &context,
|
||||
const QgsProcessingParameterWidgetContext &widgetContext,
|
||||
const QgsProcessingParameterDefinition *definition = nullptr,
|
||||
const QgsProcessingAlgorithm *algorithm = nullptr ) SIP_FACTORY;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#define SIP_NO_FILE
|
||||
#include "qgsprocessingwidgetwrapper.h"
|
||||
#include "qgsprocessingparameterdefinitionwidget.h"
|
||||
#include "qgsmaptool.h"
|
||||
|
||||
#include <QAbstractButton>
|
||||
|
@ -62,6 +62,7 @@
|
||||
#include "mesh/qgsmeshlayer.h"
|
||||
#include "mesh/qgsmeshdataprovider.h"
|
||||
#include "qgscolorbutton.h"
|
||||
#include "qgsprocessingparameterdefinitionwidget.h"
|
||||
|
||||
class TestParamType : public QgsProcessingParameterDefinition
|
||||
{
|
||||
@ -187,6 +188,7 @@ class TestProcessingGui : public QObject
|
||||
void testPointWrapper();
|
||||
void testColorWrapper();
|
||||
void mapLayerComboBox();
|
||||
void paramConfigWidget();
|
||||
|
||||
private:
|
||||
|
||||
@ -3546,6 +3548,34 @@ void TestProcessingGui::mapLayerComboBox()
|
||||
QgsProject::instance()->removeAllMapLayers();
|
||||
}
|
||||
|
||||
void TestProcessingGui::paramConfigWidget()
|
||||
{
|
||||
QgsProcessingContext context;
|
||||
QgsProcessingParameterWidgetContext widgetContext;
|
||||
std::unique_ptr< QgsProcessingParameterDefinitionWidget > widget = qgis::make_unique< QgsProcessingParameterDefinitionWidget >( QStringLiteral( "string" ), context, widgetContext );
|
||||
std::unique_ptr< QgsProcessingParameterDefinition > def( widget->createParameter( QStringLiteral( "param_name" ) ) );
|
||||
QCOMPARE( def->name(), QStringLiteral( "param_name" ) );
|
||||
QVERIFY( !( def->flags() & QgsProcessingParameterDefinition::FlagOptional ) ); // should default to mandatory
|
||||
QVERIFY( !( def->flags() & QgsProcessingParameterDefinition::FlagAdvanced ) );
|
||||
|
||||
// using a parameter definition as initial values
|
||||
def->setDescription( QStringLiteral( "test desc" ) );
|
||||
def->setFlags( QgsProcessingParameterDefinition::FlagOptional );
|
||||
widget = qgis::make_unique< QgsProcessingParameterDefinitionWidget >( QStringLiteral( "string" ), context, widgetContext, def.get() );
|
||||
def.reset( widget->createParameter( QStringLiteral( "param_name" ) ) );
|
||||
QCOMPARE( def->name(), QStringLiteral( "param_name" ) );
|
||||
QCOMPARE( def->description(), QStringLiteral( "test desc" ) );
|
||||
QVERIFY( def->flags() & QgsProcessingParameterDefinition::FlagOptional );
|
||||
QVERIFY( !( def->flags() & QgsProcessingParameterDefinition::FlagAdvanced ) );
|
||||
def->setFlags( QgsProcessingParameterDefinition::FlagAdvanced );
|
||||
widget = qgis::make_unique< QgsProcessingParameterDefinitionWidget >( QStringLiteral( "string" ), context, widgetContext, def.get() );
|
||||
def.reset( widget->createParameter( QStringLiteral( "param_name" ) ) );
|
||||
QCOMPARE( def->name(), QStringLiteral( "param_name" ) );
|
||||
QCOMPARE( def->description(), QStringLiteral( "test desc" ) );
|
||||
QVERIFY( !( def->flags() & QgsProcessingParameterDefinition::FlagOptional ) );
|
||||
QVERIFY( def->flags() & QgsProcessingParameterDefinition::FlagAdvanced );
|
||||
}
|
||||
|
||||
void TestProcessingGui::cleanupTempDir()
|
||||
{
|
||||
QDir tmpDir = QDir( mTempDir );
|
||||
|
Loading…
x
Reference in New Issue
Block a user