Skip to content

Commit cf636dc

Browse files
authoredSep 22, 2017
Merge pull request #5235 from nyalldawson/model_progress2
[processing] Proper progress reports during model execution
2 parents 5599737 + 33d2d11 commit cf636dc

File tree

7 files changed

+150
-20
lines changed

7 files changed

+150
-20
lines changed
 

‎python/core/core_auto.sip

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@
176176
%Include processing/qgsprocessingoutputs.sip
177177
%Include processing/qgsprocessingparameters.sip
178178
%Include processing/qgsprocessingutils.sip
179-
%Include processing/models/qgsprocessingmodelalgorithm.sip
180179
%Include processing/models/qgsprocessingmodelchildalgorithm.sip
181180
%Include processing/models/qgsprocessingmodelchildparametersource.sip
182181
%Include processing/models/qgsprocessingmodelcomponent.sip
@@ -384,6 +383,7 @@
384383
%Include processing/qgsprocessingfeedback.sip
385384
%Include processing/qgsprocessingprovider.sip
386385
%Include processing/qgsprocessingregistry.sip
386+
%Include processing/models/qgsprocessingmodelalgorithm.sip
387387
%Include raster/qgsrasterfilewritertask.sip
388388
%Include raster/qgsrasterlayer.sip
389389
%Include raster/qgsrasterdataprovider.sip

‎python/core/processing/models/qgsprocessingmodelalgorithm.sip

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,8 @@ Translated description of variable
374374
};
375375

376376

