QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
qgsrendererwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrendererwidget.cpp
3  ---------------------
4  begin : November 2009
5  copyright : (C) 2009 by Martin Dobias
6  email : wonder dot sk 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 #include "qgsrendererwidget.h"
16 
18 #include "qgssymbol.h"
19 #include "qgsvectorlayer.h"
20 #include "qgscolordialog.h"
21 #include "qgssymbollevelsdialog.h"
22 #include "qgssymbollayer.h"
24 #include "qgsmapcanvas.h"
25 #include "qgspanelwidget.h"
26 #include "qgsproject.h"
28 #include "qgssymbollayerutils.h"
29 #include "qgstemporalcontroller.h"
30 
31 #include <QMessageBox>
32 #include <QInputDialog>
33 #include <QMenu>
34 #include <QClipboard>
35 
37  : mLayer( layer )
38  , mStyle( style )
39 {
40  contextMenu = new QMenu( tr( "Renderer Options" ), this );
41 
42  mCopyAction = new QAction( tr( "Copy" ), this );
43  connect( mCopyAction, &QAction::triggered, this, &QgsRendererWidget::copy );
44  mCopyAction->setShortcut( QKeySequence( QKeySequence::Copy ) );
45  mPasteAction = new QAction( tr( "Paste" ), this );
46  mPasteAction->setShortcut( QKeySequence( QKeySequence::Paste ) );
47  connect( mPasteAction, &QAction::triggered, this, &QgsRendererWidget::paste );
48 
49  mCopySymbolAction = new QAction( tr( "Copy Symbol" ), this );
50  contextMenu->addAction( mCopySymbolAction );
51  connect( mCopySymbolAction, &QAction::triggered, this, &QgsRendererWidget::copySymbol );
52  mPasteSymbolAction = new QAction( tr( "Paste Symbol" ), this );
53  contextMenu->addAction( mPasteSymbolAction );
54  connect( mPasteSymbolAction, &QAction::triggered, this, &QgsRendererWidget::pasteSymbolToSelection );
55 
56  contextMenu->addSeparator();
57  contextMenu->addAction( tr( "Change Color…" ), this, SLOT( changeSymbolColor() ) );
58  contextMenu->addAction( tr( "Change Opacity…" ), this, SLOT( changeSymbolOpacity() ) );
59  contextMenu->addAction( tr( "Change Output Unit…" ), this, SLOT( changeSymbolUnit() ) );
60 
62  {
63  contextMenu->addAction( tr( "Change Width…" ), this, SLOT( changeSymbolWidth() ) );
64  }
66  {
67  contextMenu->addAction( tr( "Change Size…" ), this, SLOT( changeSymbolSize() ) );
68  contextMenu->addAction( tr( "Change Angle…" ), this, SLOT( changeSymbolAngle() ) );
69  }
70 
71  connect( contextMenu, &QMenu::aboutToShow, this, [ = ]
72  {
73  std::unique_ptr< QgsSymbol > tempSymbol( QgsSymbolLayerUtils::symbolFromMimeData( QApplication::clipboard()->mimeData() ) );
74  mPasteSymbolAction->setEnabled( static_cast< bool >( tempSymbol ) );
75  } );
76 }
77 
79 {
80  contextMenu->exec( QCursor::pos() );
81 }
82 
84 {
85  const QList<QgsSymbol *> symbolList = selectedSymbols();
86  if ( symbolList.isEmpty() )
87  {
88  return;
89  }
90 
91  QgsSymbol *firstSymbol = nullptr;
92  for ( QgsSymbol *symbol : symbolList )
93  {
94  if ( symbol )
95  {
96  firstSymbol = symbol;
97  break;
98  }
99  }
100  if ( !firstSymbol )
101  return;
102 
103  QColor currentColor = firstSymbol->color();
104 
105  QgsPanelWidget *panel = QgsPanelWidget::findParentPanel( qobject_cast< QWidget * >( parent() ) );
106  if ( panel && panel->dockMode() )
107  {
109  colorWidget->setPanelTitle( tr( "Change Symbol Color" ) );
110  colorWidget->setAllowOpacity( true );
111  connect( colorWidget, &QgsCompoundColorWidget::currentColorChanged, this, [ = ]( const QColor & color )
112  {
113  for ( QgsSymbol *symbol : symbolList )
114  {
115  if ( symbol )
116  symbol->setColor( color );
117  }
119  } );
120  panel->openPanel( colorWidget );
121  }
122  else
123  {
124  // modal dialog version... yuck
125  QColor color = QgsColorDialog::getColor( firstSymbol->color(), this, QStringLiteral( "Change Symbol Color" ), true );
126  if ( color.isValid() )
127  {
128  for ( QgsSymbol *symbol : symbolList )
129  {
130  if ( symbol )
131  symbol->setColor( color );
132  }
134  }
135  }
136 }
137 
139 {
140  QList<QgsSymbol *> symbolList = selectedSymbols();
141  if ( symbolList.isEmpty() )
142  {
143  return;
144  }
145 
146  QgsSymbol *firstSymbol = nullptr;
147  const auto constSymbolList = symbolList;
148  for ( QgsSymbol *symbol : constSymbolList )
149  {
150  if ( symbol )
151  {
152  firstSymbol = symbol;
153  break;
154  }
155  }
156  if ( !firstSymbol )
157  return;
158 
159  bool ok;
160  double oldOpacity = firstSymbol->opacity() * 100; // convert to %
161  double opacity = QInputDialog::getDouble( this, tr( "Opacity" ), tr( "Change symbol opacity [%]" ), oldOpacity, 0.0, 100.0, 1, &ok );
162  if ( ok )
163  {
164  const auto constSymbolList = symbolList;
165  for ( QgsSymbol *symbol : constSymbolList )
166  {
167  if ( symbol )
168  symbol->setOpacity( opacity / 100.0 );
169  }
171  }
172 }
173 
175 {
176  QList<QgsSymbol *> symbolList = selectedSymbols();
177  if ( symbolList.isEmpty() )
178  {
179  return;
180  }
181 
182  QgsSymbol *firstSymbol = nullptr;
183  const auto constSymbolList = symbolList;
184  for ( QgsSymbol *symbol : constSymbolList )
185  {
186  if ( symbol )
187  {
188  firstSymbol = symbol;
189  break;
190  }
191  }
192  if ( !firstSymbol )
193  return;
194 
195  bool ok;
196  int currentUnit = ( firstSymbol->outputUnit() == QgsUnitTypes::RenderMillimeters ) ? 0 : 1;
197  QString item = QInputDialog::getItem( this, tr( "Symbol unit" ), tr( "Select symbol unit" ), QStringList() << tr( "Millimeter" ) << tr( "Map unit" ), currentUnit, false, &ok );
198  if ( ok )
199  {
200  QgsUnitTypes::RenderUnit unit = ( item.compare( tr( "Millimeter" ) ) == 0 ) ? QgsUnitTypes::RenderMillimeters : QgsUnitTypes::RenderMapUnits;
201 
202  const auto constSymbolList = symbolList;
203  for ( QgsSymbol *symbol : constSymbolList )
204  {
205  if ( symbol )
206  symbol->setOutputUnit( unit );
207  }
209  }
210 }
211 
213 {
214  QList<QgsSymbol *> symbolList = selectedSymbols();
215  if ( symbolList.isEmpty() )
216  {
217  return;
218  }
219 
220  QgsDataDefinedWidthDialog dlg( symbolList, mLayer );
221 
222  dlg.setContext( mContext );
223 
224  if ( QDialog::Accepted == dlg.exec() )
225  {
226  if ( !dlg.mDDBtn->isActive() )
227  {
228  const auto constSymbolList = symbolList;
229  for ( QgsSymbol *symbol : constSymbolList )
230  {
231  if ( !symbol )
232  continue;
233 
234  if ( symbol->type() == QgsSymbol::Line )
235  static_cast<QgsLineSymbol *>( symbol )->setWidth( dlg.mSpinBox->value() );
236  }
237  }
239  }
240 }
241 
243 {
244  QList<QgsSymbol *> symbolList = selectedSymbols();
245  if ( symbolList.isEmpty() )
246  {
247  return;
248  }
249 
250  QgsDataDefinedSizeDialog dlg( symbolList, mLayer );
251  dlg.setContext( mContext );
252 
253  if ( QDialog::Accepted == dlg.exec() )
254  {
255  if ( !dlg.mDDBtn->isActive() )
256  {
257  const auto constSymbolList = symbolList;
258  for ( QgsSymbol *symbol : constSymbolList )
259  {
260  if ( !symbol )
261  continue;
262 
263  if ( symbol->type() == QgsSymbol::Marker )
264  static_cast<QgsMarkerSymbol *>( symbol )->setSize( dlg.mSpinBox->value() );
265  }
266  }
268  }
269 }
270 
272 {
273  QList<QgsSymbol *> symbolList = selectedSymbols();
274  if ( symbolList.isEmpty() )
275  {
276  return;
277  }
278 
279  QgsDataDefinedRotationDialog dlg( symbolList, mLayer );
280  dlg.setContext( mContext );
281 
282  if ( QDialog::Accepted == dlg.exec() )
283  {
284  if ( !dlg.mDDBtn->isActive() )
285  {
286  const auto constSymbolList = symbolList;
287  for ( QgsSymbol *symbol : constSymbolList )
288  {
289  if ( !symbol )
290  continue;
291 
292  if ( symbol->type() == QgsSymbol::Marker )
293  static_cast<QgsMarkerSymbol *>( symbol )->setAngle( dlg.mSpinBox->value() );
294  }
295  }
297  }
298 }
299 
301 {
302 
303 }
304 
305 void QgsRendererWidget::copySymbol()
306 {
307  QList<QgsSymbol *> symbolList = selectedSymbols();
308  if ( symbolList.isEmpty() )
309  {
310  return;
311  }
312 
313  QApplication::clipboard()->setMimeData( QgsSymbolLayerUtils::symbolToMimeData( symbolList.at( 0 ) ) );
314 }
315 
317 {
319  if ( panel && panel->dockMode() )
320  {
321  QgsSymbolLevelsWidget *widget = new QgsSymbolLevelsWidget( r, r->usingSymbolLevels(), panel );
322  widget->setPanelTitle( tr( "Symbol Levels" ) );
323  connect( widget, &QgsPanelWidget::widgetChanged, widget, &QgsSymbolLevelsWidget::apply );
324  connect( widget, &QgsPanelWidget::widgetChanged, this, [ = ]() { emit widgetChanged(); emit symbolLevelsChanged(); } );
325  panel->openPanel( widget );
326  return;
327  }
328 
329  QgsSymbolLevelsDialog dlg( r, r->usingSymbolLevels(), panel );
330  if ( dlg.exec() )
331  {
332  emit widgetChanged();
333  emit symbolLevelsChanged();
334  }
335 }
336 
338 {
339  mContext = context;
340 }
341 
343 {
344  return mContext;
345 }
346 
348 {
349  apply();
350 }
351 
352 void QgsRendererWidget::setDockMode( bool dockMode )
353 {
354  if ( dockMode )
355  {
356  // when in dock mode, these shortcuts conflict with the main window shortcuts and cannot be used
357  if ( mCopyAction )
358  mCopyAction->setShortcut( QKeySequence() );
359  if ( mPasteAction )
360  mPasteAction->setShortcut( QKeySequence() );
361  }
363 }
364 
366 {
367  QgsProperty ddSize = symbol->dataDefinedSize();
368  if ( !ddSize || !ddSize.isActive() )
369  {
370  QMessageBox::warning( this, tr( "Data-defined Size Legend" ), tr( "Data-defined size is not enabled!" ) );
371  return nullptr;
372  }
373 
374  QgsDataDefinedSizeLegendWidget *panel = new QgsDataDefinedSizeLegendWidget( ddsLegend, ddSize, symbol->clone(), mContext.mapCanvas() );
376  return panel;
377 }
378 
379 
380 //
381 // QgsDataDefinedValueDialog
382 //
383 
384 QgsDataDefinedValueDialog::QgsDataDefinedValueDialog( const QList<QgsSymbol *> &symbolList, QgsVectorLayer *layer, const QString &label )
385  : mSymbolList( symbolList )
386  , mLayer( layer )
387 {
388  setupUi( this );
389  setWindowFlags( Qt::WindowStaysOnTopHint );
390  mLabel->setText( label );
392 }
393 
395 {
396  mContext = context;
397 }
398 
400 {
401  return mContext;
402 }
403 
404 QgsExpressionContext QgsDataDefinedValueDialog::createExpressionContext() const
405 {
406  QgsExpressionContext expContext;
410  if ( auto *lMapCanvas = mContext.mapCanvas() )
411  {
412  expContext << QgsExpressionContextUtils::mapSettingsScope( lMapCanvas->mapSettings() )
413  << new QgsExpressionContextScope( lMapCanvas->expressionContextScope() );
414 
415  if ( const QgsExpressionContextScopeGenerator *generator = dynamic_cast< const QgsExpressionContextScopeGenerator * >( lMapCanvas->temporalController() ) )
416  {
417  expContext << generator->createExpressionContextScope();
418  }
419  }
420  else
421  {
423  }
424 
425  if ( auto *lVectorLayer = vectorLayer() )
426  expContext << QgsExpressionContextUtils::layerScope( lVectorLayer );
427 
428  // additional scopes
429  const auto constAdditionalExpressionContextScopes = mContext.additionalExpressionContextScopes();
430  for ( const QgsExpressionContextScope &scope : constAdditionalExpressionContextScopes )
431  {
432  expContext.appendScope( new QgsExpressionContextScope( scope ) );
433  }
434 
435  return expContext;
436 }
437 
438 void QgsDataDefinedValueDialog::init( int propertyKey )
439 {
440  QgsProperty dd( symbolDataDefined() );
441 
442  mDDBtn->init( propertyKey, dd, QgsSymbolLayer::propertyDefinitions(), mLayer );
443  mDDBtn->registerExpressionContextGenerator( this );
444 
445  QgsSymbol *initialSymbol = nullptr;
446  const auto constMSymbolList = mSymbolList;
447  for ( QgsSymbol *symbol : constMSymbolList )
448  {
449  if ( symbol )
450  {
451  initialSymbol = symbol;
452  }
453  }
454  mSpinBox->setValue( initialSymbol ? value( initialSymbol ) : 0 );
455  mSpinBox->setEnabled( !mDDBtn->isActive() );
456 }
457 
458 QgsProperty QgsDataDefinedValueDialog::symbolDataDefined() const
459 {
460  if ( mSymbolList.isEmpty() || !mSymbolList.back() )
461  return QgsProperty();
462 
463  // check that all symbols share the same size expression
464  QgsProperty dd = symbolDataDefined( mSymbolList.back() );
465  const auto constMSymbolList = mSymbolList;
466  for ( QgsSymbol *it : constMSymbolList )
467  {
468  QgsProperty symbolDD( symbolDataDefined( it ) );
469  if ( !it || !dd || !symbolDD || symbolDD != dd )
470  return QgsProperty();
471  }
472  return dd;
473 }
474 
476 {
477  QgsProperty dd( mDDBtn->toProperty() );
478  mSpinBox->setEnabled( !dd.isActive() );
479 
480  QgsProperty symbolDD( symbolDataDefined() );
481 
482  if ( // shall we remove datadefined expressions for layers ?
483  ( symbolDD && symbolDD.isActive() && !dd.isActive() )
484  // shall we set the "en masse" expression for properties ?
485  || dd.isActive() )
486  {
487  const auto constMSymbolList = mSymbolList;
488  for ( QgsSymbol *it : constMSymbolList )
489  setDataDefined( it, dd );
490  }
491 }
492 
494 {
495  const QgsMarkerSymbol *marker = static_cast<const QgsMarkerSymbol *>( symbol );
496  return marker->dataDefinedSize();
497 }
498 
500 {
501  static_cast<QgsMarkerSymbol *>( symbol )->setDataDefinedSize( dd );
502  static_cast<QgsMarkerSymbol *>( symbol )->setScaleMethod( QgsSymbol::ScaleDiameter );
503 }
504 
505 
507 {
508  const QgsMarkerSymbol *marker = static_cast<const QgsMarkerSymbol *>( symbol );
509  return marker->dataDefinedAngle();
510 }
511 
513 {
514  static_cast<QgsMarkerSymbol *>( symbol )->setDataDefinedAngle( dd );
515 }
516 
517 
519 {
520  const QgsLineSymbol *line = static_cast<const QgsLineSymbol *>( symbol );
521  return line->dataDefinedWidth();
522 }
523 
525 {
526  static_cast<QgsLineSymbol *>( symbol )->setDataDefinedWidth( dd );
527 }
528 
529 void QgsRendererWidget::apply()
530 {
531 
532 }
static QColor getColor(const QColor &initialColor, QWidget *parent, const QString &title=QString(), bool allowOpacity=false)
Returns a color selection from a color dialog.
A custom QGIS widget for selecting a color, including options for selecting colors via hue wheel,...
@ LayoutVertical
Use a narrower, vertically stacked layout.
void currentColorChanged(const QColor &color)
Emitted when the dialog's color changes.
void setAllowOpacity(bool allowOpacity)
Sets whether opacity modification (transparency) is permitted for the color dialog.
void setDataDefined(QgsSymbol *symbol, const QgsProperty &dd) override
double value(const QgsSymbol *symbol) const override
QgsProperty symbolDataDefined(const QgsSymbol *symbol) const override
QgsProperty symbolDataDefined(const QgsSymbol *symbol) const override
void setDataDefined(QgsSymbol *symbol, const QgsProperty &dd) override
double value(const QgsSymbol *symbol) const override
Widget for configuration of appearance of legend for marker symbols with data-defined size.
Object that keeps configuration of appearance of marker symbol's data-defined size in legend.
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
QgsDataDefinedValueDialog(const QList< QgsSymbol * > &symbolList, QgsVectorLayer *layer, const QString &label)
Constructor.
QgsSymbolWidgetContext context() const
Returns the context in which the symbol widget is shown, e.g., the associated map canvas and expressi...
const QgsVectorLayer * vectorLayer() const
Returns the vector layer associated with the widget.
void init(int propertyKey)
Should be called in the constructor of child classes.
QgsProperty symbolDataDefined(const QgsSymbol *symbol) const override
double value(const QgsSymbol *symbol) const override
void setDataDefined(QgsSymbol *symbol, const QgsProperty &dd) override
Abstract interface for generating an expression context scope.
Single scope for storing variables and functions for use within a QgsExpressionContext.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * atlasScope(const QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
bool usingSymbolLevels() const
Definition: qgsrenderer.h:283
A line symbol type, for rendering LineString and MultiLineString geometries.
Definition: qgssymbol.h:1204
QgsProperty dataDefinedWidth() const
Returns data defined width for whole symbol (including all symbol layers).
Definition: qgssymbol.cpp:2171
The QgsMapSettings class contains configuration for rendering of the map.
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgssymbol.h:1004
QgsProperty dataDefinedAngle() const
Returns data defined angle for whole symbol (including all symbol layers).
Definition: qgssymbol.cpp:1664
QgsProperty dataDefinedSize() const
Returns data defined size for whole symbol (including all symbol layers).
Definition: qgssymbol.cpp:1869
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgssymbol.cpp:2036
Base class for any widget that can be shown as a inline panel.
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
void widgetChanged()
Emitted when the widget state changes.
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
virtual void setDockMode(bool dockMode)
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
bool dockMode()
Returns the dock mode state.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:501
void changed()
Emitted when property definition changes.
A store for object properties.
Definition: qgsproperty.h:232
bool isActive() const
Returns whether the property is currently active.
QAction * mPasteSymbolAction
Paste symbol action.
void changeSymbolSize()
Change marker sizes of selected symbols.
virtual void paste()
virtual void pasteSymbolToSelection()
Pastes the clipboard symbol over selected items.
virtual QList< QgsSymbol * > selectedSymbols()
Subclasses may provide the capability of changing multiple symbols at once by implementing the follow...
QgsRendererWidget(QgsVectorLayer *layer, QgsStyle *style)
virtual void refreshSymbolView()
void symbolLevelsChanged()
Emitted when the symbol levels settings have been changed.
void showSymbolLevelsDialog(QgsFeatureRenderer *r)
show a dialog with renderer's symbol level settings
void changeSymbolOpacity()
Change opacity of selected symbols.
void changeSymbolWidth()
Change line widths of selected symbols.
void setDockMode(bool dockMode) override
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
QgsSymbolWidgetContext mContext
Context in which widget is shown.
void changeSymbolUnit()
Change units mm/map units of selected symbols.
virtual void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the renderer widget is shown, e.g., the associated map canvas and expressio...
QgsDataDefinedSizeLegendWidget * createDataDefinedSizeLegendWidget(const QgsMarkerSymbol *symbol, const QgsDataDefinedSizeLegend *ddsLegend)
Creates widget to setup data-defined size legend.
void contextMenuViewCategories(QPoint p)
QgsSymbolWidgetContext context() const
Returns the context in which the renderer widget is shown, e.g., the associated map canvas and expres...
void changeSymbolColor()
Change color of selected symbols.
QAction * mCopySymbolAction
Copy symbol action.
void changeSymbolAngle()
Change marker angles of selected symbols.
virtual void copy()
void applyChanges()
This method should be called whenever the renderer is actually set on the layer.
QgsVectorLayer * mLayer
static QgsSymbol * symbolFromMimeData(const QMimeData *data)
Attempts to parse mime data as a symbol.
static QMimeData * symbolToMimeData(const QgsSymbol *symbol)
Creates new mime data from a symbol.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the symbol layer property definitions.
A dialog which allows the user to modify the rendering order of symbol layers.
A widget which allows the user to modify the rendering order of symbol layers.
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
QList< QgsExpressionContextScope > additionalExpressionContextScopes() const
Returns the list of additional expression context scopes to show as available within the layer.
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:65
@ ScaleDiameter
Calculate scale by the diameter.
Definition: qgssymbol.h:100
QgsUnitTypes::RenderUnit outputUnit() const
Returns the units to use for sizes and widths within the symbol.
Definition: qgssymbol.cpp:266
qreal opacity() const
Returns the opacity for the symbol.
Definition: qgssymbol.h:481
@ Line
Line symbol.
Definition: qgssymbol.h:89
@ Marker
Marker symbol.
Definition: qgssymbol.h:88
QColor color() const
Returns the symbol's color.
Definition: qgssymbol.cpp:542
RenderUnit
Rendering size units.
Definition: qgsunittypes.h:167
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:168
@ RenderMapUnits
Map units.
Definition: qgsunittypes.h:169
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.