40 QHBoxLayout *hl =
new QHBoxLayout();
41 hl->setContentsMargins( 0, 0, 0, 0 );
43 mLineEdit =
new QLineEdit();
44 mLineEdit->setEnabled(
false );
45 hl->addWidget( mLineEdit, 1 );
47 mToolButton =
new QToolButton();
48 mToolButton->setText( QString( QChar( 0x2026 ) ) );
49 hl->addWidget( mToolButton );
53 mLineEdit->setText( tr(
"%1 dataset groups selected" ).arg( 0 ) );
55 mToolButton->setPopupMode( QToolButton::InstantPopup );
56 QMenu *toolButtonMenu =
new QMenu(
this );
57 mActionCurrentActiveDatasetGroups = toolButtonMenu->addAction( tr(
"Current Active Dataset Group" ) );
58 connect( mActionCurrentActiveDatasetGroups,
59 &QAction::triggered,
this, &QgsProcessingMeshDatasetGroupsWidget::selectCurrentActiveDatasetGroup );
61 mActionAvailableDatasetGroups = toolButtonMenu->addAction( tr(
"Select in Available Dataset Groups" ) );
62 connect( mActionAvailableDatasetGroups, &QAction::triggered,
this, &QgsProcessingMeshDatasetGroupsWidget::showDialog );
64 mToolButton->setMenu( toolButtonMenu );
67void QgsProcessingMeshDatasetGroupsWidget::setMeshLayer(
QgsMeshLayer *layer,
bool layerFromProject )
69 mActionCurrentActiveDatasetGroups->setEnabled( layer && layerFromProject );
70 mActionAvailableDatasetGroups->setEnabled( layer );
72 if ( mMeshLayer == layer )
75 mDatasetGroupsNames.clear();
77 if ( layerFromProject )
85 for (
int i : datasetGroupsIndexes )
88 if ( mParam->isDataTypeSupported( meta.
dataType() ) )
90 mDatasetGroupsNames[i] = meta.
name();
100void QgsProcessingMeshDatasetGroupsWidget::setValue(
const QVariant &value )
102 if ( value.isValid() )
103 mValue = value.userType() == QMetaType::Type::QVariantList ? value.toList() : QVariantList() << value;
111QVariant QgsProcessingMeshDatasetGroupsWidget::value()
const
116void QgsProcessingMeshDatasetGroupsWidget::showDialog()
118 QList<int> datasetGroupsIndexes;
120 QVariantList availableOptions;
123 datasetGroupsIndexes = mMeshLayer->datasetGroupsIndexes();
124 for (
int i : std::as_const( datasetGroupsIndexes ) )
127 if ( mParam->isDataTypeSupported( meta.
dataType() ) )
129 availableOptions.append( i );
130 options.append( meta.
name() );
136 for (
auto it = mDatasetGroupsNames.constBegin(); it != mDatasetGroupsNames.constEnd(); it++ )
138 availableOptions.append( it.key() );
139 options.append( it.value() );
146 QgsProcessingMultipleSelectionPanelWidget *widget =
new QgsProcessingMultipleSelectionPanelWidget( availableOptions, mValue );
147 widget->setPanelTitle( tr(
"Dataset Groups Available" ) );
149 widget->setValueFormatter( [availableOptions, options](
const QVariant & v ) -> QString
151 const int index = v.toInt();
152 const int pos = availableOptions.indexOf( index );
153 return ( pos >= 0 && pos < options.size() ) ? options.at( pos ) : QString();
156 connect( widget, &QgsProcessingMultipleSelectionPanelWidget::selectionChanged,
this, [ = ]()
158 setValue( widget->selectedOptions() );
165 QgsProcessingMultipleSelectionDialog dlg( availableOptions, mValue,
this, Qt::WindowFlags() );
167 dlg.setValueFormatter( [datasetGroupsIndexes, options](
const QVariant & v ) -> QString
169 const int index = v.toInt();
170 const int pos = datasetGroupsIndexes.indexOf( index );
171 return ( pos >= 0 && pos < options.size() ) ? options.at( pos ) : QString();
175 setValue( dlg.selectedOptions() );
180void QgsProcessingMeshDatasetGroupsWidget::selectCurrentActiveDatasetGroup()
182 QVariantList options;
183 if ( mMeshLayer && mParam )
185 int scalarDatasetGroup = mMeshLayer->rendererSettings().activeScalarDatasetGroup();
186 int vectorDatasetGroup = mMeshLayer->rendererSettings().activeVectorDatasetGroup();
188 if ( scalarDatasetGroup >= 0 && mParam->isDataTypeSupported( mMeshLayer->datasetGroupMetadata( scalarDatasetGroup ).dataType() ) )
189 options.append( scalarDatasetGroup );
191 if ( vectorDatasetGroup >= 0
192 && mParam->isDataTypeSupported( mMeshLayer->datasetGroupMetadata( vectorDatasetGroup ).dataType() )
193 && vectorDatasetGroup != scalarDatasetGroup )
194 options.append( vectorDatasetGroup );
204QString QgsProcessingMeshDatasetGroupsWidgetWrapper::parameterType()
const
211 return new QgsProcessingMeshDatasetGroupsWidgetWrapper( parameter, type );
216 return new QgsProcessingMeshDatasetGroupsParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
219void QgsProcessingMeshDatasetGroupsWidgetWrapper::postInitialize(
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
231 setMeshLayerWrapperValue( wrapper );
234 setMeshLayerWrapperValue( wrapper );
253 if ( mProcessingContextGenerator )
254 context = mProcessingContextGenerator->processingContext();
256 bool layerFromProject;
262 layerFromProject =
false;
271 mWidget->setMeshLayer( meshLayer, layerFromProject );
274QStringList QgsProcessingMeshDatasetGroupsWidgetWrapper::compatibleParameterTypes()
const
281QStringList QgsProcessingMeshDatasetGroupsWidgetWrapper::compatibleOutputTypes()
const
287QWidget *QgsProcessingMeshDatasetGroupsWidgetWrapper::createWidget()
SIP_FACTORY
290 connect( mWidget, &QgsProcessingMeshDatasetGroupsWidget::changed,
this, [ = ]
292 emit widgetValueHasChanged(
this );
298void QgsProcessingMeshDatasetGroupsWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
303 QList<int> datasetGroupIndexes;
304 if ( value.userType() == QMetaType::Type::QVariantList )
312 QVariantList varList;
313 for (
const int index : std::as_const( datasetGroupIndexes ) )
314 varList.append( index );
316 mWidget->setValue( varList );
319QVariant QgsProcessingMeshDatasetGroupsWidgetWrapper::widgetValue()
const
322 return mWidget->value();
327void QgsProcessingMeshDatasetGroupsWidget::updateSummaryText()
329 mLineEdit->setText( tr(
"%n option(s) selected",
nullptr, mValue.count() ) );
340QString QgsProcessingMeshDatasetTimeWidgetWrapper::parameterType()
const
347 return new QgsProcessingMeshDatasetTimeWidgetWrapper( parameter, type );
350void QgsProcessingMeshDatasetTimeWidgetWrapper::postInitialize(
const QList<QgsAbstractProcessingParameterWidgetWrapper *> &wrappers )
363 layerParameterWrapper = wrapper;
366 datasetGroupsParameterWrapper = wrapper;
368 setMeshLayerWrapperValue( layerParameterWrapper );
369 setDatasetGroupIndexesWrapperValue( datasetGroupsParameterWrapper );
372 setMeshLayerWrapperValue( layerParameterWrapper );
373 setDatasetGroupIndexesWrapperValue( datasetGroupsParameterWrapper );
386 return new QgsProcessingMeshDatasetTimeParameterDefinitionWidget( context, widgetContext, definition,
algorithm );
391 if ( !mWidget || !wrapper )
396 if ( mProcessingContextGenerator )
397 context = mProcessingContextGenerator->processingContext();
399 bool layerFromProject;
405 layerFromProject =
false;
413 mWidget->setMeshLayer( meshLayer, layerFromProject );
418 if ( !mWidget || !wrapper )
423 if ( !datasetGroupsVariant.isValid() || datasetGroupsVariant.userType() != QMetaType::Type::QVariantList )
424 mWidget->setDatasetGroupIndexes( QList<int>() );
426 QVariantList datasetGroupsListVariant = datasetGroupsVariant.toList();
428 QList<int> datasetGroupsIndexes;
429 for (
const QVariant &variantIndex : datasetGroupsListVariant )
430 datasetGroupsIndexes << variantIndex.toInt();
432 mWidget->setDatasetGroupIndexes( datasetGroupsIndexes );
436QStringList QgsProcessingMeshDatasetTimeWidgetWrapper::compatibleParameterTypes()
const
444QStringList QgsProcessingMeshDatasetTimeWidgetWrapper::compatibleOutputTypes()
const
450QWidget *QgsProcessingMeshDatasetTimeWidgetWrapper::createWidget()
459 connect( mWidget, &QgsProcessingMeshDatasetTimeWidget::changed,
this, [ = ]
461 emit widgetValueHasChanged(
this );
467void QgsProcessingMeshDatasetTimeWidgetWrapper::setWidgetValue(
const QVariant &value,
QgsProcessingContext &context )
471 mWidget->setValue( value );
474QVariant QgsProcessingMeshDatasetTimeWidgetWrapper::widgetValue()
const
477 return mWidget->value();
481QgsProcessingMeshDatasetTimeWidget::QgsProcessingMeshDatasetTimeWidget( QWidget *parent,
489 mValue.insert( QStringLiteral(
"type" ), QStringLiteral(
"static" ) );
491 dateTimeEdit->setDisplayFormat(
"yyyy-MM-dd HH:mm:ss" );
495 connect( radioButtonCurrentCanvasTime, &QRadioButton::toggled,
this, [
this](
bool isChecked ) {
if ( isChecked ) this->updateValue();} );
496 connect( radioButtonDefinedDateTime, &QRadioButton::toggled,
this, [
this](
bool isChecked ) {
if ( isChecked ) this->updateValue();} );
497 connect( radioButtonDatasetGroupTimeStep, &QRadioButton::toggled,
this, [
this](
bool isChecked ) {
if ( isChecked ) this->updateValue();} );
498 connect( dateTimeEdit, &QgsDateTimeEdit::dateTimeChanged,
this, &QgsProcessingMeshDatasetTimeWidget::updateValue );
499 connect( comboBoxDatasetTimeStep, qOverload<int>( &QComboBox::currentIndexChanged ),
500 this, &QgsProcessingMeshDatasetTimeWidget::updateValue );
505void QgsProcessingMeshDatasetTimeWidget::setMeshLayer(
QgsMeshLayer *layer,
bool layerFromProject )
507 if ( mMeshLayer == layer )
510 mReferenceTime = QDateTime();
512 if ( layerFromProject )
519 mMeshLayer =
nullptr;
522 storeTimeStepsFromLayer( layer );
525 if ( mReferenceTime.isValid() )
526 whileBlocking( dateTimeEdit )->setDateTime( mReferenceTime );
531void QgsProcessingMeshDatasetTimeWidget::setDatasetGroupIndexes(
const QList<int> datasetGroupIndexes )
533 if ( datasetGroupIndexes == mDatasetGroupIndexes )
535 mDatasetGroupIndexes = datasetGroupIndexes;
540void QgsProcessingMeshDatasetTimeWidget::setValue(
const QVariant &value )
542 if ( !value.isValid() || ( value.userType() != QMetaType::Type::QVariantMap && !value.toDateTime().isValid() ) )
546 if ( value.toDateTime().isValid() )
548 QDateTime dateTime = value.toDateTime();
549 dateTime.setTimeSpec( Qt::UTC );
550 mValue.insert( QStringLiteral(
"type" ), QStringLiteral(
"defined-date-time" ) );
551 mValue.insert( QStringLiteral(
"value" ), dateTime );
554 mValue = value.toMap();
556 if ( !mValue.contains( QStringLiteral(
"type" ) ) || !mValue.contains( QStringLiteral(
"value" ) ) )
559 QString type = mValue.value( QStringLiteral(
"type" ) ).toString();
562 if ( type == QLatin1String(
"static" ) )
566 else if ( type == QLatin1String(
"dataset-time-step" ) )
568 QVariantList dataset = mValue.value( QStringLiteral(
"value" ) ).toList();
569 whileBlocking( comboBoxDatasetTimeStep )->setCurrentIndex( comboBoxDatasetTimeStep->findData( dataset ) );
570 whileBlocking( radioButtonDatasetGroupTimeStep )->setChecked(
true );
572 else if ( type == QLatin1String(
"defined-date-time" ) )
574 whileBlocking( dateTimeEdit )->setDateTime( mValue.value( QStringLiteral(
"value" ) ).toDateTime() );
575 whileBlocking( radioButtonDefinedDateTime )->setChecked(
true );
577 else if ( type == QLatin1String(
"current-context-time" ) )
579 whileBlocking( radioButtonCurrentCanvasTime )->setChecked(
true );
586QVariant QgsProcessingMeshDatasetTimeWidget::value()
const
591void QgsProcessingMeshDatasetTimeWidget::updateWidget()
593 bool isStatic = !hasTemporalDataset();
594 setEnabled( !isStatic );
596 if ( mCanvas && mCanvas->mapSettings().isTemporal() )
598 whileBlocking( radioButtonCurrentCanvasTime )->setEnabled(
true && mReferenceTime.isValid() );
599 labelCurrentCanvasTime->setText( mCanvas->mapSettings().temporalRange().begin().toString(
"yyyy-MM-dd HH:mm:ss" ) );
603 whileBlocking( radioButtonCurrentCanvasTime )->setEnabled(
false );
604 if ( radioButtonCurrentCanvasTime->isChecked() )
605 whileBlocking( radioButtonDefinedDateTime )->setChecked(
true );
608 if ( ! mReferenceTime.isValid() )
609 whileBlocking( radioButtonDatasetGroupTimeStep )->setChecked(
true );
611 whileBlocking( radioButtonDefinedDateTime )->setEnabled( mReferenceTime.isValid() );
613 dateTimeEdit->setVisible( radioButtonDefinedDateTime->isChecked() && !isStatic );
614 labelCurrentCanvasTime->setVisible( radioButtonCurrentCanvasTime->isChecked() && !isStatic );
615 comboBoxDatasetTimeStep->setVisible( radioButtonDatasetGroupTimeStep->isChecked() && !isStatic );
618bool QgsProcessingMeshDatasetTimeWidget::hasTemporalDataset()
const
620 for (
int index : mDatasetGroupIndexes )
622 if ( mMeshLayer && mMeshLayer->datasetGroupMetadata( index ).isTemporal() )
624 else if ( mDatasetTimeSteps.contains( index ) )
632void QgsProcessingMeshDatasetTimeWidget::populateTimeSteps()
636 populateTimeStepsFromLayer();
640 QMap<quint64, QgsMeshDatasetIndex> timeStep;
641 for (
int groupIndex : mDatasetGroupIndexes )
643 if ( !mDatasetTimeSteps.contains( groupIndex ) )
645 const QList<qint64> relativeTimeSteps = mDatasetTimeSteps.value( groupIndex );
646 for (
int index = 0; index < relativeTimeSteps.count(); ++index )
649 if ( timeStep.contains( relativeTimeSteps.at( index ) ) )
651 timeStep[relativeTimeSteps.at( index )] = datasetIndex;
655 for (
auto it = timeStep.constBegin(); it != timeStep.constEnd(); it++ )
657 QString stringTime = QgsMeshLayerUtils::formatTime(
static_cast<double>( it.key() ) / 1000. / 3600., mReferenceTime,
QgsMeshTimeSettings() );
661 whileBlocking( comboBoxDatasetTimeStep )->addItem( stringTime, data );
666void QgsProcessingMeshDatasetTimeWidget::populateTimeStepsFromLayer()
673 QMap<quint64, QgsMeshDatasetIndex> timeStep;
674 for (
int groupIndex : std::as_const( mDatasetGroupIndexes ) )
679 int datasetCount = mMeshLayer->datasetCount( groupIndex );
681 for (
int index = 0; index < datasetCount; ++index )
684 qint64 relativeTime = mMeshLayer->datasetRelativeTimeInMilliseconds( datasetIndex );
685 if ( timeStep.contains( relativeTime ) )
687 timeStep[relativeTime] = datasetIndex;
691 for (
auto it = timeStep.constBegin(); it != timeStep.constEnd(); it++ )
693 QString stringTime = mMeshLayer->formatTime(
static_cast<double>( it.key() ) / 1000.0 / 3600.0 );
697 whileBlocking( comboBoxDatasetTimeStep )->addItem( stringTime, data );
701void QgsProcessingMeshDatasetTimeWidget::storeTimeStepsFromLayer(
QgsMeshLayer *layer )
703 mDatasetTimeSteps.clear();
707 for (
int groupIndex : datasetGroupsList )
713 QList<qint64> relativeTimeSteps;
714 relativeTimeSteps.reserve( datasetCount );
715 for (
int index = 0; index < datasetCount; ++index )
717 mDatasetTimeSteps[groupIndex] = relativeTimeSteps;
721void QgsProcessingMeshDatasetTimeWidget::buildValue()
727 mValue[QStringLiteral(
"type" )] = QStringLiteral(
"static" );
729 else if ( radioButtonDatasetGroupTimeStep->isChecked() )
731 mValue[QStringLiteral(
"type" )] = QStringLiteral(
"dataset-time-step" );
732 mValue[QStringLiteral(
"value" )] = comboBoxDatasetTimeStep->currentData();
734 else if ( radioButtonDefinedDateTime->isChecked() )
736 mValue[QStringLiteral(
"type" )] = QStringLiteral(
"defined-date-time" );
737 mValue[QStringLiteral(
"value" )] = dateTimeEdit->dateTime();
739 else if ( radioButtonCurrentCanvasTime->isChecked() && mCanvas )
741 mValue[QStringLiteral(
"type" )] = QStringLiteral(
"current-context-time" );
747void QgsProcessingMeshDatasetTimeWidget::updateValue()
754QgsProcessingMeshDatasetGroupsParameterDefinitionWidget::QgsProcessingMeshDatasetGroupsParameterDefinitionWidget(
762 QVBoxLayout *vlayout =
new QVBoxLayout();
763 vlayout->setContentsMargins( 0, 0, 0, 0 );
765 vlayout->addWidget(
new QLabel( tr(
"Linked input" ) ) );
767 mParentLayerComboBox =
new QComboBox();
768 vlayout->addWidget( mParentLayerComboBox );
770 if ( QgsProcessingModelAlgorithm *model = widgetContext.
model() )
772 const QMap<QString, QgsProcessingModelParameter> components = model->parameterComponents();
773 for (
auto it = components.constBegin(); it != components.constEnd(); ++it )
785 if ( datasetGroupDef )
788 if ( currentIndex != -1 )
789 mParentLayerComboBox->setCurrentIndex( currentIndex );
794 mParentLayerComboBox->setCurrentIndex( mParentLayerComboBox->count() - 1 );
798 setLayout( vlayout );
803 const QString &description,
806 QSet<int> supportedDataType;
811 std::unique_ptr<QgsProcessingParameterMeshDatasetGroups> param =
812 std::make_unique<QgsProcessingParameterMeshDatasetGroups>( name, description, mParentLayerComboBox->currentData().toString(), supportedDataType );
813 param->setFlags( flags );
814 return param.release();
817QgsProcessingMeshDatasetTimeParameterDefinitionWidget::QgsProcessingMeshDatasetTimeParameterDefinitionWidget(
832 QVBoxLayout *vlayout =
new QVBoxLayout();
833 vlayout->setContentsMargins( 0, 0, 0, 0 );
835 vlayout->addWidget(
new QLabel( tr(
"Linked input" ) ) );
837 mParentDatasetComboBox =
new QComboBox();
838 vlayout->addWidget( mParentDatasetComboBox );
840 QgsProcessingModelAlgorithm *model = widgetContext.
model();
843 const QMap<QString, QgsProcessingModelParameter> components = model->parameterComponents();
844 for (
auto it = components.constBegin(); it != components.constEnd(); ++it )
857 if ( currentIndex != -1 )
858 mParentDatasetComboBox->setCurrentIndex( currentIndex );
863 mParentDatasetComboBox->setCurrentIndex( mParentDatasetComboBox->count() - 1 );
873 connect( mParentDatasetComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [
this, model]
881 setLayout( vlayout );
886 std::unique_ptr<QgsProcessingParameterMeshDatasetTime> param = std::make_unique<QgsProcessingParameterMeshDatasetTime>(
887 name, description, mMeshLayerParameterName, mParentDatasetComboBox->currentData().toString() );
889 param->setFlags( flags );
890 return param.release();
QFlags< ProcessingParameterFlag > ProcessingParameterFlags
Flags which dictate the behavior of Processing parameters.
Map canvas is a class for displaying all GIS data types on a canvas.
void temporalRangeChanged()
Emitted when the map canvas temporal range changes.
QVector< T > layers() const
Returns a list of registered map layers with a specified layer type.
QDateTime referenceTime() const
Returns the reference time.
QgsMeshDataProviderTemporalCapabilities * temporalCapabilities() override
Returns the provider's temporal capabilities.
QgsMeshDatasetIndex is index that identifies the dataset group (e.g.
int group() const
Returns a group index.
int dataset() const
Returns a dataset index within group()
Implementation of map layer temporal properties for mesh layers.
Represents a mesh layer supporting display of data on structured or unstructured meshes.
int datasetCount(const QgsMeshDatasetIndex &index) const
Returns the dataset count in the dataset groups.
QList< int > datasetGroupsIndexes() const
Returns the list of indexes of dataset groups handled by the layer.
QgsMeshDataProvider * dataProvider() override
Returns the layer's data provider, it may be nullptr.
QgsMapLayerTemporalProperties * temporalProperties() override
Returns the layer's temporal properties.
qint64 datasetRelativeTimeInMilliseconds(const QgsMeshDatasetIndex &index)
Returns the relative time (in milliseconds) of the dataset from the reference time of its group.
QgsMeshDatasetGroupMetadata datasetGroupMetadata(const QgsMeshDatasetIndex &index) const
Returns the dataset groups metadata.
Represents a mesh time settings for mesh datasets.
Abstract base class for processing algorithms.
Contains information about the context in which a processing algorithm is executed.
QgsProject * project() const
Returns the project in which the algorithm is being executed.
WidgetType
Types of dialogs which Processing widgets can be created for.
@ Standard
Standard algorithm dialog.
@ Batch
Batch processing dialog.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the output class.
static QString typeName()
Returns the type name for the parameter class.
Base class for the definition of processing parameters.
QString description() const
Returns the description for the parameter.
virtual QString type() const =0
Unique parameter type name.
QString name() const
Returns the name of the parameter.
A parameter for processing algorithms that need a list of mesh dataset groups.
static QString typeName()
Returns the type name for the parameter class.
QString meshLayerParameterName() const
Returns the name of the mesh layer parameter.
A parameter for processing algorithms that need a list of mesh dataset index from time parameter.
QString datasetGroupParameterName() const
Returns the name of the dataset groups parameter.
QString meshLayerParameterName() const
Returns the name of the mesh layer parameter.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
static QString typeName()
Returns the type name for the parameter class.
Contains settings which reflect the context in which a Processing parameter widget is shown,...
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
QgsProcessingModelAlgorithm * model() const
Returns the model which the parameter widget is associated with.
static QList< int > parameterAsInts(const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a list of integer values.
static QgsMeshLayer * parameterAsMeshLayer(const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, QgsProcessingContext &context)
Evaluates the parameter with matching definition and value to a mesh layer.
static int parameterAsInt(const QgsProcessingParameterDefinition *definition, const QVariantMap ¶meters, const QgsProcessingContext &context)
Evaluates the parameter with matching definition to a static integer value.
QgsMapLayerStore * layerStore()
Returns a pointer to the project's internal layer store.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into allowing algorithms to be written in pure substantial changes are required in order to port existing x Processing algorithms for QGIS x The most significant changes are outlined not GeoAlgorithm For algorithms which operate on features one by consider subclassing the QgsProcessingFeatureBasedAlgorithm class This class allows much of the boilerplate code for looping over features from a vector layer to be bypassed and instead requires implementation of a processFeature method Ensure that your algorithm(or algorithm 's parent class) implements the new pure virtual createInstance(self) call
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.