Skip to content
Permalink
Browse files
[processing] Expose data defined button for dynamic numeric parameters
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.
@@ -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

@@ -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()
@@ -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()
@@ -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):

@@ -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">
@@ -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>
@@ -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/>

0 comments on commit 901dae1

Please sign in to comment.