Skip to content

Commit ac0bff3

Browse files
committedApr 25, 2016
[processing] added support for expressions in some input params and outputs
1 parent a7c3861 commit ac0bff3

File tree

3 files changed

+67
-13
lines changed

3 files changed

+67
-13
lines changed
 

‎python/plugins/processing/gui/AlgorithmDialog.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from PyQt.QtWidgets import QMessageBox, QApplication, QPushButton, QWidget, QVBoxLayout
3030
from PyQt.QtGui import QCursor, QColor, QPalette
3131

32-
from qgis.core import QgsMapLayerRegistry
32+
from qgis.core import QgsMapLayerRegistry, QgsExpressionContext, QgsExpressionContextUtils, QgsExpression
3333

3434
from processing.core.ProcessingLog import ProcessingLog
3535
from processing.core.ProcessingConfig import ProcessingConfig
@@ -102,8 +102,8 @@ def setParamValues(self):
102102
continue
103103
if not self.setParamValue(
104104
param, self.mainWidget.valueItems[param.name]):
105-
raise AlgorithmDialogBase.InvalidParameterValue(param,
106-
self.mainWidget.valueItems[param.name])
105+
raise AlgorithmDialogBase.InvalidParameterValue(
106+
param, self.mainWidget.valueItems[param.name])
107107

108108
for param in params:
109109
if isinstance(param, ParameterExtent):
@@ -121,6 +121,18 @@ def setParamValues(self):
121121

122122
return True
123123

124+
def evaluateExpression(self, text):
125+
context = QgsExpressionContext()
126+
context.appendScope(QgsExpressionContextUtils.projectScope())
127+
exp = QgsExpression(text)
128+
if exp.hasParserError():
129+
raise Exception(exp.parserErrorString())
130+
result = exp.evaluate(context)
131+
if exp.hasEvalError():
132+
raise ValueError(exp.evalErrorString())
133+
return result
134+
135+
124136
def setParamValue(self, param, widget, alg=None):
125137
if isinstance(param, ParameterRaster):
126138
return param.setValue(widget.getValue())
@@ -159,7 +171,12 @@ def setParamValue(self, param, widget, alg=None):
159171
if param.multiline:
160172
return param.setValue(unicode(widget.toPlainText()))
161173
else:
162-
return param.setValue(unicode(widget.text()))
174+
text = widget.text()
175+
try:
176+
text = self.evaluateExpression(text)
177+
except:
178+
return False
179+
return param.setValue(text)
163180
elif isinstance(param, ParameterGeometryPredicate):
164181
return param.setValue(widget.value())
165182
else:

‎python/plugins/processing/gui/NumberInputPanel.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,12 @@
2929

3030
from PyQt import uic
3131
from PyQt.QtCore import pyqtSignal
32+
from PyQt.QtGui import QDialog
3233

3334
from math import log10, floor
34-
from processing.gui.NumberInputDialog import NumberInputDialog
35+
from qgis.core import (QgsDataSourceURI, QgsCredentials, QgsExpressionContext,
36+
QgsExpressionContextUtils, QgsExpression)
37+
from qgis.gui import QgsEncodingFileDialog, QgsExpressionBuilderDialog
3538

