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 }
  })

(cherry picked from commit d72c4d0)
  • Loading branch information
nyalldawson committed Nov 29, 2018
1 parent 2e9f4a3 commit f68dcc2
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
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
%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
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
%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
* \ingroup core
* 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
{
Expand Down Expand Up @@ -1449,7 +1461,19 @@ class CORE_EXPORT QgsProcessingParameterNumber : public QgsProcessingParameterDe
* \ingroup core
* A double numeric parameter for distance values. Linked to a source layer or CRS parameter
* 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
{
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()
{
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() )
{
case QgsProcessingGui::Standard:
Expand All @@ -433,13 +435,14 @@ QWidget *QgsProcessingNumericWidgetWrapper::createWidget()
case QgsProcessingParameterNumber::Double:
mDoubleSpinBox = new QgsDoubleSpinBox();
mDoubleSpinBox->setExpressionsEnabled( true );
mDoubleSpinBox->setDecimals( 6 );
mDoubleSpinBox->setDecimals( decimals );

// guess reasonable step value for double spin boxes
if ( !qgsDoubleNear( numberDef->maximum(), std::numeric_limits<double>::max() ) &&
!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 );
}

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 );

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
Expand Down Expand Up @@ -1280,6 +1293,19 @@ void TestProcessingGui::testDistanceWrapper()

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
QgsProcessingDistanceWidgetWrapper wrapperB( &param, QgsProcessingGui::Batch );

Expand Down

0 comments on commit f68dcc2

Please sign in to comment.