Refactor Algorithm setParamValues -> getParamValues

Now returns a dict of parameter inputs for the algorithm
This commit is contained in:
Nyall Dawson 2017-05-15 16:16:32 +10:00
parent 9997ab6e1e
commit f1c53c3aa4
6 changed files with 106 additions and 55 deletions

View File

@ -107,10 +107,10 @@ class GdalParametersPanel(ParametersPanel):
def parametersHaveChanged(self):
try:
self.parent.setParamValues()
for output in self.alg.outputs:
if output.value is None:
output.value = self.tr("[temporary file]")
parameters = self.parent.getParamValues()
for output in self.alg.destinationParameterDefinitions():
if parameters[output.name()] is None:
parameters[output.name()] = self.tr("[temporary file]")
commands = self.alg.getConsoleCommands()
commands = [c for c in commands if c not in ['cmd.exe', '/C ']]
self.text.setPlainText(" ".join(commands))

View File

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
"""
***************************************************************************
QgisAlgorithm.py
----------------
Date : May 2017
Copyright : (C) 2017 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. *
* *
***************************************************************************
"""
__author__ = 'Nyall Dawson'
__date__ = 'May2017'
__copyright__ = '(C) 2017, Nyall Dawson'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
from processing.core import GeoAlgorithm
from processing.algs.help import shortHelp
class QgisAlgorithm(QgisAlgorithm):
def __init__(self):
super().__init__()
def shortHelpString(self):
return shortHelp.get(self.id(), None)

View File

