Skip to content

Commit

Permalink
[processing] Expose data defined button for dynamic numeric parameters
Browse files Browse the repository at this point in the history
When running algorithms through the toolbox, which have dynamic
numeric parameters, add a data defined property override button
next to the widget so that users can set the overrides for these
parameters.

Previously this was available only in the backend, but not
exposed anywhere in the GUI.

Note that currently no algorithms support dynamic parameters,
so don't expect to see this everywhere. It's also only available
in toolbox/batch processing modes, not in models.
  • Loading branch information
nyalldawson committed Dec 2, 2017
1 parent ecbc471 commit 901dae1
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 4 deletions.
33 changes: 31 additions & 2 deletions python/plugins/processing/gui/NumberInputPanel.py
Expand Up @@ -34,10 +34,13 @@
from qgis.PyQt.QtWidgets import QDialog

from qgis.core import (QgsExpression,
QgsProperty,
QgsProcessingParameterNumber,
QgsProcessingOutputNumber,
QgsProcessingParameterDefinition,
QgsProcessingModelChildParameterSource)
QgsProcessingModelChildParameterSource,
QgsProcessingFeatureSourceDefinition,
QgsProcessingUtils)
from qgis.gui import QgsExpressionBuilderDialog
from processing.tools.dataobjects import createExpressionContext, createContext

Expand Down Expand Up @@ -71,6 +74,11 @@ def __init__(self, param, modelParametersDialog):
self.btnSelect.clicked.connect(self.showExpressionsBuilder)
self.leText.textChanged.connect(lambda: self.hasChanged.emit())

# remove data defined button from modeler
self.layout().removeWidget(self.btnDataDefined)
sip.delete(self.btnDataDefined)
self.btnDataDefined = None

def showExpressionsBuilder(self):
context = createExpressionContext()
processing_context = createContext()
Expand Down Expand Up @@ -188,10 +196,31 @@ def __init__(self, param):
sip.delete(self.btnSelect)
self.btnSelect = None

if not self.param.isDynamic():
# only show data defined button for dynamic properties
self.layout().removeWidget(self.btnDataDefined)
sip.delete(self.btnDataDefined)
self.btnDataDefined = None
else:
self.btnDataDefined.init(0, QgsProperty(), self.param.dynamicPropertyDefinition())

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

def setDynamicLayer(self, layer):
context = createContext()
try:
if isinstance(layer, QgsProcessingFeatureSourceDefinition):
layer, ok = layer.source.valueAsString(context.expressionContext())
if isinstance(layer, str):
layer = QgsProcessingUtils.mapLayerFromString(layer, context)
self.btnDataDefined.setVectorLayer(layer)
except:
pass

def getValue(self):
if self.allowing_null and self.spnValue.value() == self.spnValue.minimum():
if self.btnDataDefined is not None and self.btnDataDefined.isActive():
return self.btnDataDefined.toProperty()
elif self.allowing_null and self.spnValue.value() == self.spnValue.minimum():
return None
else:
return self.spnValue.value()
Expand Down
11 changes: 11 additions & 0 deletions python/plugins/processing/gui/wrappers.py
Expand Up @@ -671,6 +671,17 @@ def setValue(self, value):
def value(self):
return self.widget.getValue()

def postInitialize(self, wrappers):
if self.dialogType in (DIALOG_STANDARD, DIALOG_BATCH) and self.param.isDynamic():
for wrapper in wrappers:
if wrapper.param.name() == self.param.dynamicLayerParameterName():
self.widget.setDynamicLayer(wrapper.value())
wrapper.widgetValueHasChanged.connect(self.parentLayerChanged)
break

def parentLayerChanged(self, wrapper):
self.widget.setDynamicLayer(wrapper.value())


class RangeWidgetWrapper(WidgetWrapper):

Expand Down
22 changes: 20 additions & 2 deletions python/plugins/processing/ui/widgetNumberSelector.ui
Expand Up @@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>249</width>
<height>37</height>
<width>380</width>
<height>52</height>
</rect>
</property>
<property name="windowTitle">
Expand Down Expand Up @@ -61,6 +61,19 @@
</property>
</widget>
</item>
<item>
<widget class="QgsPropertyOverrideButton" name="btnDataDefined">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
Expand All @@ -70,6 +83,11 @@
<header>qgis.gui</header>
<container>1</container>
</customwidget>
<customwidget>
<class>QgsPropertyOverrideButton</class>
<extends>QToolButton</extends>
<header>qgis.gui</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
Expand Down

0 comments on commit 901dae1

Please sign in to comment.