mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-15 00:02:52 -04:00
Move parameter retrieval logic from dialog to ParametersPanel
This is cleaner, because the panel owns all the wrappers required to evaluate the parameter values
This commit is contained in:
parent
a80bdc47e5
commit
d69519a91e
@ -21,33 +21,21 @@ __author__ = 'Victor Olaya'
|
||||
__date__ = 'August 2012'
|
||||
__copyright__ = '(C) 2012, Victor Olaya'
|
||||
|
||||
import os
|
||||
from pprint import pformat
|
||||
import time
|
||||
|
||||
from qgis.PyQt.QtCore import QCoreApplication, Qt
|
||||
from qgis.PyQt.QtWidgets import QMessageBox, QPushButton, QSizePolicy, QDialogButtonBox
|
||||
from qgis.PyQt.QtCore import QCoreApplication
|
||||
from qgis.PyQt.QtWidgets import QMessageBox, QPushButton, QDialogButtonBox
|
||||
from qgis.PyQt.QtGui import QColor, QPalette
|
||||
|
||||
from qgis.core import (Qgis,
|
||||
QgsProject,
|
||||
QgsApplication,
|
||||
QgsProcessingUtils,
|
||||
QgsProcessingParameterDefinition,
|
||||
QgsProcessingAlgRunnerTask,
|
||||
QgsProcessingOutputHtml,
|
||||
QgsProcessingParameterVectorDestination,
|
||||
QgsProcessingOutputLayerDefinition,
|
||||
QgsProcessingParameterFeatureSink,
|
||||
QgsProcessingParameterRasterDestination,
|
||||
QgsProcessingAlgorithm,
|
||||
QgsProcessingParameters,
|
||||
QgsProxyProgressTask,
|
||||
QgsTaskManager,
|
||||
QgsProcessingFeatureSourceDefinition)
|
||||
from qgis.gui import (QgsGui,
|
||||
QgsMessageBar,
|
||||
QgsProcessingLayerOutputDestinationWidget,
|
||||
QgsProcessingAlgorithmDialogBase)
|
||||
from qgis.utils import iface
|
||||
|
||||
@ -59,7 +47,6 @@ from processing.gui.BatchAlgorithmDialog import BatchAlgorithmDialog
|
||||
from processing.gui.AlgorithmDialogBase import AlgorithmDialogBase
|
||||
from processing.gui.AlgorithmExecutor import executeIterating, execute, execute_in_place
|
||||
from processing.gui.Postprocessing import handleAlgorithmResults
|
||||
from processing.gui.wrappers import WidgetWrapper
|
||||
|
||||
from processing.tools import dataobjects
|
||||
|
||||
@ -82,20 +69,23 @@ class AlgorithmDialog(QgsProcessingAlgorithmDialogBase):
|
||||
if not self.in_place:
|
||||
self.runAsBatchButton = QPushButton(QCoreApplication.translate("AlgorithmDialog", "Run as Batch Process…"))
|
||||
self.runAsBatchButton.clicked.connect(self.runAsBatch)
|
||||
self.buttonBox().addButton(self.runAsBatchButton, QDialogButtonBox.ResetRole) # reset role to ensure left alignment
|
||||
self.buttonBox().addButton(self.runAsBatchButton,
|
||||
QDialogButtonBox.ResetRole) # reset role to ensure left alignment
|
||||
else:
|
||||
self.active_layer = iface.activeLayer()
|
||||
self.runAsBatchButton = None
|
||||
has_selection = self.active_layer and (self.active_layer.selectedFeatureCount() > 0)
|
||||
self.buttonBox().button(QDialogButtonBox.Ok).setText(QCoreApplication.translate("AlgorithmDialog", "Modify Selected Features")
|
||||
if has_selection else QCoreApplication.translate("AlgorithmDialog", "Modify All Features"))
|
||||
self.buttonBox().button(QDialogButtonBox.Close).setText(QCoreApplication.translate("AlgorithmDialog", "Cancel"))
|
||||
self.buttonBox().button(QDialogButtonBox.Ok).setText(
|
||||
QCoreApplication.translate("AlgorithmDialog", "Modify Selected Features")
|
||||
if has_selection else QCoreApplication.translate("AlgorithmDialog", "Modify All Features"))
|
||||
self.buttonBox().button(QDialogButtonBox.Close).setText(
|
||||
QCoreApplication.translate("AlgorithmDialog", "Cancel"))
|
||||
self.setWindowTitle(self.windowTitle() + ' | ' + self.active_layer.name())
|
||||
|
||||
self.updateRunButtonVisibility()
|
||||
|
||||
def getParametersPanel(self, alg, parent):
|
||||
panel = ParametersPanel(parent, alg, self.in_place, parameters_generator=self)
|
||||
panel = ParametersPanel(parent, alg, self.in_place)
|
||||
return panel
|
||||
|
||||
def runAsBatch(self):
|
||||
@ -116,70 +106,10 @@ class AlgorithmDialog(QgsProcessingAlgorithmDialogBase):
|
||||
self.mainWidget().setParameters(parameters)
|
||||
|
||||
def createProcessingParameters(self):
|
||||
parameters = {}
|
||||
|
||||
if self.mainWidget() is None:
|
||||
return parameters
|
||||
|
||||
for param in self.algorithm().parameterDefinitions():
|
||||
if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||
continue
|
||||
if not param.isDestination():
|
||||
|
||||
if self.in_place and param.name() == 'INPUT':
|
||||
parameters[param.name()] = self.active_layer
|
||||
continue
|
||||
|
||||
try:
|
||||
wrapper = self.mainWidget().wrappers[param.name()]
|
||||
except KeyError:
|
||||
continue
|
||||
|
||||
# For compatibility with 3.x API, we need to check whether the wrapper is
|
||||
# the deprecated WidgetWrapper class. If not, it's the newer
|
||||
# QgsAbstractProcessingParameterWidgetWrapper class
|
||||
# TODO QGIS 4.0 - remove
|
||||
if issubclass(wrapper.__class__, WidgetWrapper):
|
||||
widget = wrapper.widget
|
||||
else:
|
||||
widget = wrapper.wrappedWidget()
|
||||
|
||||
if widget is None:
|
||||
continue
|
||||
|
||||
value = wrapper.parameterValue()
|
||||
parameters[param.name()] = value
|
||||
|
||||
if not param.checkValueIsAcceptable(value):
|
||||
raise AlgorithmDialogBase.InvalidParameterValue(param, widget)
|
||||
else:
|
||||
if self.in_place and param.name() == 'OUTPUT':
|
||||
parameters[param.name()] = 'memory:'
|
||||
continue
|
||||
|
||||
try:
|
||||
wrapper = self.mainWidget().wrappers[param.name()]
|
||||
except KeyError:
|
||||
continue
|
||||
|
||||
widget = wrapper.wrappedWidget()
|
||||
value = wrapper.parameterValue()
|
||||
|
||||
dest_project = None
|
||||
if wrapper.customProperties().get('OPEN_AFTER_RUNNING'):
|
||||
dest_project = QgsProject.instance()
|
||||
|
||||
if value and isinstance(value, QgsProcessingOutputLayerDefinition):
|
||||
value.destinationProject = dest_project
|
||||
if value:
|
||||
parameters[param.name()] = value
|
||||
if param.isDestination():
|
||||
context = dataobjects.createContext()
|
||||
ok, error = self.algorithm().provider().isSupportedOutputValue(value, param, context)
|
||||
if not ok:
|
||||
raise AlgorithmDialogBase.InvalidOutputExtension(widget, error)
|
||||
|
||||
return self.algorithm().preprocessParameters(parameters)
|
||||
return {}
|
||||
else:
|
||||
return self.mainWidget().createProcessingParameters()
|
||||
|
||||
def runAlgorithm(self):
|
||||
self.feedback = self.createFeedback()
|
||||
@ -211,7 +141,8 @@ class AlgorithmDialog(QgsProcessingAlgorithmDialogBase):
|
||||
self.iterateParam = None
|
||||
|
||||
for param in self.algorithm().parameterDefinitions():
|
||||
if isinstance(parameters.get(param.name(), None), QgsProcessingFeatureSourceDefinition) and parameters[param.name()].flags & QgsProcessingFeatureSourceDefinition.FlagCreateIndividualOutputPerInputFeature:
|
||||
if isinstance(parameters.get(param.name(), None), QgsProcessingFeatureSourceDefinition) and parameters[
|
||||
param.name()].flags & QgsProcessingFeatureSourceDefinition.FlagCreateIndividualOutputPerInputFeature:
|
||||
self.iterateParam = param.name()
|
||||
break
|
||||
|
||||
@ -223,12 +154,14 @@ class AlgorithmDialog(QgsProcessingAlgorithmDialogBase):
|
||||
self.setProgressText(QCoreApplication.translate('AlgorithmDialog', 'Processing algorithm…'))
|
||||
|
||||
self.setInfo(
|
||||
QCoreApplication.translate('AlgorithmDialog', '<b>Algorithm \'{0}\' starting…</b>').format(self.algorithm().displayName()), escapeHtml=False)
|
||||
QCoreApplication.translate('AlgorithmDialog', '<b>Algorithm \'{0}\' starting…</b>').format(
|
||||
self.algorithm().displayName()), escapeHtml=False)
|
||||
|
||||
self.feedback.pushInfo(self.tr('Input parameters:'))
|
||||
display_params = []
|
||||
for k, v in parameters.items():
|
||||
display_params.append("'" + k + "' : " + self.algorithm().parameterDefinition(k).valueAsPythonString(v, self.context))
|
||||
display_params.append(
|
||||
"'" + k + "' : " + self.algorithm().parameterDefinition(k).valueAsPythonString(v, self.context))
|
||||
self.feedback.pushCommandInfo('{ ' + ', '.join(display_params) + ' }')
|
||||
self.feedback.pushInfo('')
|
||||
start_time = time.time()
|
||||
@ -259,7 +192,8 @@ class AlgorithmDialog(QgsProcessingAlgorithmDialogBase):
|
||||
|
||||
def on_complete(ok, results):
|
||||
if ok:
|
||||
self.feedback.pushInfo(self.tr('Execution completed in {0:0.2f} seconds').format(time.time() - start_time))
|
||||
self.feedback.pushInfo(
|
||||
self.tr('Execution completed in {0:0.2f} seconds').format(time.time() - start_time))
|
||||
self.feedback.pushInfo(self.tr('Results:'))
|
||||
r = {k: v for k, v in results.items() if k not in ('CHILD_RESULTS', 'CHILD_INPUTS')}
|
||||
self.feedback.pushCommandInfo(pformat(r))
|
||||
@ -291,7 +225,9 @@ class AlgorithmDialog(QgsProcessingAlgorithmDialogBase):
|
||||
task.executed.connect(on_complete)
|
||||
self.setCurrentTask(task)
|
||||
else:
|
||||
self.proxy_progress = QgsProxyProgressTask(QCoreApplication.translate("AlgorithmDialog", "Executing “{}”").format(self.algorithm().displayName()))
|
||||
self.proxy_progress = QgsProxyProgressTask(
|
||||
QCoreApplication.translate("AlgorithmDialog", "Executing “{}”").format(
|
||||
self.algorithm().displayName()))
|
||||
QgsApplication.taskManager().addTask(self.proxy_progress)
|
||||
self.feedback.progressChanged.connect(self.proxy_progress.setProxyProgress)
|
||||
self.feedback_dialog = self.createProgressDialog()
|
||||
@ -314,8 +250,9 @@ class AlgorithmDialog(QgsProcessingAlgorithmDialogBase):
|
||||
except:
|
||||
pass
|
||||
self.messageBar().clearWidgets()
|
||||
self.messageBar().pushMessage("", self.tr("Wrong or missing parameter value: {0}").format(e.parameter.description()),
|
||||
level=Qgis.Warning, duration=5)
|
||||
self.messageBar().pushMessage("", self.tr("Wrong or missing parameter value: {0}").format(
|
||||
e.parameter.description()),
|
||||
level=Qgis.Warning, duration=5)
|
||||
except AlgorithmDialogBase.InvalidOutputExtension as e:
|
||||
try:
|
||||
self.buttonBox().accepted.connect(lambda e=e:
|
||||
@ -337,7 +274,8 @@ class AlgorithmDialog(QgsProcessingAlgorithmDialogBase):
|
||||
# add html results to results dock
|
||||
for out in self.algorithm().outputDefinitions():
|
||||
if isinstance(out, QgsProcessingOutputHtml) and out.name() in result and result[out.name()]:
|
||||
resultsList.addResult(icon=self.algorithm().icon(), name=out.description(), timestamp=time.localtime(),
|
||||
resultsList.addResult(icon=self.algorithm().icon(), name=out.description(),
|
||||
timestamp=time.localtime(),
|
||||
result=result[out.name()])
|
||||
if not handleAlgorithmResults(self.algorithm(), context, feedback, not keepOpen, result):
|
||||
self.resetGui()
|
||||
|
@ -28,7 +28,8 @@ __copyright__ = '(C) 2012, Victor Olaya'
|
||||
from qgis.core import (QgsProcessingParameterDefinition,
|
||||
QgsProcessingParameterExtent,
|
||||
QgsProject,
|
||||
QgsProcessingModelAlgorithm)
|
||||
QgsProcessingModelAlgorithm,
|
||||
QgsProcessingOutputLayerDefinition)
|
||||
from qgis.gui import (QgsProcessingContextGenerator,
|
||||
QgsProcessingParameterWidgetContext,
|
||||
QgsProcessingParametersWidget,
|
||||
@ -38,19 +39,19 @@ from qgis.gui import (QgsProcessingContextGenerator,
|
||||
from qgis.utils import iface
|
||||
|
||||
from processing.gui.wrappers import WidgetWrapperFactory, WidgetWrapper
|
||||
from processing.gui.AlgorithmDialogBase import AlgorithmDialogBase
|
||||
from processing.tools.dataobjects import createContext
|
||||
|
||||
|
||||
class ParametersPanel(QgsProcessingParametersWidget, QgsProcessingParametersGenerator):
|
||||
|
||||
def __init__(self, parent, alg, in_place=False, parameters_generator=None):
|
||||
def __init__(self, parent, alg, in_place=False):
|
||||
super().__init__(alg, parent)
|
||||
self.in_place = in_place
|
||||
|
||||
self.wrappers = {}
|
||||
|
||||
self.processing_context = createContext()
|
||||
self.processing_parameters_generator = parameters_generator
|
||||
|
||||
class ContextGenerator(QgsProcessingContextGenerator):
|
||||
|
||||
@ -100,7 +101,7 @@ class ParametersPanel(QgsProcessingParametersWidget, QgsProcessingParametersGene
|
||||
wrapper = WidgetWrapperFactory.create_wrapper(param, self.parent())
|
||||
wrapper.setWidgetContext(widget_context)
|
||||
wrapper.registerProcessingContextGenerator(self.context_generator)
|
||||
wrapper.registerProcessingParametersGenerator(self.processing_parameters_generator)
|
||||
wrapper.registerProcessingParametersGenerator(self)
|
||||
self.wrappers[param.name()] = wrapper
|
||||
|
||||
# For compatibility with 3.x API, we need to check whether the wrapper is
|
||||
@ -152,7 +153,7 @@ class ParametersPanel(QgsProcessingParametersWidget, QgsProcessingParametersGene
|
||||
wrapper = QgsGui.processingGuiRegistry().createParameterWidgetWrapper(output, QgsProcessingGui.Standard)
|
||||
wrapper.setWidgetContext(widget_context)
|
||||
wrapper.registerProcessingContextGenerator(self.context_generator)
|
||||
wrapper.registerProcessingParametersGenerator(self.processing_parameters_generator)
|
||||
wrapper.registerProcessingParametersGenerator(self)
|
||||
self.wrappers[output.name()] = wrapper
|
||||
|
||||
label = wrapper.createWrappedLabel()
|
||||
@ -185,6 +186,69 @@ class ParametersPanel(QgsProcessingParametersWidget, QgsProcessingParametersGene
|
||||
for wrapper in list(self.wrappers.values()):
|
||||
wrapper.postInitialize(list(self.wrappers.values()))
|
||||
|
||||
def createProcessingParameters(self):
|
||||
parameters = {}
|
||||
|
||||
for param in self.algorithm().parameterDefinitions():
|
||||
if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||
continue
|
||||
if not param.isDestination():
|
||||
|
||||
if self.in_place and param.name() == 'INPUT':
|
||||
parameters[param.name()] = self.active_layer
|
||||
continue
|
||||
|
||||
try:
|
||||
wrapper = self.wrappers[param.name()]
|
||||
except KeyError:
|
||||
continue
|
||||
|
||||
# For compatibility with 3.x API, we need to check whether the wrapper is
|
||||
# the deprecated WidgetWrapper class. If not, it's the newer
|
||||
# QgsAbstractProcessingParameterWidgetWrapper class
|
||||
# TODO QGIS 4.0 - remove
|
||||
if issubclass(wrapper.__class__, WidgetWrapper):
|
||||
widget = wrapper.widget
|
||||
else:
|
||||
widget = wrapper.wrappedWidget()
|
||||
|
||||
if widget is None:
|
||||
continue
|
||||
|
||||
value = wrapper.parameterValue()
|
||||
parameters[param.name()] = value
|
||||
|
||||
if not param.checkValueIsAcceptable(value):
|
||||
raise AlgorithmDialogBase.InvalidParameterValue(param, widget)
|
||||
else:
|
||||
if self.in_place and param.name() == 'OUTPUT':
|
||||
parameters[param.name()] = 'memory:'
|
||||
continue
|
||||
|
||||
try:
|
||||
wrapper = self.wrappers[param.name()]
|
||||
except KeyError:
|
||||
continue
|
||||
|
||||
widget = wrapper.wrappedWidget()
|
||||
value = wrapper.parameterValue()
|
||||
|
||||
dest_project = None
|
||||
if wrapper.customProperties().get('OPEN_AFTER_RUNNING'):
|
||||
dest_project = QgsProject.instance()
|
||||
|
||||
if value and isinstance(value, QgsProcessingOutputLayerDefinition):
|
||||
value.destinationProject = dest_project
|
||||
if value:
|
||||
parameters[param.name()] = value
|
||||
if param.isDestination():
|
||||
context = createContext()
|
||||
ok, error = self.algorithm().provider().isSupportedOutputValue(value, param, context)
|
||||
if not ok:
|
||||
raise AlgorithmDialogBase.InvalidOutputExtension(widget, error)
|
||||
|
||||
return self.algorithm().preprocessParameters(parameters)
|
||||
|
||||
def setParameters(self, parameters):
|
||||
for param in self.algorithm().parameterDefinitions():
|
||||
if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
|
||||
|
Loading…
x
Reference in New Issue
Block a user