QGIS API Documentation  3.27.0-Master (597e8eebd4)
qgsmodelgraphicsscene.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmodelgraphicsscene.cpp
3  ----------------------------------
4  Date : March 2020
5  Copyright : (C) 2020 Nyall Dawson
6  Email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsmodelgraphicsscene.h"
20 #include "qgsmodelarrowitem.h"
22 #include "qgsmessagebar.h"
23 #include "qgsmessagebaritem.h"
24 #include "qgsmessageviewer.h"
25 #include "qgsapplication.h"
26 #include <QGraphicsSceneMouseEvent>
27 #include <QPushButton>
28 
30 
31 QgsModelGraphicsScene::QgsModelGraphicsScene( QObject *parent )
32  : QGraphicsScene( parent )
33 {
34  setItemIndexMethod( QGraphicsScene::NoIndex );
35 }
36 
37 QgsProcessingModelAlgorithm *QgsModelGraphicsScene::model()
38 {
39  return mModel;
40 }
41 
42 void QgsModelGraphicsScene::setModel( QgsProcessingModelAlgorithm *model )
43 {
44  mModel = model;
45 }
46 
47 void QgsModelGraphicsScene::setFlag( QgsModelGraphicsScene::Flag flag, bool on )
48 {
49  if ( on )
50  mFlags |= flag;
51  else
52  mFlags &= ~flag;
53 }
54 
55 void QgsModelGraphicsScene::mousePressEvent( QGraphicsSceneMouseEvent *event )
56 {
57  if ( event->button() != Qt::LeftButton )
58  return;
59  QGraphicsScene::mousePressEvent( event );
60 }
61 
62 QgsModelComponentGraphicItem *QgsModelGraphicsScene::createParameterGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelParameter *param ) const
63 {
64  return new QgsModelParameterGraphicItem( param, model, nullptr );
65 }
66 
67 QgsModelChildAlgorithmGraphicItem *QgsModelGraphicsScene::createChildAlgGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelChildAlgorithm *child ) const
68 {
69  return new QgsModelChildAlgorithmGraphicItem( child, model, nullptr );
70 }
71 
72 QgsModelComponentGraphicItem *QgsModelGraphicsScene::createOutputGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelOutput *output ) const
73 {
74  return new QgsModelOutputGraphicItem( output, model, nullptr );
75 }
76 
77 QgsModelComponentGraphicItem *QgsModelGraphicsScene::createCommentGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelComment *comment, QgsModelComponentGraphicItem *parentItem ) const
78 {
79  return new QgsModelCommentGraphicItem( comment, parentItem, model, nullptr );
80 }
81 
82 QgsModelComponentGraphicItem *QgsModelGraphicsScene::createGroupBoxGraphicItem( QgsProcessingModelAlgorithm *model, QgsProcessingModelGroupBox *box ) const
83 {
84  return new QgsModelGroupBoxGraphicItem( box, model, nullptr );
85 }
86 
87 void QgsModelGraphicsScene::createItems( QgsProcessingModelAlgorithm *model, QgsProcessingContext &context )
88 {
89  // model group boxes
90  const QList<QgsProcessingModelGroupBox> boxes = model->groupBoxes();
91  mGroupBoxItems.clear();
92  for ( const QgsProcessingModelGroupBox &box : boxes )
93  {
94  QgsModelComponentGraphicItem *item = createGroupBoxGraphicItem( model, box.clone() );
95  addItem( item );
96  item->setPos( box.position().x(), box.position().y() );
97  mGroupBoxItems.insert( box.uuid(), item );
98  connect( item, &QgsModelComponentGraphicItem::requestModelRepaint, this, &QgsModelGraphicsScene::rebuildRequired );
99  connect( item, &QgsModelComponentGraphicItem::changed, this, &QgsModelGraphicsScene::componentChanged );
100  connect( item, &QgsModelComponentGraphicItem::aboutToChange, this, &QgsModelGraphicsScene::componentAboutToChange );
101  }
102 
103  // model input parameters
104  const QMap<QString, QgsProcessingModelParameter> params = model->parameterComponents();
105  for ( auto it = params.constBegin(); it != params.constEnd(); ++it )
106  {
107  QgsModelComponentGraphicItem *item = createParameterGraphicItem( model, it.value().clone() );
108  addItem( item );
109  item->setPos( it.value().position().x(), it.value().position().y() );
110  mParameterItems.insert( it.value().parameterName(), item );
111  connect( item, &QgsModelComponentGraphicItem::requestModelRepaint, this, &QgsModelGraphicsScene::rebuildRequired );
112  connect( item, &QgsModelComponentGraphicItem::changed, this, &QgsModelGraphicsScene::componentChanged );
113  connect( item, &QgsModelComponentGraphicItem::aboutToChange, this, &QgsModelGraphicsScene::componentAboutToChange );
114 
115  addCommentItemForComponent( model, it.value(), item );
116  }
117 
118  // input dependency arrows
119  for ( auto it = params.constBegin(); it != params.constEnd(); ++it )
120  {
121  const QgsProcessingParameterDefinition *parameterDef = model->parameterDefinition( it.key() );
122  const QStringList parameterLinks = parameterDef->dependsOnOtherParameters();
123  for ( const QString &otherName : parameterLinks )
124  {
125  if ( mParameterItems.contains( it.key() ) && mParameterItems.contains( otherName ) )
126  {
127  std::unique_ptr< QgsModelArrowItem > arrow = std::make_unique< QgsModelArrowItem >( mParameterItems.value( otherName ), QgsModelArrowItem::Marker::Circle, mParameterItems.value( it.key() ), QgsModelArrowItem::Marker::ArrowHead );
128  arrow->setPenStyle( Qt::DotLine );
129  addItem( arrow.release() );
130  }
131  }
132  }
133 
134  // child algorithms
135  const QMap<QString, QgsProcessingModelChildAlgorithm> childAlgs = model->childAlgorithms();
136  for ( auto it = childAlgs.constBegin(); it != childAlgs.constEnd(); ++it )
137  {
138  QgsModelChildAlgorithmGraphicItem *item = createChildAlgGraphicItem( model, it.value().clone() );
139  addItem( item );
140  item->setPos( it.value().position().x(), it.value().position().y() );
141  item->setResults( mChildResults.value( it.value().childId() ).toMap() );
142  item->setInputs( mChildInputs.value( it.value().childId() ).toMap() );
143  mChildAlgorithmItems.insert( it.value().childId(), item );
144  connect( item, &QgsModelComponentGraphicItem::requestModelRepaint, this, &QgsModelGraphicsScene::rebuildRequired );
145  connect( item, &QgsModelComponentGraphicItem::changed, this, &QgsModelGraphicsScene::componentChanged );
146  connect( item, &QgsModelComponentGraphicItem::aboutToChange, this, &QgsModelGraphicsScene::componentAboutToChange );
147 
148  addCommentItemForComponent( model, it.value(), item );
149  }
150 
151  // arrows linking child algorithms
152  for ( auto it = childAlgs.constBegin(); it != childAlgs.constEnd(); ++it )
153  {
154  int topIdx = 0;
155  int bottomIdx = 0;
156  if ( !it.value().algorithm() )
157  continue;
158 
159  const QgsProcessingParameterDefinitions parameters = it.value().algorithm()->parameterDefinitions();
160  for ( const QgsProcessingParameterDefinition *parameter : parameters )
161  {
162  if ( !( parameter->flags() & QgsProcessingParameterDefinition::FlagHidden ) )
163  {
164  QList< QgsProcessingModelChildParameterSource > sources;
165  if ( it.value().parameterSources().contains( parameter->name() ) )
166  sources = it.value().parameterSources()[parameter->name()];
167  for ( const QgsProcessingModelChildParameterSource &source : sources )
168  {
169  const QList< LinkSource > sourceItems = linkSourcesForParameterValue( model, QVariant::fromValue( source ), it.value().childId(), context );
170  for ( const LinkSource &link : sourceItems )
171  {
172  if ( !link.item )
173  continue;
174  QgsModelArrowItem *arrow = nullptr;
175  if ( link.linkIndex == -1 )
176  arrow = new QgsModelArrowItem( link.item, QgsModelArrowItem::Marker::Circle, mChildAlgorithmItems.value( it.value().childId() ), parameter->isDestination() ? Qt::BottomEdge : Qt::TopEdge, parameter->isDestination() ? bottomIdx : topIdx, QgsModelArrowItem::Marker::Circle );
177  else
178  arrow = new QgsModelArrowItem( link.item, link.edge, link.linkIndex, true, QgsModelArrowItem::Marker::Circle,
179  mChildAlgorithmItems.value( it.value().childId() ),
180  parameter->isDestination() ? Qt::BottomEdge : Qt::TopEdge,
181  parameter->isDestination() ? bottomIdx : topIdx,
182  true,
183  QgsModelArrowItem::Marker::Circle );
184  addItem( arrow );
185  }
186  }
187  if ( parameter->isDestination() )
188  bottomIdx++;
189  else
190  topIdx++;
191  }
192  }
193  const QList< QgsProcessingModelChildDependency > dependencies = it.value().dependencies();
194  for ( const QgsProcessingModelChildDependency &depend : dependencies )
195  {
196  if ( depend.conditionalBranch.isEmpty() || !model->childAlgorithm( depend.childId ).algorithm() )
197  {
198  addItem( new QgsModelArrowItem( mChildAlgorithmItems.value( depend.childId ), QgsModelArrowItem::Marker::Circle, mChildAlgorithmItems.value( it.value().childId() ), QgsModelArrowItem::Marker::ArrowHead ) );
199  }
200  else
201  {
202  // find branch link point
203  const QgsProcessingOutputDefinitions outputs = model->childAlgorithm( depend.childId ).algorithm()->outputDefinitions();
204  int i = 0;
205  bool found = false;
206  for ( const QgsProcessingOutputDefinition *output : outputs )
207  {
208  if ( output->name() == depend.conditionalBranch )
209  {
210  found = true;
211  break;
212  }
213  i++;
214  }
215  if ( found )
216  addItem( new QgsModelArrowItem( mChildAlgorithmItems.value( depend.childId ), Qt::BottomEdge, i, QgsModelArrowItem::Marker::Circle, mChildAlgorithmItems.value( it.value().childId() ), QgsModelArrowItem::Marker::ArrowHead ) );
217  }
218  }
219  }
220 
221  // and finally the model outputs
222  for ( auto it = childAlgs.constBegin(); it != childAlgs.constEnd(); ++it )
223  {
224  const QMap<QString, QgsProcessingModelOutput> outputs = it.value().modelOutputs();
225  QMap< QString, QgsModelComponentGraphicItem * > outputItems;
226 
227  // offsets from algorithm item needed to correctly place output items
228  // which does not have valid position assigned (https://github.com/qgis/QGIS/issues/48132)
229  QgsProcessingModelComponent *algItem = mChildAlgorithmItems[it.value().childId()]->component();
230  const double outputOffsetX = algItem->size().width();
231  double outputOffsetY = 1.5 * algItem->size().height();
232 
233  for ( auto outputIt = outputs.constBegin(); outputIt != outputs.constEnd(); ++outputIt )
234  {
235  QgsModelComponentGraphicItem *item = createOutputGraphicItem( model, outputIt.value().clone() );
236  addItem( item );
237  connect( item, &QgsModelComponentGraphicItem::requestModelRepaint, this, &QgsModelGraphicsScene::rebuildRequired );
238  connect( item, &QgsModelComponentGraphicItem::changed, this, &QgsModelGraphicsScene::componentChanged );
239  connect( item, &QgsModelComponentGraphicItem::aboutToChange, this, &QgsModelGraphicsScene::componentAboutToChange );
240 
241  // if output added not at the same time as algorithm then it does not have
242  // valid position and will be placed at (0,0). We need to calculate better position.
243  // See https://github.com/qgis/QGIS/issues/48132.
244  QPointF pos = outputIt.value().position();
245  if ( pos.isNull() )
246  {
247  pos = algItem->position() + QPointF( outputOffsetX, outputOffsetY );
248  outputOffsetY += 1.5 * outputIt.value().size().height();
249  }
250  int idx = -1;
251  int i = 0;
252  // find the actual index of the linked output from the child algorithm it comes from
253  if ( it.value().algorithm() )
254  {
255  const QgsProcessingOutputDefinitions sourceChildAlgOutputs = it.value().algorithm()->outputDefinitions();
256  for ( const QgsProcessingOutputDefinition *childAlgOutput : sourceChildAlgOutputs )
257  {
258  if ( childAlgOutput->name() == outputIt.value().childOutputName() )
259  {
260  idx = i;
261  break;
262  }
263  i++;
264  }
265  }
266 
267  item->setPos( pos );
268  outputItems.insert( outputIt.key(), item );
269  addItem( new QgsModelArrowItem( mChildAlgorithmItems[it.value().childId()], Qt::BottomEdge, idx, QgsModelArrowItem::Marker::Circle, item, QgsModelArrowItem::Marker::Circle ) );
270 
271  addCommentItemForComponent( model, outputIt.value(), item );
272  }
273  mOutputItems.insert( it.value().childId(), outputItems );
274  }
275 }
276 
277 QList<QgsModelComponentGraphicItem *> QgsModelGraphicsScene::selectedComponentItems()
278 {
279  QList<QgsModelComponentGraphicItem *> componentItemList;
280 
281  const QList<QGraphicsItem *> graphicsItemList = selectedItems();
282  for ( QGraphicsItem *item : graphicsItemList )
283  {
284  if ( QgsModelComponentGraphicItem *componentItem = dynamic_cast<QgsModelComponentGraphicItem *>( item ) )
285  {
286  componentItemList.push_back( componentItem );
287  }
288  }
289 
290  return componentItemList;
291 }
292 
293 QgsModelComponentGraphicItem *QgsModelGraphicsScene::componentItemAt( QPointF position ) const
294 {
295  //get a list of items which intersect the specified position, in descending z order
296  const QList<QGraphicsItem *> itemList = items( position, Qt::IntersectsItemShape, Qt::DescendingOrder );
297 
298  for ( QGraphicsItem *graphicsItem : itemList )
299  {
300  if ( QgsModelComponentGraphicItem *componentItem = dynamic_cast<QgsModelComponentGraphicItem *>( graphicsItem ) )
301  {
302  return componentItem;
303  }
304  }
305  return nullptr;
306 }
307 
308 QgsModelComponentGraphicItem *QgsModelGraphicsScene::groupBoxItem( const QString &uuid )
309 {
310  return mGroupBoxItems.value( uuid );
311 }
312 
313 void QgsModelGraphicsScene::selectAll()
314 {
315  //select all items in scene
316  QgsModelComponentGraphicItem *focusedItem = nullptr;
317  const QList<QGraphicsItem *> itemList = items();
318  for ( QGraphicsItem *graphicsItem : itemList )
319  {
320  if ( QgsModelComponentGraphicItem *componentItem = dynamic_cast<QgsModelComponentGraphicItem *>( graphicsItem ) )
321  {
322  componentItem->setSelected( true );
323  if ( !focusedItem )
324  focusedItem = componentItem;
325  }
326  }
327  emit selectedItemChanged( focusedItem );
328 }
329 
330 void QgsModelGraphicsScene::deselectAll()
331 {
332  //we can't use QGraphicsScene::clearSelection, as that emits no signals
333  //and we don't know which items are being deselected
334  //instead, do the clear selection manually...
335  const QList<QGraphicsItem *> selectedItemList = selectedItems();
336  for ( QGraphicsItem *item : selectedItemList )
337  {
338  if ( QgsModelComponentGraphicItem *componentItem = dynamic_cast<QgsModelComponentGraphicItem *>( item ) )
339  {
340  componentItem->setSelected( false );
341  }
342  }
343  emit selectedItemChanged( nullptr );
344 }
345 
346 void QgsModelGraphicsScene::setSelectedItem( QgsModelComponentGraphicItem *item )
347 {
348  whileBlocking( this )->deselectAll();
349  if ( item )
350  {
351  item->setSelected( true );
352  }
353  emit selectedItemChanged( item );
354 }
355 
356 void QgsModelGraphicsScene::setChildAlgorithmResults( const QVariantMap &results )
357 {
358  mChildResults = results;
359 
360  for ( auto it = mChildResults.constBegin(); it != mChildResults.constEnd(); ++it )
361  {
362  if ( QgsModelChildAlgorithmGraphicItem *item = mChildAlgorithmItems.value( it.key() ) )
363  {
364  item->setResults( it.value().toMap() );
365  }
366  }
367 }
368 
369 void QgsModelGraphicsScene::setChildAlgorithmInputs( const QVariantMap &inputs )
370 {
371  mChildInputs = inputs;
372 
373  for ( auto it = mChildInputs.constBegin(); it != mChildInputs.constEnd(); ++it )
374  {
375  if ( QgsModelChildAlgorithmGraphicItem *item = mChildAlgorithmItems.value( it.key() ) )
376  {
377  item->setInputs( it.value().toMap() );
378  }
379  }
380 }
381 
382 QList<QgsModelGraphicsScene::LinkSource> QgsModelGraphicsScene::linkSourcesForParameterValue( QgsProcessingModelAlgorithm *model, const QVariant &value, const QString &childId, QgsProcessingContext &context ) const
383 {
384  QList<QgsModelGraphicsScene::LinkSource> res;
385  if ( value.type() == QVariant::List )
386  {
387  const QVariantList list = value.toList();
388  for ( const QVariant &v : list )
389  res.append( linkSourcesForParameterValue( model, v, childId, context ) );
390  }
391  else if ( value.type() == QVariant::StringList )
392  {
393  const QStringList list = value.toStringList();
394  for ( const QString &v : list )
395  res.append( linkSourcesForParameterValue( model, v, childId, context ) );
396  }
397  else if ( value.canConvert< QgsProcessingModelChildParameterSource >() )
398  {
399  const QgsProcessingModelChildParameterSource source = value.value< QgsProcessingModelChildParameterSource >();
400  switch ( source.source() )
401  {
402  case QgsProcessingModelChildParameterSource::ModelParameter:
403  {
404  LinkSource l;
405  l.item = mParameterItems.value( source.parameterName() );
406  res.append( l );
407  break;
408  }
409  case QgsProcessingModelChildParameterSource::ChildOutput:
410  {
411  if ( !model->childAlgorithm( source.outputChildId() ).algorithm() )
412  break;
413 
414  const QgsProcessingOutputDefinitions outputs = model->childAlgorithm( source.outputChildId() ).algorithm()->outputDefinitions();
415  int i = 0;
416  for ( const QgsProcessingOutputDefinition *output : outputs )
417  {
418  if ( output->name() == source.outputName() )
419  break;
420  i++;
421  }
422  if ( mChildAlgorithmItems.contains( source.outputChildId() ) )
423  {
424  LinkSource l;
425  l.item = mChildAlgorithmItems.value( source.outputChildId() );
426  l.edge = Qt::BottomEdge;
427 
428  // do sanity check of linked index
429  if ( i >= model->childAlgorithm( source.outputChildId() ).algorithm()->outputDefinitions().length() )
430  {
431  QString short_message = tr( "Check output links for alg: %1" ).arg( model->childAlgorithm( source.outputChildId() ).algorithm()->name() );
432  QString long_message = tr( "Cannot link output for alg: %1" ).arg( model->childAlgorithm( source.outputChildId() ).algorithm()->name() );
433  QString title( tr( "Algorithm link error" ) );
434  if ( messageBar() )
435  showWarning( const_cast<QString &>( short_message ), const_cast<QString &>( title ), const_cast<QString &>( long_message ) );
436  else
437  QgsMessageLog::logMessage( long_message, "QgsModelGraphicsScene", Qgis::MessageLevel::Warning, true );
438  break;
439  }
440 
441  l.linkIndex = i;
442  res.append( l );
443  }
444 
445  break;
446  }
447 
448  case QgsProcessingModelChildParameterSource::Expression:
449  {
450  const QMap<QString, QgsProcessingModelAlgorithm::VariableDefinition> variables = model->variablesForChildAlgorithm( childId, context );
451  const QgsExpression exp( source.expression() );
452  const QSet<QString> vars = exp.referencedVariables();
453  for ( const QString &v : vars )
454  {
455  if ( variables.contains( v ) )
456  {
457  res.append( linkSourcesForParameterValue( model, QVariant::fromValue( variables.value( v ).source ), childId, context ) );
458  }
459  }
460  break;
461  }
462 
463  case QgsProcessingModelChildParameterSource::StaticValue:
464  case QgsProcessingModelChildParameterSource::ExpressionText:
465  case QgsProcessingModelChildParameterSource::ModelOutput:
466  break;
467  }
468  }
469  return res;
470 }
471 
472 void QgsModelGraphicsScene::addCommentItemForComponent( QgsProcessingModelAlgorithm *model, const QgsProcessingModelComponent &component, QgsModelComponentGraphicItem *parentItem )
473 {
474  if ( mFlags & FlagHideComments || !component.comment() || component.comment()->description().isEmpty() )
475  return;
476 
477  QgsModelComponentGraphicItem *commentItem = createCommentGraphicItem( model, component.comment()->clone(), parentItem );
478  commentItem->setPos( component.comment()->position().x(), component.comment()->position().y() );
479  addItem( commentItem );
480  connect( commentItem, &QgsModelComponentGraphicItem::requestModelRepaint, this, &QgsModelGraphicsScene::rebuildRequired );
481  connect( commentItem, &QgsModelComponentGraphicItem::changed, this, &QgsModelGraphicsScene::componentChanged );
482  connect( commentItem, &QgsModelComponentGraphicItem::aboutToChange, this, &QgsModelGraphicsScene::componentAboutToChange );
483 
484  std::unique_ptr< QgsModelArrowItem > arrow = std::make_unique< QgsModelArrowItem >( parentItem, QgsModelArrowItem::Circle, commentItem, QgsModelArrowItem::Circle );
485  arrow->setPenStyle( Qt::DotLine );
486  addItem( arrow.release() );
487 }
488 
489 QgsMessageBar *QgsModelGraphicsScene::messageBar() const
490 {
491  return mMessageBar;
492 }
493 
494 void QgsModelGraphicsScene::setMessageBar( QgsMessageBar *messageBar )
495 {
496  mMessageBar = messageBar;
497 }
498 
499 void QgsModelGraphicsScene::showWarning( const QString &shortMessage, const QString &title, const QString &longMessage, Qgis::MessageLevel level ) const
500 {
501  QgsMessageBarItem *messageWidget = QgsMessageBar::createMessage( QString(), shortMessage );
502  QPushButton *detailsButton = new QPushButton( tr( "Details" ) );
503  connect( detailsButton, &QPushButton::clicked, detailsButton, [ = ]
504  {
505  QgsMessageViewer *dialog = new QgsMessageViewer( detailsButton );
506  dialog->setTitle( title );
507  dialog->setMessage( longMessage, QgsMessageOutput::MessageHtml );
508  dialog->showMessage();
509  } );
510  messageWidget->layout()->addWidget( detailsButton );
511  mMessageBar->clearWidgets();
512  mMessageBar->pushWidget( messageWidget, level, 0 );
513 }
514 
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition: qgis.h:115
Class for parsing and evaluation of expressions (formerly called "search strings").
Represents an item shown within a QgsMessageBar widget.
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:61
static QgsMessageBarItem * createMessage(const QString &text, QWidget *parent=nullptr)
Creates message bar item widget containing a message text to be displayed on the bar.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
A generic message view for displaying QGIS messages.
void setTitle(const QString &title) override
Sets title for the messages.
void setMessage(const QString &message, MessageType msgType) override
Sets message, it won't be displayed until.
void showMessage(bool blocking=true) override
display the message to the user and deletes itself
QgsProcessingOutputDefinitions outputDefinitions() const
Returns an ordered list of output definitions utilized by the algorithm.
Contains information about the context in which a processing algorithm is executed.
Base class for the definition of processing outputs.
Base class for the definition of processing parameters.
@ FlagHidden
Parameter is hidden and should not be shown to users.
virtual QStringList dependsOnOtherParameters() const
Returns a list of other parameter names on which this parameter is dependent (e.g.
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.
Definition: qgis.h:2186
QList< const QgsProcessingOutputDefinition * > QgsProcessingOutputDefinitions
List of processing parameters.
QList< const QgsProcessingParameterDefinition * > QgsProcessingParameterDefinitions
List of processing parameters.