Skip to content

Commit

Permalink
[processing] Allow parameter metadata to set the number of decimal pl…
Browse files Browse the repository at this point in the history
…aces

to show in numeric/distance widgets

E.g. to only show 2 decimal places:

  # only show two decimal places in parameter's widgets, not 6:
  param.setMetadata( {'widget_wrapper':
    { 'decimals': 2 }
  })
  • Loading branch information
nyalldawson committed Nov 29, 2018
1 parent b03d8a7 commit d72c4d0
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 4 deletions.
Expand Up @@ -1364,6 +1364,17 @@ class QgsProcessingParameterNumber : QgsProcessingParameterDefinition
%Docstring %Docstring
A numeric parameter for processing algorithms. A numeric parameter for processing algorithms.


For numeric parameters with a dataType() of Double, the number of decimals places
shown in the parameter's widget can be specified by setting the parameter's metadata. For example:

.. code-block:: python

param = QgsProcessingParameterNumber( 'VAL', 'Threshold', type=QgsProcessingParameter.Double)
# only show two decimal places in parameter's widgets, not 6:
param.setMetadata( {'widget_wrapper':
{ 'decimals': 2 }
})

.. versionadded:: 3.0 .. versionadded:: 3.0
%End %End


Expand Down Expand Up @@ -1463,6 +1474,17 @@ class QgsProcessingParameterDistance : QgsProcessingParameterNumber
A double numeric parameter for distance values. Linked to a source layer or CRS parameter A double numeric parameter for distance values. Linked to a source layer or CRS parameter
to determine what units the distance values are in. to determine what units the distance values are in.


The number of decimals places shown in a distance parameter's widget can be specified by
setting the parameter's metadata. For example:

.. code-block:: python

param = QgsProcessingParameterDistance( 'VAL', 'Threshold')
# only show two decimal places in parameter's widgets, not 6:
param.setMetadata( {'widget_wrapper':
{ 'decimals': 2 }
})

.. versionadded:: 3.2 .. versionadded:: 3.2
%End %End