377+
378+
377379
/************************************************************************
378380
* This file has been generated automatically from *
379381
* *

‎python/core/qgsfeedback.sip

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,6 @@ class QgsFeedback : QObject
3838
QgsFeedback( QObject *parent /TransferThis/ = 0 );
3939
%Docstring
4040
Construct a feedback object
41-
%End
42-
43-
void cancel();
44-
%Docstring
45-
Tells the internal routines that the current operation should be canceled. This should be run by the main thread
4641
%End
4742

4843
bool isCanceled() const;
@@ -71,6 +66,13 @@ Tells whether the operation has been canceled already
7166
:rtype: float
7267
%End
7368

69+
public slots:
70+
71+
void cancel();
72+
%Docstring
73+
Tells the internal routines that the current operation should be canceled. This should be run by the main thread
74+
%End
75+
7476
signals:
7577
void canceled();
7678
%Docstring

‎src/core/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ SET(QGIS_CORE_MOC_HDRS
682682
processing/qgsprocessingfeedback.h
683683
processing/qgsprocessingprovider.h
684684
processing/qgsprocessingregistry.h
685+
processing/models/qgsprocessingmodelalgorithm.h
685686

686687
providers/memory/qgsmemoryprovider.h
687688

@@ -978,7 +979,6 @@ SET(QGIS_CORE_HDRS
978979
processing/qgsprocessingoutputs.h
979980
processing/qgsprocessingparameters.h
980981
processing/qgsprocessingutils.h
981-
processing/models/qgsprocessingmodelalgorithm.h
982982
processing/models/qgsprocessingmodelchildalgorithm.h
983983
processing/models/qgsprocessingmodelchildparametersource.h
984984
processing/models/qgsprocessingmodelcomponent.h

‎src/core/processing/models/qgsprocessingmodelalgorithm.cpp

Lines changed: 81 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ QVariantMap QgsProcessingModelAlgorithm::processAlgorithm( const QVariantMap &pa
214214
QTime totalTime;
215215
totalTime.start();
216216

217+
QgsProcessingModelFeedback modelFeedback( toExecute.count(), feedback );
217218
QgsExpressionContext baseContext = createExpressionContext( parameters, context );
218219

219220
QVariantMap childResults;
@@ -225,6 +226,9 @@ QVariantMap QgsProcessingModelAlgorithm::processAlgorithm( const QVariantMap &pa
225226
executedAlg = false;
226227
Q_FOREACH ( const QString &childId, toExecute )
227228
{
229+
if ( feedback && feedback->isCanceled() )
230+
break;
231+
228232
if ( executed.contains( childId ) )
229233
continue;
230234

@@ -252,15 +256,23 @@ QVariantMap QgsProcessingModelAlgorithm::processAlgorithm( const QVariantMap &pa
252256

253257
QVariantMap childParams = parametersForChildAlgorithm( child, parameters, childResults, expContext );
254258
feedback->setProgressText( QObject::tr( "Running %1 [%2/%3]" ).arg( child.description() ).arg( executed.count() + 1 ).arg( toExecute.count() ) );
255-
//feedback->pushDebugInfo( "Parameters: " + ', '.join( [str( p ).strip() +
256-
// '=' + str( p.value ) for p in alg.algorithm.parameters] ) )
259+
260+
QStringList params;
261+
for ( auto childParamIt = childParams.constBegin(); childParamIt != childParams.constEnd(); ++childParamIt )
262+
{
263+
params << QStringLiteral( "%1: %2" ).arg( childParamIt.key(),
264+
child.algorithm()->parameterDefinition( childParamIt.key() )->valueAsPythonString( childParamIt.value(), context ) );
265+
}
266+
267+
feedback->pushInfo( QObject::tr( "Input Parameters:" ) );
268+
feedback->pushCommandInfo( QStringLiteral( "{ %1 }" ).arg( params.join( QStringLiteral( ", " ) ) ) );
257269

258270
QTime childTime;
259271
childTime.start();
260272

261273
bool ok = false;
262274
std::unique_ptr< QgsProcessingAlgorithm > childAlg( child.algorithm()->create( child.configuration() ) );
263-
QVariantMap results = childAlg->run( childParams, context, feedback, &ok );
275+
QVariantMap results = childAlg->run( childParams, context, &modelFeedback, &ok );
264276
childAlg.reset( nullptr );
265277
if ( !ok )
266278
{
@@ -280,8 +292,12 @@ QVariantMap QgsProcessingModelAlgorithm::processAlgorithm( const QVariantMap &pa
280292
}
281293

282294
executed.insert( childId );
283-
feedback->pushDebugInfo( QObject::tr( "OK. Execution took %1 s (%2 outputs)." ).arg( childTime.elapsed() / 1000.0 ).arg( results.count() ) );
295+
modelFeedback.setCurrentStep( executed.count() );
296+
feedback->pushInfo( QObject::tr( "OK. Execution took %1 s (%2 outputs)." ).arg( childTime.elapsed() / 1000.0 ).arg( results.count() ) );
284297
}
298+
299+
if ( feedback && feedback->isCanceled() )
300+
break;
285301
}
286302
feedback->pushDebugInfo( QObject::tr( "Model processed OK. Executed %1 algorithms total in %2 s." ).arg( executed.count() ).arg( totalTime.elapsed() / 1000.0 ) );
287303

@@ -1123,4 +1139,65 @@ QgsProcessingAlgorithm *QgsProcessingModelAlgorithm::createInstance() const
11231139
return alg;
11241140
}
11251141

1142+
1143+
1144+
1145+
//
1146+
// QgsProcessingModelFeedback
1147+
//
1148+
1149+
QgsProcessingModelFeedback::QgsProcessingModelFeedback( int childAlgorithmCount, QgsProcessingFeedback *feedback )
1150+
: mChildSteps( childAlgorithmCount )
1151+
, mFeedback( feedback )
1152+
{
1153+
connect( mFeedback, &QgsFeedback::canceled, this, &QgsFeedback::cancel, Qt::DirectConnection );
1154+
connect( this, &QgsFeedback::progressChanged, this, &QgsProcessingModelFeedback::updateOverallProgress );
1155+
}
1156+
1157+
void QgsProcessingModelFeedback::setCurrentStep( int step )
1158+
{
1159+
mCurrentStep = step;
1160+
mFeedback->setProgress( 100.0 * static_cast< double >( mCurrentStep ) / mChildSteps );
1161+
}
1162+
1163+
void QgsProcessingModelFeedback::setProgressText( const QString &text )
1164+
{
1165+
mFeedback->setProgressText( text );
1166+
}
1167+
1168+
void QgsProcessingModelFeedback::reportError( const QString &error )
1169+
{
1170+
mFeedback->reportError( error );
1171+
}
1172+
1173+
void QgsProcessingModelFeedback::pushInfo( const QString &info )
1174+
{
1175+
mFeedback->pushInfo( info );
1176+
}
1177+
1178+
void QgsProcessingModelFeedback::pushCommandInfo( const QString &info )
1179+
{
1180+
mFeedback->pushCommandInfo( info );
1181+
}
1182+
1183+
void QgsProcessingModelFeedback::pushDebugInfo( const QString &info )
1184+
{
1185+
mFeedback->pushDebugInfo( info );
1186+
}
1187+
1188+
void QgsProcessingModelFeedback::pushConsoleInfo( const QString &info )
1189+
{
1190+
mFeedback->pushConsoleInfo( info );
1191+
}
1192+
1193+
void QgsProcessingModelFeedback::updateOverallProgress( double progress )
1194+
{
1195+
double baseProgress = 100.0 * static_cast< double >( mCurrentStep ) / mChildSteps;
1196+
double currentAlgorithmProgress = progress / mChildSteps;
1197+
mFeedback->setProgress( baseProgress + currentAlgorithmProgress );
1198+
}
1199+
1200+
1201+
11261202
///@endcond
1203+

‎src/core/processing/models/qgsprocessingmodelalgorithm.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,53 @@ class CORE_EXPORT QgsProcessingModelAlgorithm : public QgsProcessingAlgorithm
403403
friend class TestQgsProcessing;
404404
};
405405

406+
407+
#ifndef SIP_RUN
408+
409+
/**
410+
* Model algorithm feedback which proxies its calls to an underlying
411+
* feedback object, but scales overall progress reports to account
412+
* for the number of child steps in a model.
413+
*/
414+
class QgsProcessingModelFeedback : public QgsProcessingFeedback
415+
{
416+
Q_OBJECT
417+
418+
public:
419+
420+
/**
421+
* Constructor for QgsProcessingModelFeedback, for a model with the specified
422+
* number of active child algorithms. This feedback object will proxy calls
423+
* to the specified \a feedback object.
424+
*/
425+
QgsProcessingModelFeedback( int childAlgorithmCount, QgsProcessingFeedback *feedback );
426+
427+
/**
428+
* Sets the current child algorithm \a step which is being executed. This is used
429+
* to scale the overall progress to account for progress through the overall model.
430+
*/
431+
void setCurrentStep( int step );
432+
433+
void setProgressText( const QString &text ) override;
434+
void reportError( const QString &error ) override;
435+
void pushInfo( const QString &info ) override;
436+
void pushCommandInfo( const QString &info ) override;
437+
void pushDebugInfo( const QString &info ) override;
438+
void pushConsoleInfo( const QString &info ) override;
439+
440+
private slots:
441+
442+
void updateOverallProgress( double progress );
443+
444+
private:
445+
446+
int mChildSteps = 0;
447+
int mCurrentStep = 0;
448+
QgsProcessingFeedback *mFeedback = nullptr;
449+
};
450+
451+
#endif
452+
406453
///@endcond
407454

408455
#endif // QGSPROCESSINGMODELALGORITHM_H

‎src/core/qgsfeedback.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,6 @@ class CORE_EXPORT QgsFeedback : public QObject
5050
, mCanceled( false )
5151
{}
5252

53-
//! Tells the internal routines that the current operation should be canceled. This should be run by the main thread
54-
void cancel()
55-
{
56-
if ( mCanceled )
57-
return; // only emit the signal once
58-
mCanceled = true;
59-
emit canceled();
60-
}
61-
6253
//! Tells whether the operation has been canceled already
6354
bool isCanceled() const { return mCanceled; }
6455

@@ -88,6 +79,17 @@ class CORE_EXPORT QgsFeedback : public QObject
8879
*/
8980
double progress() const { return mProgress; }
9081

82+
public slots:
83+
84+
//! Tells the internal routines that the current operation should be canceled. This should be run by the main thread
85+
void cancel()
86+
{
87+
if ( mCanceled )
88+
return; // only emit the signal once
89+
mCanceled = true;
90+
emit canceled();
91+
}
92+
9193
signals:
9294
//! Internal routines can connect to this signal if they use event loop
9395
void canceled();

0 commit comments

Comments
 (0)
Please sign in to comment.