3639
pluginPath = os.path.split(os.path.dirname(__file__))[0]
3740
WIDGET, BASE = uic.loadUiType(
@@ -46,6 +49,7 @@ def __init__(self, number, minimum, maximum, isInteger):
4649
super(NumberInputPanel, self).__init__(None)
4750
self.setupUi(self)
4851

52+
self.spnValue.setExpressionsEnabled(True)
4953
self.isInteger = isInteger
5054
if self.isInteger:
5155
self.spnValue.setDecimals(0)
@@ -74,15 +78,27 @@ def __init__(self, number, minimum, maximum, isInteger):
7478
self.spnValue.setValue(0)
7579
self.spnValue.setClearValue(0)
7680

77-
self.btnCalc.clicked.connect(self.showNumberInputDialog)
81+
self.btnCalc.setFixedHeight(self.spnValue.height())
82+
83+
self.btnCalc.clicked.connect(self.showExpressionsBuilder)
7884

7985
self.spnValue.valueChanged.connect(lambda: self.hasChanged.emit())
8086

81-
def showNumberInputDialog(self):
82-
dlg = NumberInputDialog(self.isInteger)
83-
dlg.exec_()
84-
if dlg.value is not None:
85-
self.spnValue.setValue(dlg.value)
87+
def showExpressionsBuilder(self):
88+
context = QgsExpressionContext()
89+
context.appendScope(QgsExpressionContextUtils.globalScope())
90+
context.appendScope(QgsExpressionContextUtils.projectScope())
91+
dlg = QgsExpressionBuilderDialog(None, self.spnValue.text(), self, "generic", context)
92+
dlg.setWindowTitle(self.tr("Expression based input"));
93+
if dlg.exec_() == QDialog.Accepted:
94+
exp = QgsExpression(dlg.expressionText())
95+
if not exp.hasParserError():
96+
result = exp.evaluate(context)
97+
if not exp.hasEvalError():
98+
try:
99+
self.spnValue.setValue(float(result))
100+
except:
101+
pass
86102

87103
def getValue(self):
88104
return self.spnValue.value()

‎python/plugins/processing/gui/OutputSelectionPanel.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@
3232
from PyQt.QtCore import QCoreApplication, QSettings
3333
from PyQt.QtWidgets import QDialog, QMenu, QAction, QFileDialog
3434
from PyQt.QtGui import QCursor
35-
from qgis.gui import QgsEncodingFileDialog
36-
from qgis.core import QgsDataSourceURI, QgsCredentials
35+
from qgis.gui import QgsEncodingFileDialog, QgsExpressionBuilderDialog
36+
from qgis.core import QgsDataSourceURI, QgsCredentials, QgsExpressionContext,\
37+
QgsExpressionContextUtils, QgsExpression
3738

3839
from processing.core.ProcessingConfig import ProcessingConfig
3940
from processing.core.outputs import OutputVector
@@ -78,6 +79,11 @@ def selectOutput(self):
7879
actionSaveToFile.triggered.connect(self.selectFile)
7980
popupMenu.addAction(actionSaveToFile)
8081

82+
actionShowExpressionsBuilder = QAction(
83+
self.tr('Use expression...'), self.btnSelect)
84+
actionShowExpressionsBuilder.triggered.connect(self.showExpressionsBuilder)
85+
popupMenu.addAction(actionShowExpressionsBuilder)
86+
8187
if isinstance(self.output, OutputVector) \
8288
and self.alg.provider.supportsNonFileBasedOutput():
8389
actionSaveToMemory = QAction(
@@ -100,6 +106,14 @@ def selectOutput(self):
100106

101107
popupMenu.exec_(QCursor.pos())
102108

109+
def showExpressionsBuilder(self):
110+
context = QgsExpressionContext()
111+
context.appendScope(QgsExpressionContextUtils.projectScope())
112+
dlg = QgsExpressionBuilderDialog(None, self.leText.text(), self, "generic", context)
113+
dlg.setWindowTitle(self.tr("Expression based output"));
114+
if dlg.exec_() == QDialog.Accepted:
115+
self.leText.setText(dlg.expressionText())
116+
103117
def saveToTemporaryFile(self):
104118
self.leText.setText('')
105119

@@ -202,6 +216,13 @@ def selectDirectory(self):
202216

203217
def getValue(self):
204218
fileName = unicode(self.leText.text())
219+
context = QgsExpressionContext()
220+
context.appendScope(QgsExpressionContextUtils.projectScope())
221+
exp = QgsExpression(fileName)
222+
if not exp.hasParserError():
223+
result = exp.evaluate(context)
224+
if not exp.hasEvalError():
225+
fileName = result
205226
if fileName.strip() in ['', self.SAVE_TO_TEMP_FILE]:
206227
value = None
207228
elif fileName.startswith('memory:'):

0 commit comments

Comments
 (0)
Failed to load comments.