Expand Down
28 changes: 26 additions & 2 deletions src/core/processing/qgsprocessingparameters.h
Expand Up @@ -1359,7 +1359,19 @@ class CORE_EXPORT QgsProcessingParameterMultipleLayers : public QgsProcessingPar
* \class QgsProcessingParameterNumber * \class QgsProcessingParameterNumber
* \ingroup core * \ingroup core
* A numeric parameter for processing algorithms. * A numeric parameter for processing algorithms.
* \since QGIS 3.0 *
* For numeric parameters with a dataType() of Double, the number of decimals places
* shown in the parameter's widget can be specified by setting the parameter's metadata. For example:
*
* * \code{.py}
* param = QgsProcessingParameterNumber( 'VAL', 'Threshold', type=QgsProcessingParameter.Double)
* # only show two decimal places in parameter's widgets, not 6:
* param.setMetadata( {'widget_wrapper':
* { 'decimals': 2 }
* })
* \endcode
*
* \since QGIS 3.0
*/ */
class CORE_EXPORT QgsProcessingParameterNumber : public QgsProcessingParameterDefinition class CORE_EXPORT QgsProcessingParameterNumber : public QgsProcessingParameterDefinition
{ {
Expand Down Expand Up @@ -1449,7 +1461,19 @@ class CORE_EXPORT QgsProcessingParameterNumber : public QgsProcessingParameterDe
* \ingroup core * \ingroup core
* A double numeric parameter for distance values. Linked to a source layer or CRS parameter * A double numeric parameter for distance values. Linked to a source layer or CRS parameter
* to determine what units the distance values are in. * to determine what units the distance values are in.
* \since QGIS 3.2 *
* The number of decimals places shown in a distance parameter's widget can be specified by
* setting the parameter's metadata. For example:
*
* * \code{.py}
* param = QgsProcessingParameterDistance( 'VAL', 'Threshold')
* # only show two decimal places in parameter's widgets, not 6:
* param.setMetadata( {'widget_wrapper':
* { 'decimals': 2 }
* })
* \endcode
*
* \since QGIS 3.2
*/ */
class CORE_EXPORT QgsProcessingParameterDistance : public QgsProcessingParameterNumber class CORE_EXPORT QgsProcessingParameterDistance : public QgsProcessingParameterNumber
{ {
Expand Down
7 changes: 5 additions & 2 deletions src/gui/processing/qgsprocessingwidgetwrapperimpl.cpp
Expand Up @@ -420,6 +420,8 @@ QgsProcessingNumericWidgetWrapper::QgsProcessingNumericWidgetWrapper( const QgsP
QWidget *QgsProcessingNumericWidgetWrapper::createWidget() QWidget *QgsProcessingNumericWidgetWrapper::createWidget()
{ {
const QgsProcessingParameterNumber *numberDef = static_cast< const QgsProcessingParameterNumber * >( parameterDefinition() ); const QgsProcessingParameterNumber *numberDef = static_cast< const QgsProcessingParameterNumber * >( parameterDefinition() );
const QVariantMap metadata = numberDef->metadata();
const int decimals = metadata.value( QStringLiteral( "widget_wrapper" ) ).toMap().value( QStringLiteral( "decimals" ), 6 ).toInt();
switch ( type() ) switch ( type() )
{ {
case QgsProcessingGui::Standard: case QgsProcessingGui::Standard:
Expand All @@ -433,13 +435,14 @@ QWidget *QgsProcessingNumericWidgetWrapper::createWidget()
case QgsProcessingParameterNumber::Double: case QgsProcessingParameterNumber::Double:
mDoubleSpinBox = new QgsDoubleSpinBox(); mDoubleSpinBox = new QgsDoubleSpinBox();
mDoubleSpinBox->setExpressionsEnabled( true ); mDoubleSpinBox->setExpressionsEnabled( true );
mDoubleSpinBox->setDecimals( 6 ); mDoubleSpinBox->setDecimals( decimals );


// guess reasonable step value for double spin boxes // guess reasonable step value for double spin boxes
if ( !qgsDoubleNear( numberDef->maximum(), std::numeric_limits<double>::max() ) && if ( !qgsDoubleNear( numberDef->maximum(), std::numeric_limits<double>::max() ) &&
!qgsDoubleNear( numberDef->minimum(), std::numeric_limits<double>::lowest() + 1 ) ) !qgsDoubleNear( numberDef->minimum(), std::numeric_limits<double>::lowest() + 1 ) )
{ {
const double singleStep = calculateStep( numberDef->minimum(), numberDef->maximum() ); double singleStep = calculateStep( numberDef->minimum(), numberDef->maximum() );
singleStep = std::max( singleStep, std::pow( 10, -decimals ) );
mDoubleSpinBox->setSingleStep( singleStep ); mDoubleSpinBox->setSingleStep( singleStep );
} }


Expand Down
26 changes: 26 additions & 0 deletions tests/src/gui/testprocessinggui.cpp
Expand Up @@ -1005,6 +1005,19 @@ void TestProcessingGui::testNumericWrapperDouble()
QCOMPARE( wrapperOptionalDefault.parameterValue().toDouble(), 5.0 ); QCOMPARE( wrapperOptionalDefault.parameterValue().toDouble(), 5.0 );


delete w; delete w;

// with decimals
QgsProcessingParameterNumber paramDecimals( QStringLiteral( "num" ), QStringLiteral( "num" ), QgsProcessingParameterNumber::Double, QVariant(), true, 1, 1.02 );
QVariantMap metadata;
QVariantMap wrapperMetadata;
wrapperMetadata.insert( QStringLiteral( "decimals" ), 2 );
metadata.insert( QStringLiteral( "widget_wrapper" ), wrapperMetadata );
paramDecimals.setMetadata( metadata );
QgsProcessingNumericWidgetWrapper wrapperDecimals( &paramDecimals, type );
w = wrapperDecimals.createWrappedWidget( context );
QCOMPARE( static_cast< QgsDoubleSpinBox * >( wrapperDecimals.wrappedWidget() )->decimals(), 2 );
QCOMPARE( static_cast< QgsDoubleSpinBox * >( wrapperDecimals.wrappedWidget() )->singleStep(), 0.01 ); // single step should never be less than set number of decimals
delete w;
}; };


// standard wrapper // standard wrapper
Expand Down Expand Up @@ -1280,6 +1293,19 @@ void TestProcessingGui::testDistanceWrapper()


delete w; delete w;


// with decimals
QgsProcessingParameterDistance paramDecimals( QStringLiteral( "num" ), QStringLiteral( "num" ), QVariant(), QString(), true, 1, 1.02 );
QVariantMap metadata;
QVariantMap wrapperMetadata;
wrapperMetadata.insert( QStringLiteral( "decimals" ), 2 );
metadata.insert( QStringLiteral( "widget_wrapper" ), wrapperMetadata );
paramDecimals.setMetadata( metadata );
QgsProcessingDistanceWidgetWrapper wrapperDecimals( &paramDecimals, QgsProcessingGui::Standard );
w = wrapperDecimals.createWrappedWidget( context );
QCOMPARE( wrapperDecimals.mDoubleSpinBox->decimals(), 2 );
QCOMPARE( wrapperDecimals.mDoubleSpinBox->singleStep(), 0.01 ); // single step should never be less than set number of decimals
delete w;

// batch wrapper // batch wrapper
QgsProcessingDistanceWidgetWrapper wrapperB( &param, QgsProcessingGui::Batch ); QgsProcessingDistanceWidgetWrapper wrapperB( &param, QgsProcessingGui::Batch );


Expand Down

0 comments on commit d72c4d0

Please sign in to comment.