@ -31,7 +31,8 @@ from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QPushButton, QWidget,
from qgis.PyQt.QtGui import QCursor, QColor, QPalette
from qgis.core import (QgsProject,
QgsProcessingUtils)
QgsProcessingUtils,
QgsProcessingParameterDefinition)
from qgis.gui import QgsMessageBar
from qgis.utils import iface
@ -88,23 +89,26 @@ class AlgorithmDialog(AlgorithmDialogBase):
dlg.show()
dlg.exec_()
def setParamValues(self):
params = self.alg.parameters
outputs = self.alg.outputs
def getParamValues(self):
parameters = {}
for param in params:
if param.hidden:
for param in self.alg.parameterDefinitions():
if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
continue
wrapper = self.mainWidget.wrappers[param.name]
if not self.setParamValue(param, wrapper):
raise AlgorithmDialogBase.InvalidParameterValue(param, wrapper.widget)
if not param.isDestination():
wrapper = self.mainWidget.wrappers[param.name()]
if wrapper.widget:
value = wrapper.value()
parameters[param.name()] = value
for output in outputs:
if output.hidden:
continue
output.value = self.mainWidget.outputWidgets[output.name].getValue()
if isinstance(output, (OutputRaster, OutputVector, OutputTable)):
output.open = self.mainWidget.checkBoxes[output.name].isChecked()
#TODO
#if not self.setParamValue(param, wrapper):
# raise AlgorithmDialogBase.InvalidParameterValue(param, wrapper.widget)
else:
parameters[param.name()] = self.mainWidget.outputWidgets[param.name()].getValue()
# TODO
#if isinstance(output, (OutputRaster, OutputVector, OutputTable)):
# output.open = self.mainWidget.checkBoxes[param.name()].isChecked()
return True
@ -154,7 +158,7 @@ class AlgorithmDialog(AlgorithmDialogBase):
checkCRS = ProcessingConfig.getSetting(ProcessingConfig.WARN_UNMATCHING_CRS)
try:
self.setParamValues()
parameters = self.getParamValues()
if checkCRS and not self.alg.checkInputCRS():
reply = QMessageBox.question(self, self.tr("Unmatching CRS's"),
self.tr('Layers do not all use the same CRS. This can '

View File

@ -219,8 +219,8 @@ class AlgorithmDialogBase(BASE, WIDGET):
self.setInfo(text, False)
QCoreApplication.processEvents()
def setParamValues(self):
pass
def getParamValues(self):
return {}
def setParamValue(self, param, widget, alg=None):
pass

View File

@ -36,7 +36,8 @@ from qgis.PyQt.QtGui import QCursor
from qgis.gui import QgsEncodingFileDialog, QgsExpressionBuilderDialog
from qgis.core import (QgsDataSourceUri,
QgsCredentials,
QgsSettings)
QgsSettings,
QgsProcessingOutputVectorLayer)
from processing.core.ProcessingConfig import ProcessingConfig
from processing.core.outputs import OutputVector
from processing.core.outputs import OutputDirectory
@ -47,22 +48,22 @@ WIDGET, BASE = uic.loadUiType(
os.path.join(pluginPath, 'ui', 'widgetBaseSelector.ui'))
class OutputSelectionPanel(BASE, WIDGET):
class DestinationSelectionPanel(BASE, WIDGET):
SAVE_TO_TEMP_FILE = QCoreApplication.translate(
'OutputSelectionPanel', '[Save to temporary file]')
'DestinationSelectionPanel', '[Save to temporary file]')
SAVE_TO_TEMP_LAYER = QCoreApplication.translate(
'OutputSelectionPanel', '[Create temporary layer]')
'DestinationSelectionPanel', '[Create temporary layer]')
def __init__(self, output, alg):
super(OutputSelectionPanel, self).__init__(None)
def __init__(self, parameter, alg):
super(DestinationSelectionPanel, self).__init__(None)
self.setupUi(self)
self.output = output
self.parameter = parameter
self.alg = alg
if hasattr(self.leText, 'setPlaceholderText'):
if isinstance(output, OutputVector) \
if isinstance(self.parameter, QgsProcessingOutputVectorLayer) \
and alg.provider().supportsNonFileBasedOutput():
# use memory layers for temporary files if supported
self.leText.setPlaceholderText(self.SAVE_TO_TEMP_LAYER)
@ -72,12 +73,12 @@ class OutputSelectionPanel(BASE, WIDGET):
self.btnSelect.clicked.connect(self.selectOutput)
def selectOutput(self):
if isinstance(self.output, OutputDirectory):
if isinstance(self.parameter, OutputDirectory):
self.selectDirectory()
else:
popupMenu = QMenu()
if isinstance(self.output, OutputVector) \
if isinstance(self.parameter, QgsProcessingOutputVectorLayer) \
and self.alg.provider().supportsNonFileBasedOutput():
# use memory layers for temporary layers if supported
actionSaveToTemp = QAction(
@ -98,7 +99,7 @@ class OutputSelectionPanel(BASE, WIDGET):
actionShowExpressionsBuilder.triggered.connect(self.showExpressionsBuilder)
popupMenu.addAction(actionShowExpressionsBuilder)
if isinstance(self.output, OutputVector) \
if isinstance(self.parameter, QgsProcessingOutputVectorLayer) \
and self.alg.provider().supportsNonFileBasedOutput():
actionSaveToSpatialite = QAction(
self.tr('Save to Spatialite table...'), self.btnSelect)
@ -118,7 +119,7 @@ class OutputSelectionPanel(BASE, WIDGET):
def showExpressionsBuilder(self):
dlg = QgsExpressionBuilderDialog(None, self.leText.text(), self, 'generic',
self.output.expressionContext(self.alg))
self.parameter.expressionContext(self.alg))
dlg.setWindowTitle(self.tr('Expression based output'))
if dlg.exec_() == QDialog.Accepted:
self.leText.setText(dlg.expressionText())
@ -127,7 +128,7 @@ class OutputSelectionPanel(BASE, WIDGET):
self.leText.setText('')
def saveToPostGIS(self):
dlg = PostgisTableSelector(self, self.output.name.lower())
dlg = PostgisTableSelector(self, self.parameter.name().lower())
dlg.exec_()
if dlg.connection:
settings = QgsSettings()
@ -140,7 +141,7 @@ class OutputSelectionPanel(BASE, WIDGET):
uri = QgsDataSourceUri()
uri.setConnection(host, str(port), dbname, user, password)
uri.setDataSource(dlg.schema, dlg.table,
"the_geom" if self.output.hasGeometry() else None)
"the_geom" if self.parameter.hasGeometry() else None)
connInfo = uri.connectionInfo()
(success, user, passwd) = QgsCredentials.instance().get(connInfo, None, None)
@ -149,7 +150,7 @@ class OutputSelectionPanel(BASE, WIDGET):
self.leText.setText("postgis:" + uri.uri())
def saveToSpatialite(self):
fileFilter = self.output.tr('SpatiaLite files (*.sqlite)', 'OutputFile')
fileFilter = self.tr('SpatiaLite files (*.sqlite)', 'OutputFile')
settings = QgsSettings()
if settings.contains('/Processing/LastOutputPath'):
@ -167,7 +168,7 @@ class OutputSelectionPanel(BASE, WIDGET):
if fileDialog.exec_() == QDialog.Accepted:
files = fileDialog.selectedFiles()
encoding = str(fileDialog.encoding())
self.output.encoding = encoding
self.parameter.encoding = encoding
fileName = str(files[0])
selectedFileFilter = str(fileDialog.selectedNameFilter())
if not fileName.lower().endswith(
@ -181,12 +182,12 @@ class OutputSelectionPanel(BASE, WIDGET):
uri = QgsDataSourceUri()
uri.setDatabase(fileName)
uri.setDataSource('', self.output.name.lower(),
'the_geom' if self.output.hasGeometry() else None)
uri.setDataSource('', self.parameter.name().lower(),
'the_geom' if self.parameter.hasGeometry() else None)
self.leText.setText("spatialite:" + uri.uri())
def selectFile(self):
fileFilter = self.output.getFileFilter(self.alg)
fileFilter = self.parameter.getFileFilter(self.alg)
settings = QgsSettings()
if settings.contains('/Processing/LastOutputPath'):
@ -204,7 +205,7 @@ class OutputSelectionPanel(BASE, WIDGET):
if fileDialog.exec_() == QDialog.Accepted:
files = fileDialog.selectedFiles()
encoding = str(fileDialog.encoding())
self.output.encoding = encoding
self.parameter.encoding = encoding
fileName = str(files[0])
selectedFileFilter = str(fileDialog.selectedNameFilter())
if not fileName.lower().endswith(

View File

@ -34,14 +34,16 @@ import os
from qgis.core import (QgsProcessingParameterDefinition,
QgsProcessingParameterExtent,
QgsProcessingParameterPoint,
QgsProcessingParameterVectorLayer)
QgsProcessingParameterVectorLayer,
QgsProcessingOutputVectorLayer,
QgsProcessingParameterOutputVectorLayer)
from qgis.PyQt import uic
from qgis.PyQt.QtCore import QCoreApplication
from qgis.PyQt.QtWidgets import (QWidget, QHBoxLayout, QToolButton,
QLabel, QCheckBox)
from qgis.PyQt.QtGui import QIcon
from processing.gui.OutputSelectionPanel import OutputSelectionPanel
from processing.gui.DestinationSelectionPanel import DestinationSelectionPanel
from processing.gui.wrappers import WidgetWrapperFactory
from processing.core.parameters import ParameterVector, ParameterExtent, ParameterPoint
from processing.core.outputs import OutputRaster
@ -93,17 +95,7 @@ class ParametersPanel(BASE, WIDGET):
continue
if param.isDestination():
label = QLabel(param.description())
widget = OutputSelectionPanel(param, self.alg)
self.layoutMain.insertWidget(self.layoutMain.count() - 1, label)
self.layoutMain.insertWidget(self.layoutMain.count() - 1, widget)
if isinstance(param, (OutputRaster, QgsProcessingParameterOutputVectorLayer, OutputTable)):
check = QCheckBox()
check.setText(self.tr('Open output file after running algorithm'))
check.setChecked(True)
self.layoutMain.insertWidget(self.layoutMain.count() - 1, check)
self.checkBoxes[param.name()] = check
self.outputWidgets[param.name()] = widget
continue
else:
desc = param.description()
if isinstance(param, QgsProcessingParameterExtent):
@ -157,6 +149,22 @@ class ParametersPanel(BASE, WIDGET):
self.layoutMain.insertWidget(
self.layoutMain.count() - 2, widget)
for output in self.alg.destinationParameterDefinitions():
if output.flags() & QgsProcessingParameterDefinition.FlagHidden:
continue
label = QLabel(output.description())
widget = DestinationSelectionPanel(output, self.alg)
self.layoutMain.insertWidget(self.layoutMain.count() - 1, label)
self.layoutMain.insertWidget(self.layoutMain.count() - 1, widget)
if isinstance(output, (OutputRaster, QgsProcessingParameterOutputVectorLayer, OutputTable)):
check = QCheckBox()
check.setText(self.tr('Open output file after running algorithm'))
check.setChecked(True)
self.layoutMain.insertWidget(self.layoutMain.count() - 1, check)
self.checkBoxes[output.name()] = check
self.outputWidgets[output.name()] = widget
for wrapper in list(self.wrappers.values()):
wrapper.postInitialize(list(self.wrappers.values()))