QGIS API Documentation 3.99.0-Master (c22de0620c0)
Loading...
Searching...
No Matches
qgsplotwidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsplotwidget.cpp
3 -----------------
4 begin : August 2025
5 copyright : (C) 2025 by Mathieu Pellerin
6 email : mathieu dot opengis dot ch
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 "qgsplotwidget.h"
17
18#include "qgsapplication.h"
19#include "qgsbarchartplot.h"
20#include "qgscolorrampbutton.h"
22#include "qgsfillsymbol.h"
23#include "qgslinechartplot.h"
24#include "qgslinesymbol.h"
26#include "qgspiechartplot.h"
27#include "qgsplotregistry.h"
28
29#include <QString>
30
31#include "moc_qgsplotwidget.cpp"
32
33using namespace Qt::StringLiterals;
34
36{
37 mExpressionContextGenerator = generator;
38}
39
41{
43 if ( mExpressionContextGenerator )
44 {
45 context = mExpressionContextGenerator->createExpressionContext();
46 }
47 else
48 {
50 }
51
52 auto plotScope = std::make_unique<QgsExpressionContextScope>( u"plot"_s );
53 plotScope->addVariable( QgsExpressionContextScope::StaticVariable( u"plot_axis"_s, QString(), true ) );
54 plotScope->addVariable( QgsExpressionContextScope::StaticVariable( u"plot_axis_value"_s, 0.0, true ) );
55 context.appendScope( plotScope.release() );
56
57 auto chartScope = std::make_unique<QgsExpressionContextScope>( u"chart"_s );
58 chartScope->addVariable( QgsExpressionContextScope::StaticVariable( u"chart_series_name"_s, QString(), true ) );
59 chartScope->addVariable( QgsExpressionContextScope::StaticVariable( u"chart_category"_s, QString(), true ) );
60 chartScope->addVariable( QgsExpressionContextScope::StaticVariable( u"chart_value"_s, 0.0, true ) );
61 context.appendScope( chartScope.release() );
62
63 context.setHighlightedVariables( { u"plot_axis"_s, u"plot_axis_value"_s, u"chart_series_name"_s, u"chart_category"_s, u"chart_value"_s } );
64
65 return context;
66}
67
69{
70 button->blockSignals( true );
71 button->init( static_cast< int >( key ), mPropertyCollection, QgsPlot::propertyDefinitions(), nullptr );
72 connect( button, &QgsPropertyOverrideButton::changed, this, &QgsPlotWidget::updateProperty );
74 button->blockSignals( false );
75}
76
78{
79 if ( !button )
80 {
81 return;
82 }
83
84 if ( button->propertyKey() < 0 )
85 {
86 return;
87 }
88
89 const QgsPlot::DataDefinedProperty key = static_cast<QgsPlot::DataDefinedProperty>( button->propertyKey() );
90 whileBlocking( button )->setToProperty( mPropertyCollection.property( key ) );
91}
92
93void QgsPlotWidget::updateProperty()
94{
95 QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
96 const QgsPlot::DataDefinedProperty key = static_cast<QgsPlot::DataDefinedProperty>( button->propertyKey() );
98 emit widgetChanged();
99}
100
101
103 : QgsPlotWidget( parent )
104{
105 setupUi( this );
106
107 setPanelTitle( tr( "Bar Chart Plot Properties" ) );
108
109 mSymbolsList->setColumnCount( 2 );
110 mSymbolsList->setSelectionBehavior( QAbstractItemView::SelectRows );
111 mSymbolsList->setSelectionMode( QAbstractItemView::ExtendedSelection );
112 mSymbolsList->setSortingEnabled( false );
113 mSymbolsList->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::Stretch );
114 mSymbolsList->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Stretch );
115 mSymbolsList->horizontalHeader()->hide();
116 mSymbolsList->verticalHeader()->hide();
117
118 connect( mAddSymbolPushButton, &QPushButton::clicked, this, &QgsBarChartPlotWidget::mAddSymbolPushButton_clicked );
119 connect( mRemoveSymbolPushButton, &QPushButton::clicked, this, &QgsBarChartPlotWidget::mRemoveSymbolPushButton_clicked );
120
121 mSpinMinXAxis->setClearValue( 0 );
122 connect( mSpinMinXAxis, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
123 if ( mBlockChanges )
124 return;
125 emit widgetChanged();
126 } );
127
128 connect( mSpinMaxXAxis, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
129 if ( mBlockChanges )
130 return;
131 emit widgetChanged();
132 } );
133
134 mSpinMinYAxis->setClearValue( 0 );
135 connect( mSpinMinYAxis, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
136 if ( mBlockChanges )
137 return;
138 emit widgetChanged();
139 } );
140
141 mSpinMaxYAxis->setClearValue( 0 );
142 connect( mSpinMaxYAxis, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
143 if ( mBlockChanges )
144 return;
145 emit widgetChanged();
146 } );
147
148 mXAxisMajorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
149 connect( mXAxisMajorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
150 if ( mBlockChanges )
151 return;
152 emit widgetChanged();
153 } );
154 mXAxisMajorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMajorSymbol() );
155
156 mXAxisMinorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
157 connect( mXAxisMinorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
158 if ( mBlockChanges )
159 return;
160 emit widgetChanged();
161 } );
162 mXAxisMinorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMinorSymbol() );
163
164 connect( mXAxisMajorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
165 if ( mBlockChanges )
166 return;
167 emit widgetChanged();
168 } );
169
170 connect( mXAxisMinorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
171 if ( mBlockChanges )
172 return;
173 emit widgetChanged();
174 } );
175
176 connect( mXAxisLabelIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
177 if ( mBlockChanges )
178 return;
179 emit widgetChanged();
180 } );
181
182 mYAxisMajorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
183 connect( mYAxisMajorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
184 if ( mBlockChanges )
185 return;
186 emit widgetChanged();
187 } );
188 mYAxisMajorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMajorSymbol() );
189
190 mYAxisMinorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
191 connect( mYAxisMinorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
192 if ( mBlockChanges )
193 return;
194 emit widgetChanged();
195 } );
196 mYAxisMinorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMinorSymbol() );
197
198 connect( mYAxisLabelIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
199 if ( mBlockChanges )
200 return;
201 emit widgetChanged();
202 } );
203
204 connect( mYAxisMajorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
205 if ( mBlockChanges )
206 return;
207 emit widgetChanged();
208 } );
209
210 connect( mYAxisMinorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
211 if ( mBlockChanges )
212 return;
213 emit widgetChanged();
214 } );
215
216 mChartBackgroundSymbolButton->setSymbolType( Qgis::SymbolType::Fill );
217 connect( mChartBackgroundSymbolButton, &QgsSymbolButton::changed, this, [this] {
218 if ( mBlockChanges )
219 return;
220 emit widgetChanged();
221 } );
222 mChartBackgroundSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::chartBackgroundSymbol() );
223
224 mChartBorderSymbolButton->setSymbolType( Qgis::SymbolType::Fill );
225 connect( mChartBorderSymbolButton, &QgsSymbolButton::changed, this, [this] {
226 if ( mBlockChanges )
227 return;
228 emit widgetChanged();
229 } );
230 mChartBorderSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::chartBorderSymbol() );
231
232 connect( mXAxisLabelFormatButton, &QPushButton::clicked, this, [this] {
234 widget->setPanelTitle( tr( "X Axis Number Format" ) );
235 widget->setFormat( mXAxisNumericFormat.get() );
236 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [this, widget] {
237 mXAxisNumericFormat.reset( widget->format() );
238 emit widgetChanged();
239 } );
240 openPanel( widget );
241 } );
242
243 connect( mYAxisLabelFormatButton, &QPushButton::clicked, this, [this] {
245 widget->setPanelTitle( tr( "Y Axis Number Format" ) );
246 widget->setFormat( mYAxisNumericFormat.get() );
247 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [this, widget] {
248 mYAxisNumericFormat.reset( widget->format() );
249 emit widgetChanged();
250 } );
251 openPanel( widget );
252 } );
253
254 mXAxisLabelFontButton->setDialogTitle( tr( "X Axis Label Font" ) );
255 mYAxisLabelFontButton->setDialogTitle( tr( "Y Axis Label Font" ) );
256 mXAxisLabelFontButton->setMode( QgsFontButton::ModeTextRenderer );
257 mYAxisLabelFontButton->setMode( QgsFontButton::ModeTextRenderer );
258
259 connect( mXAxisLabelFontButton, &QgsFontButton::changed, this, [this] {
260 if ( mBlockChanges )
261 return;
262 emit widgetChanged();
263 } );
264
265 connect( mYAxisLabelFontButton, &QgsFontButton::changed, this, [this] {
266 if ( mBlockChanges )
267 return;
268 emit widgetChanged();
269 } );
270
271 mSpinLeftMargin->setClearValue( 0 );
272 connect( mSpinLeftMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
273 if ( mBlockChanges )
274 return;
275 emit widgetChanged();
276 } );
277
278 mSpinRightMargin->setClearValue( 0 );
279 connect( mSpinRightMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
280 if ( mBlockChanges )
281 return;
282 emit widgetChanged();
283 } );
284
285 mSpinTopMargin->setClearValue( 0 );
286 connect( mSpinTopMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
287 if ( mBlockChanges )
288 return;
289 emit widgetChanged();
290 } );
291
292 mSpinBottomMargin->setClearValue( 0 );
293 connect( mSpinBottomMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
294 if ( mBlockChanges )
295 return;
296 emit widgetChanged();
297 } );
298
299 mXAxisTypeCombo->addItem( tr( "Interval" ), QVariant::fromValue( Qgis::PlotAxisType::Interval ) );
300 mXAxisTypeCombo->addItem( tr( "Categorical" ), QVariant::fromValue( Qgis::PlotAxisType::Categorical ) );
301 connect( mXAxisTypeCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
302 if ( mBlockChanges )
303 return;
304 emit widgetChanged();
305 } );
306
307 mXAxisLabelsCombo->addItem( tr( "None" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::NoLabels ) );
308 mXAxisLabelsCombo->addItem( tr( "Every Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::EveryLabel ) );
309 mXAxisLabelsCombo->addItem( tr( "First Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::FirstLabel ) );
310 mXAxisLabelsCombo->addItem( tr( "Last Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::LastLabel ) );
311 mXAxisLabelsCombo->addItem( tr( "First and Last Values" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::FirstAndLastLabels ) );
312 connect( mXAxisLabelsCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
313 if ( mBlockChanges )
314 return;
315 emit widgetChanged();
316 } );
317
318 mXAxisMajorLinesSymbolButton->registerExpressionContextGenerator( this );
319 mXAxisMinorLinesSymbolButton->registerExpressionContextGenerator( this );
320 mXAxisLabelFontButton->registerExpressionContextGenerator( this );
321 mYAxisMajorLinesSymbolButton->registerExpressionContextGenerator( this );
322 mYAxisMinorLinesSymbolButton->registerExpressionContextGenerator( this );
323 mYAxisLabelFontButton->registerExpressionContextGenerator( this );
324 mChartBackgroundSymbolButton->registerExpressionContextGenerator( this );
325 mChartBorderSymbolButton->registerExpressionContextGenerator( this );
326
331
338
343}
344
345void QgsBarChartPlotWidget::mAddSymbolPushButton_clicked()
346{
347 const int row = mSymbolsList->rowCount();
348 mSymbolsList->insertRow( row );
349
350 QTableWidgetItem *item = new QTableWidgetItem();
351 item->setData( Qt::DisplayRole, tr( "Symbol" ) );
352 mSymbolsList->setItem( row, 0, item );
353
354 QgsSymbolButton *symbolButton = new QgsSymbolButton( this );
355 symbolButton->setSymbolType( Qgis::SymbolType::Fill );
356 symbolButton->setShowNull( true );
358 symbolButton->registerExpressionContextGenerator( this );
359 connect( symbolButton, &QgsSymbolButton::changed, this, [this] {
360 if ( mBlockChanges )
361 return;
362 emit widgetChanged();
363 } );
364 mSymbolsList->setCellWidget( row, 1, symbolButton );
365
366 emit widgetChanged();
367}
368
369void QgsBarChartPlotWidget::mRemoveSymbolPushButton_clicked()
370{
371 QTableWidgetItem *item = mSymbolsList->currentItem();
372 if ( !item )
373 {
374 return;
375 }
376
377 mSymbolsList->removeRow( mSymbolsList->row( item ) );
378
379 emit widgetChanged();
380}
381
383{
384 QgsBarChartPlot *chartPlot = dynamic_cast<QgsBarChartPlot *>( plot );
385 if ( !chartPlot )
386 {
387 return;
388 }
389
390 mBlockChanges++;
391
392 mSymbolsList->clear();
393 const int symbolCount = chartPlot->fillSymbolCount();
394 for ( int i = 0; i < symbolCount; i++ )
395 {
396 const int row = mSymbolsList->rowCount();
397 mSymbolsList->insertRow( row );
398
399 QTableWidgetItem *item = new QTableWidgetItem();
400 item->setData( Qt::DisplayRole, tr( "Symbol" ) );
401 mSymbolsList->setItem( row, 0, item );
402
403 QgsSymbolButton *symbolButton = new QgsSymbolButton( this );
404 symbolButton->setSymbolType( Qgis::SymbolType::Fill );
405 symbolButton->setShowNull( true );
406 symbolButton->setSymbol( chartPlot->fillSymbolAt( i )->clone() );
407 symbolButton->registerExpressionContextGenerator( this );
408 connect( symbolButton, &QgsSymbolButton::changed, this, [this] {
409 if ( mBlockChanges )
410 return;
411 emit widgetChanged();
412 } );
413 mSymbolsList->setCellWidget( row, 1, symbolButton );
414 }
415
416 mSpinMinXAxis->setValue( chartPlot->xMinimum() );
417 mSpinMaxXAxis->setValue( chartPlot->xMaximum() );
418 mSpinMinYAxis->setValue( chartPlot->yMinimum() );
419 mSpinMaxYAxis->setValue( chartPlot->yMaximum() );
420
421 if ( chartPlot->xAxis().gridMajorSymbol() )
422 mXAxisMajorLinesSymbolButton->setSymbol( chartPlot->xAxis().gridMajorSymbol()->clone() );
423 if ( chartPlot->xAxis().gridMinorSymbol() )
424 mXAxisMinorLinesSymbolButton->setSymbol( chartPlot->xAxis().gridMinorSymbol()->clone() );
425 if ( chartPlot->yAxis().gridMajorSymbol() )
426 mYAxisMajorLinesSymbolButton->setSymbol( chartPlot->yAxis().gridMajorSymbol()->clone() );
427 if ( chartPlot->yAxis().gridMinorSymbol() )
428 mYAxisMinorLinesSymbolButton->setSymbol( chartPlot->yAxis().gridMinorSymbol()->clone() );
429
430 mXAxisLabelFontButton->setTextFormat( chartPlot->xAxis().textFormat() );
431 mXAxisNumericFormat.reset( chartPlot->xAxis().numericFormat()->clone() );
432 mYAxisLabelFontButton->setTextFormat( chartPlot->yAxis().textFormat() );
433 mYAxisNumericFormat.reset( chartPlot->yAxis().numericFormat()->clone() );
434
435 mXAxisTypeCombo->setCurrentIndex( mXAxisTypeCombo->findData( QVariant::fromValue( chartPlot->xAxis().type() ) ) );
436 mXAxisLabelsCombo->setCurrentIndex( mXAxisLabelsCombo->findData( QVariant::fromValue( chartPlot->xAxis().labelSuffixPlacement() ) ) );
437
438 mXAxisMajorIntervalSpin->setValue( chartPlot->xAxis().gridIntervalMajor() );
439 mXAxisMinorIntervalSpin->setValue( chartPlot->xAxis().gridIntervalMinor() );
440 mXAxisLabelIntervalSpin->setValue( chartPlot->xAxis().labelInterval() );
441
442 mYAxisMajorIntervalSpin->setValue( chartPlot->yAxis().gridIntervalMajor() );
443 mYAxisMinorIntervalSpin->setValue( chartPlot->yAxis().gridIntervalMinor() );
444 mYAxisLabelIntervalSpin->setValue( chartPlot->yAxis().labelInterval() );
445
446 if ( chartPlot->chartBackgroundSymbol() )
447 mChartBackgroundSymbolButton->setSymbol( chartPlot->chartBackgroundSymbol()->clone() );
448 if ( chartPlot->chartBorderSymbol() )
449 mChartBorderSymbolButton->setSymbol( chartPlot->chartBorderSymbol()->clone() );
450
451 mSpinLeftMargin->setValue( chartPlot->margins().left() );
452 mSpinRightMargin->setValue( chartPlot->margins().right() );
453 mSpinTopMargin->setValue( chartPlot->margins().top() );
454 mSpinBottomMargin->setValue( chartPlot->margins().bottom() );
455
456 mFlipAxes = chartPlot->flipAxes();
457
459
460 updateDataDefinedButton( mDDBtnMinXAxis );
461 updateDataDefinedButton( mDDBtnMaxXAxis );
462 updateDataDefinedButton( mDDBtnMinYAxis );
463 updateDataDefinedButton( mDDBtnMaxYAxis );
464
465 updateDataDefinedButton( mDDBtnXAxisMajorInterval );
466 updateDataDefinedButton( mDDBtnXAxisMinorInterval );
467 updateDataDefinedButton( mDDBtnXAxisLabelInterval );
468 updateDataDefinedButton( mDDBtnYAxisMajorInterval );
469 updateDataDefinedButton( mDDBtnYAxisMinorInterval );
470 updateDataDefinedButton( mDDBtnYAxisLabelInterval );
471
472 updateDataDefinedButton( mDDBtnLeftMargin );
473 updateDataDefinedButton( mDDBtnRightMargin );
474 updateDataDefinedButton( mDDBtnTopMargin );
475 updateDataDefinedButton( mDDBtnBottomMargin );
476
477 mBlockChanges--;
478}
479
480
482{
483 QgsPlot *plot = QgsApplication::plotRegistry()->createPlot( u"bar"_s );
484 QgsBarChartPlot *chartPlot = dynamic_cast<QgsBarChartPlot *>( plot );
485 if ( !chartPlot )
486 {
487 return nullptr;
488 }
489
490 const int rowCount = mSymbolsList->rowCount();
491 for ( int i = 0; i < rowCount; i++ )
492 {
493 QgsSymbolButton *symbolButton = dynamic_cast<QgsSymbolButton *>( mSymbolsList->cellWidget( i, 1 ) );
494 if ( symbolButton )
495 {
496 chartPlot->setFillSymbolAt( i, symbolButton->clonedSymbol<QgsFillSymbol>() );
497 }
498 }
499
500 chartPlot->setXMinimum( mSpinMinXAxis->value() );
501 chartPlot->setXMaximum( mSpinMaxXAxis->value() );
502 chartPlot->setYMinimum( mSpinMinYAxis->value() );
503 chartPlot->setYMaximum( mSpinMaxYAxis->value() );
504
505 chartPlot->xAxis().setGridMajorSymbol( mXAxisMajorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
506 chartPlot->xAxis().setGridMinorSymbol( mXAxisMinorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
507 chartPlot->yAxis().setGridMajorSymbol( mYAxisMajorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
508 chartPlot->yAxis().setGridMinorSymbol( mYAxisMinorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
509
510 chartPlot->xAxis().setTextFormat( mXAxisLabelFontButton->textFormat() );
511 chartPlot->xAxis().setNumericFormat( mXAxisNumericFormat.get()->clone() );
512 chartPlot->yAxis().setTextFormat( mYAxisLabelFontButton->textFormat() );
513 chartPlot->yAxis().setNumericFormat( mYAxisNumericFormat.get()->clone() );
514
515 chartPlot->xAxis().setType( mXAxisTypeCombo->currentData().value<Qgis::PlotAxisType>() );
516 chartPlot->xAxis().setLabelSuffixPlacement( mXAxisLabelsCombo->currentData().value<Qgis::PlotAxisSuffixPlacement>() );
517
518 chartPlot->xAxis().setGridIntervalMajor( mXAxisMajorIntervalSpin->value() );
519 chartPlot->xAxis().setGridIntervalMinor( mXAxisMinorIntervalSpin->value() );
520 chartPlot->xAxis().setLabelInterval( mXAxisLabelIntervalSpin->value() );
521
522 chartPlot->yAxis().setGridIntervalMajor( mYAxisMajorIntervalSpin->value() );
523 chartPlot->yAxis().setGridIntervalMinor( mYAxisMinorIntervalSpin->value() );
524 chartPlot->yAxis().setLabelInterval( mYAxisLabelIntervalSpin->value() );
525
526 chartPlot->setChartBackgroundSymbol( mChartBackgroundSymbolButton->clonedSymbol<QgsFillSymbol>() );
527 chartPlot->setChartBorderSymbol( mChartBorderSymbolButton->clonedSymbol<QgsFillSymbol>() );
528
529 QgsMargins margins;
530 margins.setLeft( mSpinLeftMargin->value() );
531 margins.setRight( mSpinRightMargin->value() );
532 margins.setTop( mSpinTopMargin->value() );
533 margins.setBottom( mSpinBottomMargin->value() );
534 chartPlot->setMargins( margins );
535
536 chartPlot->setFlipAxes( mFlipAxes );
538
539 return plot;
540}
541
542
544 : QgsPlotWidget( parent )
545{
546 setupUi( this );
547
548 setPanelTitle( tr( "Line Chart Plot Properties" ) );
549
550 mSymbolsList->setColumnCount( 3 );
551 mSymbolsList->setSelectionBehavior( QAbstractItemView::SelectRows );
552 mSymbolsList->setSelectionMode( QAbstractItemView::ExtendedSelection );
553 mSymbolsList->setSortingEnabled( false );
554 mSymbolsList->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::Stretch );
555 mSymbolsList->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Stretch );
556 mSymbolsList->horizontalHeader()->setSectionResizeMode( 2, QHeaderView::Stretch );
557 mSymbolsList->horizontalHeader()->hide();
558 mSymbolsList->verticalHeader()->hide();
559
560 connect( mAddSymbolPushButton, &QPushButton::clicked, this, &QgsLineChartPlotWidget::mAddSymbolPushButton_clicked );
561 connect( mRemoveSymbolPushButton, &QPushButton::clicked, this, &QgsLineChartPlotWidget::mRemoveSymbolPushButton_clicked );
562
563 mSpinMinXAxis->setClearValue( 0 );
564 connect( mSpinMinXAxis, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
565 if ( mBlockChanges )
566 return;
567 emit widgetChanged();
568 } );
569
570 connect( mSpinMaxXAxis, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
571 if ( mBlockChanges )
572 return;
573 emit widgetChanged();
574 } );
575
576 mSpinMinYAxis->setClearValue( 0 );
577 connect( mSpinMinYAxis, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
578 if ( mBlockChanges )
579 return;
580 emit widgetChanged();
581 } );
582
583 mSpinMaxYAxis->setClearValue( 0 );
584 connect( mSpinMaxYAxis, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
585 if ( mBlockChanges )
586 return;
587 emit widgetChanged();
588 } );
589
590 mXAxisMajorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
591 connect( mXAxisMajorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
592 if ( mBlockChanges )
593 return;
594 emit widgetChanged();
595 } );
596 mXAxisMajorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMajorSymbol() );
597
598 mXAxisMinorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
599 connect( mXAxisMinorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
600 if ( mBlockChanges )
601 return;
602 emit widgetChanged();
603 } );
604 mXAxisMinorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMinorSymbol() );
605
606 connect( mXAxisMajorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
607 if ( mBlockChanges )
608 return;
609 emit widgetChanged();
610 } );
611
612 connect( mXAxisMinorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
613 if ( mBlockChanges )
614 return;
615 emit widgetChanged();
616 } );
617
618 connect( mXAxisLabelIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
619 if ( mBlockChanges )
620 return;
621 emit widgetChanged();
622 } );
623
624 mYAxisMajorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
625 connect( mYAxisMajorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
626 if ( mBlockChanges )
627 return;
628 emit widgetChanged();
629 } );
630 mYAxisMajorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMajorSymbol() );
631
632 mYAxisMinorLinesSymbolButton->setSymbolType( Qgis::SymbolType::Line );
633 connect( mYAxisMinorLinesSymbolButton, &QgsSymbolButton::changed, this, [this] {
634 if ( mBlockChanges )
635 return;
636 emit widgetChanged();
637 } );
638 mYAxisMinorLinesSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::axisGridMinorSymbol() );
639
640 connect( mYAxisLabelIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
641 if ( mBlockChanges )
642 return;
643 emit widgetChanged();
644 } );
645
646 connect( mYAxisMajorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
647 if ( mBlockChanges )
648 return;
649 emit widgetChanged();
650 } );
651
652 connect( mYAxisMinorIntervalSpin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
653 if ( mBlockChanges )
654 return;
655 emit widgetChanged();
656 } );
657
658 mChartBackgroundSymbolButton->setSymbolType( Qgis::SymbolType::Fill );
659 connect( mChartBackgroundSymbolButton, &QgsSymbolButton::changed, this, [this] {
660 if ( mBlockChanges )
661 return;
662 emit widgetChanged();
663 } );
664 mChartBackgroundSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::chartBackgroundSymbol() );
665
666 mChartBorderSymbolButton->setSymbolType( Qgis::SymbolType::Fill );
667 connect( mChartBorderSymbolButton, &QgsSymbolButton::changed, this, [this] {
668 if ( mBlockChanges )
669 return;
670 emit widgetChanged();
671 } );
672 mChartBorderSymbolButton->setDefaultSymbol( QgsPlotDefaultSettings::chartBorderSymbol() );
673
674 connect( mXAxisLabelFormatButton, &QPushButton::clicked, this, [this] {
676 widget->setPanelTitle( tr( "X Axis Number Format" ) );
677 widget->setFormat( mXAxisNumericFormat.get() );
678 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [this, widget] {
679 mXAxisNumericFormat.reset( widget->format() );
680 emit widgetChanged();
681 } );
682 openPanel( widget );
683 } );
684
685 connect( mYAxisLabelFormatButton, &QPushButton::clicked, this, [this] {
687 widget->setPanelTitle( tr( "Y Axis Number Format" ) );
688 widget->setFormat( mYAxisNumericFormat.get() );
689 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [this, widget] {
690 mYAxisNumericFormat.reset( widget->format() );
691 emit widgetChanged();
692 } );
693 openPanel( widget );
694 } );
695
696 mXAxisLabelFontButton->setDialogTitle( tr( "X Axis Label Font" ) );
697 mYAxisLabelFontButton->setDialogTitle( tr( "Y Axis Label Font" ) );
698 mXAxisLabelFontButton->setMode( QgsFontButton::ModeTextRenderer );
699 mYAxisLabelFontButton->setMode( QgsFontButton::ModeTextRenderer );
700
701 connect( mXAxisLabelFontButton, &QgsFontButton::changed, this, [this] {
702 if ( mBlockChanges )
703 return;
704 emit widgetChanged();
705 } );
706
707 connect( mYAxisLabelFontButton, &QgsFontButton::changed, this, [this] {
708 if ( mBlockChanges )
709 return;
710 emit widgetChanged();
711 } );
712
713 mSpinLeftMargin->setClearValue( 0 );
714 connect( mSpinLeftMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
715 if ( mBlockChanges )
716 return;
717 emit widgetChanged();
718 } );
719
720 mSpinRightMargin->setClearValue( 0 );
721 connect( mSpinRightMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
722 if ( mBlockChanges )
723 return;
724 emit widgetChanged();
725 } );
726
727 mSpinTopMargin->setClearValue( 0 );
728 connect( mSpinTopMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
729 if ( mBlockChanges )
730 return;
731 emit widgetChanged();
732 } );
733
734 mSpinBottomMargin->setClearValue( 0 );
735 connect( mSpinBottomMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
736 if ( mBlockChanges )
737 return;
738 emit widgetChanged();
739 } );
740
741 mXAxisTypeCombo->addItem( tr( "Interval" ), QVariant::fromValue( Qgis::PlotAxisType::Interval ) );
742 mXAxisTypeCombo->addItem( tr( "Categorical" ), QVariant::fromValue( Qgis::PlotAxisType::Categorical ) );
743 connect( mXAxisTypeCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
744 if ( mBlockChanges )
745 return;
746 emit widgetChanged();
747 } );
748
749 mXAxisLabelsCombo->addItem( tr( "None" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::NoLabels ) );
750 mXAxisLabelsCombo->addItem( tr( "Every Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::EveryLabel ) );
751 mXAxisLabelsCombo->addItem( tr( "First Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::FirstLabel ) );
752 mXAxisLabelsCombo->addItem( tr( "Last Value" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::LastLabel ) );
753 mXAxisLabelsCombo->addItem( tr( "First and Last Values" ), QVariant::fromValue( Qgis::PlotAxisSuffixPlacement::FirstAndLastLabels ) );
754 connect( mXAxisLabelsCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
755 if ( mBlockChanges )
756 return;
757 emit widgetChanged();
758 } );
759
760 mXAxisMajorLinesSymbolButton->registerExpressionContextGenerator( this );
761 mXAxisMinorLinesSymbolButton->registerExpressionContextGenerator( this );
762 mXAxisLabelFontButton->registerExpressionContextGenerator( this );
763 mYAxisMajorLinesSymbolButton->registerExpressionContextGenerator( this );
764 mYAxisMinorLinesSymbolButton->registerExpressionContextGenerator( this );
765 mYAxisLabelFontButton->registerExpressionContextGenerator( this );
766 mChartBackgroundSymbolButton->registerExpressionContextGenerator( this );
767 mChartBorderSymbolButton->registerExpressionContextGenerator( this );
768
773
780
785}
786
787void QgsLineChartPlotWidget::mAddSymbolPushButton_clicked()
788{
789 const int row = mSymbolsList->rowCount();
790 mSymbolsList->insertRow( row );
791
792 QTableWidgetItem *item = new QTableWidgetItem();
793 item->setData( Qt::DisplayRole, tr( "Symbol" ) );
794 mSymbolsList->setItem( row, 0, item );
795
796 // Line
797 QgsSymbolButton *symbolButton = new QgsSymbolButton( this );
798 symbolButton->setSymbolType( Qgis::SymbolType::Line );
799 symbolButton->setShowNull( true );
801 symbolButton->registerExpressionContextGenerator( this );
802 connect( symbolButton, &QgsSymbolButton::changed, this, [this] {
803 if ( mBlockChanges )
804 return;
805 emit widgetChanged();
806 } );
807 mSymbolsList->setCellWidget( row, 1, symbolButton );
808
809 // Marker
810 symbolButton = new QgsSymbolButton( this );
811 symbolButton->setFixedSizeConstraints( false );
813 symbolButton->setShowNull( true );
815 symbolButton->registerExpressionContextGenerator( this );
816 connect( symbolButton, &QgsSymbolButton::changed, this, [this] {
817 if ( mBlockChanges )
818 return;
819 emit widgetChanged();
820 } );
821 mSymbolsList->setCellWidget( row, 2, symbolButton );
822
823 emit widgetChanged();
824}
825
826void QgsLineChartPlotWidget::mRemoveSymbolPushButton_clicked()
827{
828 QTableWidgetItem *item = mSymbolsList->currentItem();
829 if ( !item )
830 {
831 return;
832 }
833
834 mSymbolsList->removeRow( mSymbolsList->row( item ) );
835
836 emit widgetChanged();
837}
838
840{
841 QgsLineChartPlot *chartPlot = dynamic_cast<QgsLineChartPlot *>( plot );
842 if ( !chartPlot )
843 {
844 return;
845 }
846
847 mBlockChanges++;
848
849 mSymbolsList->clear();
850 const int symbolCount = std::max( chartPlot->markerSymbolCount(), chartPlot->lineSymbolCount() );
851 for ( int i = 0; i < symbolCount; i++ )
852 {
853 const int row = mSymbolsList->rowCount();
854 mSymbolsList->insertRow( row );
855
856 QTableWidgetItem *item = new QTableWidgetItem();
857 item->setData( Qt::DisplayRole, tr( "Symbol" ) );
858 mSymbolsList->setItem( row, 0, item );
859
860 // Line
861 QgsSymbolButton *symbolButton = new QgsSymbolButton( this );
862 symbolButton->setSymbolType( Qgis::SymbolType::Line );
863 symbolButton->setShowNull( true );
864 symbolButton->setSymbol( i < chartPlot->lineSymbolCount() ? chartPlot->lineSymbolAt( i )->clone() : nullptr );
865 symbolButton->registerExpressionContextGenerator( this );
866 connect( symbolButton, &QgsSymbolButton::changed, this, [this] {
867 if ( mBlockChanges )
868 return;
869 emit widgetChanged();
870 } );
871 mSymbolsList->setCellWidget( row, 1, symbolButton );
872
873 // Marker
874 symbolButton = new QgsSymbolButton( this );
875 symbolButton->setFixedSizeConstraints( false );
877 symbolButton->setShowNull( true );
878 symbolButton->setSymbol( i < chartPlot->markerSymbolCount() ? chartPlot->markerSymbolAt( i )->clone() : nullptr );
879 symbolButton->registerExpressionContextGenerator( this );
880 connect( symbolButton, &QgsSymbolButton::changed, this, [this] {
881 if ( mBlockChanges )
882 return;
883 emit widgetChanged();
884 } );
885 mSymbolsList->setCellWidget( row, 2, symbolButton );
886 }
887
888 mSpinMinXAxis->setValue( chartPlot->xMinimum() );
889 mSpinMaxXAxis->setValue( chartPlot->xMaximum() );
890 mSpinMinYAxis->setValue( chartPlot->yMinimum() );
891 mSpinMaxYAxis->setValue( chartPlot->yMaximum() );
892
893 if ( chartPlot->xAxis().gridMajorSymbol() )
894 mXAxisMajorLinesSymbolButton->setSymbol( chartPlot->xAxis().gridMajorSymbol()->clone() );
895 if ( chartPlot->xAxis().gridMinorSymbol() )
896 mXAxisMinorLinesSymbolButton->setSymbol( chartPlot->xAxis().gridMinorSymbol()->clone() );
897 if ( chartPlot->yAxis().gridMajorSymbol() )
898 mYAxisMajorLinesSymbolButton->setSymbol( chartPlot->yAxis().gridMajorSymbol()->clone() );
899 if ( chartPlot->yAxis().gridMinorSymbol() )
900 mYAxisMinorLinesSymbolButton->setSymbol( chartPlot->yAxis().gridMinorSymbol()->clone() );
901
902 mXAxisLabelFontButton->setTextFormat( chartPlot->xAxis().textFormat() );
903 mYAxisLabelFontButton->setTextFormat( chartPlot->yAxis().textFormat() );
904
905 mXAxisTypeCombo->setCurrentIndex( mXAxisTypeCombo->findData( QVariant::fromValue( chartPlot->xAxis().type() ) ) );
906 mXAxisLabelsCombo->setCurrentIndex( mXAxisLabelsCombo->findData( QVariant::fromValue( chartPlot->xAxis().labelSuffixPlacement() ) ) );
907
908 mXAxisMajorIntervalSpin->setValue( chartPlot->xAxis().gridIntervalMajor() );
909 mXAxisMinorIntervalSpin->setValue( chartPlot->xAxis().gridIntervalMinor() );
910 mXAxisLabelIntervalSpin->setValue( chartPlot->xAxis().labelInterval() );
911
912 mYAxisMajorIntervalSpin->setValue( chartPlot->yAxis().gridIntervalMajor() );
913 mYAxisMinorIntervalSpin->setValue( chartPlot->yAxis().gridIntervalMinor() );
914 mYAxisLabelIntervalSpin->setValue( chartPlot->yAxis().labelInterval() );
915
916 if ( chartPlot->chartBackgroundSymbol() )
917 mChartBackgroundSymbolButton->setSymbol( chartPlot->chartBackgroundSymbol()->clone() );
918 if ( chartPlot->chartBorderSymbol() )
919 mChartBorderSymbolButton->setSymbol( chartPlot->chartBorderSymbol()->clone() );
920
921 mSpinLeftMargin->setValue( chartPlot->margins().left() );
922 mSpinRightMargin->setValue( chartPlot->margins().right() );
923 mSpinTopMargin->setValue( chartPlot->margins().top() );
924 mSpinBottomMargin->setValue( chartPlot->margins().bottom() );
925
926 mFlipAxes = chartPlot->flipAxes();
927
929
930 updateDataDefinedButton( mDDBtnMinXAxis );
931 updateDataDefinedButton( mDDBtnMaxXAxis );
932 updateDataDefinedButton( mDDBtnMinYAxis );
933 updateDataDefinedButton( mDDBtnMaxYAxis );
934
935 updateDataDefinedButton( mDDBtnXAxisMajorInterval );
936 updateDataDefinedButton( mDDBtnXAxisMinorInterval );
937 updateDataDefinedButton( mDDBtnXAxisLabelInterval );
938 updateDataDefinedButton( mDDBtnYAxisMajorInterval );
939 updateDataDefinedButton( mDDBtnYAxisMinorInterval );
940 updateDataDefinedButton( mDDBtnYAxisLabelInterval );
941
942 updateDataDefinedButton( mDDBtnLeftMargin );
943 updateDataDefinedButton( mDDBtnRightMargin );
944 updateDataDefinedButton( mDDBtnTopMargin );
945 updateDataDefinedButton( mDDBtnBottomMargin );
946
947 mBlockChanges--;
948}
949
950
952{
953 QgsPlot *plot = QgsApplication::plotRegistry()->createPlot( u"line"_s );
954 QgsLineChartPlot *chartPlot = dynamic_cast<QgsLineChartPlot *>( plot );
955 if ( !chartPlot )
956 {
957 return nullptr;
958 }
959
960 const int rowCount = mSymbolsList->rowCount();
961 for ( int i = 0; i < rowCount; i++ )
962 {
963 QgsSymbolButton *symbolButton = dynamic_cast<QgsSymbolButton *>( mSymbolsList->cellWidget( i, 1 ) );
964 if ( symbolButton )
965 {
966 chartPlot->setLineSymbolAt( i, symbolButton->clonedSymbol<QgsLineSymbol>() );
967 }
968
969 symbolButton = dynamic_cast<QgsSymbolButton *>( mSymbolsList->cellWidget( i, 2 ) );
970 if ( symbolButton )
971 {
972 chartPlot->setMarkerSymbolAt( i, symbolButton->clonedSymbol<QgsMarkerSymbol>() );
973 }
974 }
975
976 chartPlot->setXMinimum( mSpinMinXAxis->value() );
977 chartPlot->setXMaximum( mSpinMaxXAxis->value() );
978 chartPlot->setYMinimum( mSpinMinYAxis->value() );
979 chartPlot->setYMaximum( mSpinMaxYAxis->value() );
980
981 chartPlot->xAxis().setGridMajorSymbol( mXAxisMajorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
982 chartPlot->xAxis().setGridMinorSymbol( mXAxisMinorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
983 chartPlot->yAxis().setGridMajorSymbol( mYAxisMajorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
984 chartPlot->yAxis().setGridMinorSymbol( mYAxisMinorLinesSymbolButton->clonedSymbol<QgsLineSymbol>() );
985
986 chartPlot->xAxis().setTextFormat( mXAxisLabelFontButton->textFormat() );
987 chartPlot->yAxis().setTextFormat( mYAxisLabelFontButton->textFormat() );
988
989 chartPlot->xAxis().setType( mXAxisTypeCombo->currentData().value<Qgis::PlotAxisType>() );
990 chartPlot->xAxis().setLabelSuffixPlacement( mXAxisLabelsCombo->currentData().value<Qgis::PlotAxisSuffixPlacement>() );
991
992 chartPlot->xAxis().setGridIntervalMajor( mXAxisMajorIntervalSpin->value() );
993 chartPlot->xAxis().setGridIntervalMinor( mXAxisMinorIntervalSpin->value() );
994 chartPlot->xAxis().setLabelInterval( mXAxisLabelIntervalSpin->value() );
995
996 chartPlot->yAxis().setGridIntervalMajor( mYAxisMajorIntervalSpin->value() );
997 chartPlot->yAxis().setGridIntervalMinor( mYAxisMinorIntervalSpin->value() );
998 chartPlot->yAxis().setLabelInterval( mYAxisLabelIntervalSpin->value() );
999
1000 chartPlot->setChartBackgroundSymbol( mChartBackgroundSymbolButton->clonedSymbol<QgsFillSymbol>() );
1001 chartPlot->setChartBorderSymbol( mChartBorderSymbolButton->clonedSymbol<QgsFillSymbol>() );
1002
1003 QgsMargins margins;
1004 margins.setLeft( mSpinLeftMargin->value() );
1005 margins.setRight( mSpinRightMargin->value() );
1006 margins.setTop( mSpinTopMargin->value() );
1007 margins.setBottom( mSpinBottomMargin->value() );
1008 chartPlot->setMargins( margins );
1009
1010 chartPlot->setFlipAxes( mFlipAxes );
1012
1013 return plot;
1014}
1015
1016
1018 : QgsPlotWidget( parent )
1019{
1020 setupUi( this );
1021
1022 setPanelTitle( tr( "Pie Chart Plot Properties" ) );
1023
1024 mSymbolsList->setColumnCount( 3 );
1025 mSymbolsList->setSelectionBehavior( QAbstractItemView::SelectRows );
1026 mSymbolsList->setSelectionMode( QAbstractItemView::ExtendedSelection );
1027 mSymbolsList->setSortingEnabled( false );
1028 mSymbolsList->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::Stretch );
1029 mSymbolsList->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Stretch );
1030 mSymbolsList->horizontalHeader()->setSectionResizeMode( 2, QHeaderView::Stretch );
1031 mSymbolsList->horizontalHeader()->hide();
1032 mSymbolsList->verticalHeader()->hide();
1033
1034 mLabelCombo->addItem( tr( "None" ), QVariant::fromValue( Qgis::PieChartLabelType::NoLabels ) );
1035 mLabelCombo->addItem( tr( "Category Labels" ), QVariant::fromValue( Qgis::PieChartLabelType::Categories ) );
1036 mLabelCombo->addItem( tr( "Value Labels" ), QVariant::fromValue( Qgis::PieChartLabelType::Values ) );
1037 connect( mLabelCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
1038 if ( mBlockChanges )
1039 return;
1040 emit widgetChanged();
1041 } );
1042
1043 mLabelFontButton->setDialogTitle( tr( "Chart Label Font" ) );
1044 mLabelFontButton->setMode( QgsFontButton::ModeTextRenderer );
1045 connect( mLabelFontButton, &QgsFontButton::changed, this, [this] {
1046 if ( mBlockChanges )
1047 return;
1048 emit widgetChanged();
1049 } );
1050
1051 connect( mLabelFormatButton, &QPushButton::clicked, this, [this] {
1053 widget->setPanelTitle( tr( "Chart Number Format" ) );
1054 widget->setFormat( mNumericFormat.get() );
1055 connect( widget, &QgsNumericFormatSelectorWidget::changed, this, [this, widget] {
1056 mNumericFormat.reset( widget->format() );
1057 emit widgetChanged();
1058 } );
1059 openPanel( widget );
1060 } );
1061
1062 mSpinLeftMargin->setClearValue( 0 );
1063 connect( mSpinLeftMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
1064 if ( mBlockChanges )
1065 return;
1066 emit widgetChanged();
1067 } );
1068
1069 mSpinRightMargin->setClearValue( 0 );
1070 connect( mSpinRightMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
1071 if ( mBlockChanges )
1072 return;
1073 emit widgetChanged();
1074 } );
1075
1076 mSpinTopMargin->setClearValue( 0 );
1077 connect( mSpinTopMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
1078 if ( mBlockChanges )
1079 return;
1080 emit widgetChanged();
1081 } );
1082
1083 mSpinBottomMargin->setClearValue( 0 );
1084 connect( mSpinBottomMargin, qOverload<double>( &QDoubleSpinBox::valueChanged ), this, [this]( double ) {
1085 if ( mBlockChanges )
1086 return;
1087 emit widgetChanged();
1088 } );
1089
1090 connect( mAddSymbolPushButton, &QPushButton::clicked, this, &QgsPieChartPlotWidget::mAddSymbolPushButton_clicked );
1091 connect( mRemoveSymbolPushButton, &QPushButton::clicked, this, &QgsPieChartPlotWidget::mRemoveSymbolPushButton_clicked );
1092
1093 mLabelFontButton->registerExpressionContextGenerator( this );
1094
1099}
1100
1101void QgsPieChartPlotWidget::mAddSymbolPushButton_clicked()
1102{
1103 const int row = mSymbolsList->rowCount();
1104 mSymbolsList->insertRow( row );
1105
1106 QTableWidgetItem *item = new QTableWidgetItem();
1107 item->setData( Qt::DisplayRole, tr( "Symbol" ) );
1108 mSymbolsList->setItem( row, 0, item );
1109
1110 // Fill
1111 QgsSymbolButton *symbolButton = new QgsSymbolButton( this );
1112 symbolButton->setSymbolType( Qgis::SymbolType::Fill );
1113 symbolButton->setShowNull( true );
1115 symbolButton->registerExpressionContextGenerator( this );
1116 connect( symbolButton, &QgsSymbolButton::changed, this, [this] {
1117 if ( mBlockChanges )
1118 return;
1119 emit widgetChanged();
1120 } );
1121 mSymbolsList->setCellWidget( row, 1, symbolButton );
1122
1123 // Color ramp
1124 QgsColorRampButton *colorRampButton = new QgsColorRampButton( this );
1125 colorRampButton->setShowNull( true );
1127 connect( colorRampButton, &QgsColorRampButton::colorRampChanged, this, [this] {
1128 if ( mBlockChanges )
1129 return;
1130 emit widgetChanged();
1131 } );
1132 mSymbolsList->setCellWidget( row, 2, colorRampButton );
1133
1134 emit widgetChanged();
1135}
1136
1137void QgsPieChartPlotWidget::mRemoveSymbolPushButton_clicked()
1138{
1139 QTableWidgetItem *item = mSymbolsList->currentItem();
1140 if ( !item )
1141 {
1142 return;
1143 }
1144
1145 mSymbolsList->removeRow( mSymbolsList->row( item ) );
1146
1147 emit widgetChanged();
1148}
1149
1151{
1152 QgsPieChartPlot *chartPlot = dynamic_cast<QgsPieChartPlot *>( plot );
1153 if ( !chartPlot )
1154 {
1155 return;
1156 }
1157
1158 mBlockChanges++;
1159
1160 mSymbolsList->clear();
1161 const int symbolCount = std::max( chartPlot->fillSymbolCount(), chartPlot->colorRampCount() );
1162 for ( int i = 0; i < symbolCount; i++ )
1163 {
1164 const int row = mSymbolsList->rowCount();
1165 mSymbolsList->insertRow( row );
1166
1167 QTableWidgetItem *item = new QTableWidgetItem();
1168 item->setData( Qt::DisplayRole, tr( "Symbol" ) );
1169 mSymbolsList->setItem( row, 0, item );
1170
1171 // Fill
1172 QgsSymbolButton *symbolButton = new QgsSymbolButton( this );
1173 symbolButton->setSymbolType( Qgis::SymbolType::Fill );
1174 symbolButton->setShowNull( true );
1175 symbolButton->setSymbol( i < chartPlot->fillSymbolCount() ? chartPlot->fillSymbolAt( i )->clone() : nullptr );
1176 symbolButton->registerExpressionContextGenerator( this );
1177 connect( symbolButton, &QgsSymbolButton::changed, this, [this] {
1178 if ( mBlockChanges )
1179 return;
1180 emit widgetChanged();
1181 } );
1182 mSymbolsList->setCellWidget( row, 1, symbolButton );
1183
1184 // Color ramp
1185 QgsColorRampButton *colorRampButton = new QgsColorRampButton( this );
1186 colorRampButton->setShowNull( true );
1187 colorRampButton->setColorRamp( i < chartPlot->colorRampCount() ? chartPlot->colorRampAt( i )->clone() : nullptr );
1188 connect( colorRampButton, &QgsColorRampButton::colorRampChanged, this, [this] {
1189 if ( mBlockChanges )
1190 return;
1191 emit widgetChanged();
1192 } );
1193 mSymbolsList->setCellWidget( row, 2, colorRampButton );
1194 }
1195
1196 mNumericFormat.reset( chartPlot->numericFormat()->clone() );
1197 mLabelFontButton->setTextFormat( chartPlot->textFormat() );
1198
1199 mLabelCombo->setCurrentIndex( mLabelCombo->findData( QVariant::fromValue( chartPlot->labelType() ) ) );
1200
1202
1203 updateDataDefinedButton( mDDBtnLeftMargin );
1204 updateDataDefinedButton( mDDBtnRightMargin );
1205 updateDataDefinedButton( mDDBtnTopMargin );
1206 updateDataDefinedButton( mDDBtnBottomMargin );
1207
1208 mBlockChanges--;
1209}
1210
1212{
1213 QgsPlot *plot = QgsApplication::plotRegistry()->createPlot( u"pie"_s );
1214 QgsPieChartPlot *chartPlot = dynamic_cast<QgsPieChartPlot *>( plot );
1215 if ( !chartPlot )
1216 {
1217 return nullptr;
1218 }
1219
1220 const int rowCount = mSymbolsList->rowCount();
1221 for ( int i = 0; i < rowCount; i++ )
1222 {
1223 QgsSymbolButton *symbolButton = dynamic_cast<QgsSymbolButton *>( mSymbolsList->cellWidget( i, 1 ) );
1224 if ( symbolButton )
1225 {
1226 chartPlot->setFillSymbolAt( i, symbolButton->clonedSymbol<QgsFillSymbol>() );
1227 }
1228
1229 QgsColorRampButton *colorRampButton = dynamic_cast<QgsColorRampButton *>( mSymbolsList->cellWidget( i, 2 ) );
1230 if ( colorRampButton )
1231 {
1232 chartPlot->setColorRampAt( i, colorRampButton->colorRamp()->clone() );
1233 }
1234 }
1235
1236 chartPlot->setNumericFormat( mNumericFormat.get()->clone() );
1237 chartPlot->setTextFormat( mLabelFontButton->textFormat() );
1238 chartPlot->setLabelType( mLabelCombo->currentData().value<Qgis::PieChartLabelType>() );
1239
1240 QgsMargins margins;
1241 margins.setLeft( mSpinLeftMargin->value() );
1242 margins.setRight( mSpinRightMargin->value() );
1243 margins.setTop( mSpinTopMargin->value() );
1244 margins.setBottom( mSpinBottomMargin->value() );
1245 chartPlot->setMargins( margins );
1246
1248
1249 return plot;
1250}
PieChartLabelType
Pie chart label types.
Definition qgis.h:3432
@ Categories
Category labels are drawn.
Definition qgis.h:3434
@ Values
Value labels are drawn.
Definition qgis.h:3435
@ NoLabels
Labels are not drawn.
Definition qgis.h:3433
PlotAxisSuffixPlacement
Placement options for suffixes in the labels for axis of plots.
Definition qgis.h:3404
@ FirstAndLastLabels
Place suffix after the first and last label values only.
Definition qgis.h:3409
@ EveryLabel
Place suffix after every value label.
Definition qgis.h:3406
@ FirstLabel
Place suffix after the first label value only.
Definition qgis.h:3407
@ LastLabel
Place suffix after the last label value only.
Definition qgis.h:3408
@ NoLabels
Do not place suffixes.
Definition qgis.h:3405
PlotAxisType
Plots axis types.
Definition qgis.h:3420
@ Categorical
The axis represents categories.
Definition qgis.h:3422
@ Interval
The axis represents a range of values.
Definition qgis.h:3421
@ Marker
Marker symbol.
Definition qgis.h:632
@ Line
Line symbol.
Definition qgis.h:633
@ Fill
Fill symbol.
Definition qgis.h:634
const QgsMargins & margins() const
Returns the margins of the plot area (in millimeters).
Definition qgsplot.cpp:296
void setMargins(const QgsMargins &margins)
Sets the margins of the plot area (in millimeters).
Definition qgsplot.cpp:301
void setXMaximum(double maximum)
Sets the maximum value of the x axis.
Definition qgsplot.h:737
double yMaximum() const
Returns the maximum value of the y axis.
Definition qgsplot.h:744
void setYMinimum(double minimum)
Sets the minimum value of the y axis.
Definition qgsplot.h:723
double xMinimum() const
Returns the minimum value of the x axis.
Definition qgsplot.h:702
void setChartBackgroundSymbol(QgsFillSymbol *symbol)
Sets the fill symbol used to render the background of the chart.
Definition qgsplot.cpp:1113
void setFlipAxes(bool flipAxes)
Sets whether the X and Y axes are flipped.
Definition qgsplot.cpp:1128
QgsPlotAxis & yAxis()
Returns a reference to the plot's y axis.
Definition qgsplot.h:772
void setChartBorderSymbol(QgsFillSymbol *symbol)
Sets the symbol used to render the border of the chart.
Definition qgsplot.cpp:1123
bool flipAxes() const
Returns whether the X and Y axes are flipped.
Definition qgsplot.h:816
QgsFillSymbol * chartBackgroundSymbol()
Returns the fill symbol used to render the background of the chart.
Definition qgsplot.cpp:1108
void setXMinimum(double minimum)
Sets the minimum value of the x axis.
Definition qgsplot.h:709
QgsPlotAxis & xAxis()
Returns a reference to the plot's x axis.
Definition qgsplot.h:758
QgsFillSymbol * chartBorderSymbol()
Returns the symbol used to render the border of the chart.
Definition qgsplot.cpp:1118
double yMinimum() const
Returns the minimum value of the y axis.
Definition qgsplot.h:716
void setYMaximum(double maximum)
Sets the maximum value of the y axis.
Definition qgsplot.h:751
double xMaximum() const
Returns the maximum value of the x axis.
Definition qgsplot.h:730
static QgsPlotRegistry * plotRegistry()
Returns the application's plot registry, used for plot types.
void setPlot(QgsPlot *plot) override
Sets the widget to match the settings of the plot.
QgsBarChartPlotWidget(QWidget *parent=nullptr)
Constructor for QgsBarChartPlotWidget.
QgsPlot * createPlot() override
Creates a plot defined by the current settings in the widget.
A simple bar chart class.
void setFillSymbolAt(int index, QgsFillSymbol *symbol)
Sets the fill symbol to use for the series with matching index.
int fillSymbolCount() const
Returns the fill symbols list count.
QgsFillSymbol * fillSymbolAt(int index) const
Returns the fill symbol for the series with matching index.
A cross platform button subclass for selecting color ramps.
void setColorRamp(QgsColorRamp *colorramp)
Sets the current color ramp for the button.
QgsColorRamp * colorRamp() const
Returns a copy of the current color ramp.
void setShowNull(bool showNull)
Sets whether a set to null (clear) option is shown in the button's drop-down menu.
void colorRampChanged()
Emitted whenever a new color ramp is set for the button.
virtual QgsColorRamp * clone() const =0
Creates a clone of the color ramp.
Abstract interface for generating an expression context.
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.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
QgsFillSymbol * clone() const override
Returns a deep copy of this symbol.
@ ModeTextRenderer
Configure font settings for use with QgsTextRenderer.
void changed()
Emitted when the widget's text format settings are changed.
QgsLineChartPlotWidget(QWidget *parent=nullptr)
Constructor for QgsLineChartPlotWidget.
void setPlot(QgsPlot *plot) override
Sets the widget to match the settings of the plot.
QgsPlot * createPlot() override
Creates a plot defined by the current settings in the widget.
A simple line chart class.
QgsMarkerSymbol * markerSymbolAt(int index) const
Returns the marker symbol for the series with matching index.
QgsLineSymbol * lineSymbolAt(int index) const
Returns the line symbol for the series with matching index.
void setLineSymbolAt(int index, QgsLineSymbol *symbol)
Sets the line symbol to use for the series with matching index.
int lineSymbolCount() const
Returns the line symbols list count.
void setMarkerSymbolAt(int index, QgsMarkerSymbol *symbol)
Sets the fill symbol to use for the series with matching index.
int markerSymbolCount() const
Returns the line symbols list count.
A line symbol type, for rendering LineString and MultiLineString geometries.
QgsLineSymbol * clone() const override
Returns a deep copy of this symbol.
Defines the four margins of a rectangle.
Definition qgsmargins.h:40
void setBottom(double bottom)
Sets the bottom margin to bottom.
Definition qgsmargins.h:116
double top() const
Returns the top margin.
Definition qgsmargins.h:80
void setLeft(double left)
Sets the left margin to left.
Definition qgsmargins.h:98
double right() const
Returns the right margin.
Definition qgsmargins.h:86
double bottom() const
Returns the bottom margin.
Definition qgsmargins.h:92
void setRight(double right)
Sets the right margin to right.
Definition qgsmargins.h:110
void setTop(double top)
Sets the top margin to top.
Definition qgsmargins.h:104
double left() const
Returns the left margin.
Definition qgsmargins.h:74
A marker symbol type, for rendering Point and MultiPoint geometries.
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
A widget which allows choice of numeric formats and the properties of them.
QgsNumericFormat * format() const
Returns a new format object representing the settings currently configured in the widget.
void changed()
Emitted whenever the format configured55 in the widget is changed.
void setFormat(const QgsNumericFormat *format)
Sets the format to show in the widget.
virtual QgsNumericFormat * clone() const =0
Clones the format, returning a new object.
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.
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
QgsPlot * createPlot() override
Creates a plot defined by the current settings in the widget.
void setPlot(QgsPlot *plot) override
Sets the widget to match the settings of the plot.
QgsPieChartPlotWidget(QWidget *parent=nullptr)
Constructor for QgsLineChartPlotWidget.
A simple pie chart class.
void setTextFormat(const QgsTextFormat &format)
Sets the text format used for the pie chart labels.
QgsTextFormat textFormat() const
Returns the text format used for the pie chart labels.
QgsFillSymbol * fillSymbolAt(int index) const
Returns the fill symbol for the series with matching index.
void setNumericFormat(QgsNumericFormat *format)
Sets the numeric format used for the pie chart labels.
QgsColorRamp * colorRampAt(int index) const
Returns the color ramp for the series with matching index.
QgsNumericFormat * numericFormat() const
Returns the numeric format used for the pie chart labels.
void setLabelType(Qgis::PieChartLabelType type)
Sets the pie chart label type.
Qgis::PieChartLabelType labelType() const
Returns the pie chart label type.
int fillSymbolCount() const
Returns the fill symbols list count.
void setColorRampAt(int index, QgsColorRamp *ramp)
Sets the color ramp for the series with matching index.
void setFillSymbolAt(int index, QgsFillSymbol *symbol)
Sets the fill symbol to use for the series with matching index.
int colorRampCount() const
Returns the color ramps list count.
QgsLineSymbol * gridMinorSymbol()
Returns the line symbol used to render the minor lines in the axis grid.
Definition qgsplot.cpp:208
void setGridMajorSymbol(QgsLineSymbol *symbol)
Sets the symbol used to render the major lines in the axis grid.
Definition qgsplot.cpp:203
double gridIntervalMinor() const
Returns the interval of minor grid lines for the axis.
Definition qgsplot.h:389
double gridIntervalMajor() const
Returns the interval of major grid lines for the axis.
Definition qgsplot.h:403
void setType(Qgis::PlotAxisType type)
Sets the axis type.
Definition qgsplot.cpp:112
void setNumericFormat(QgsNumericFormat *format)
Sets the numeric format used for the axis labels.
Definition qgsplot.cpp:173
QgsTextFormat textFormat() const
Returns the text format used for the axis labels.
Definition qgsplot.cpp:218
void setGridIntervalMajor(double interval)
Sets the interval of major grid lines for the axis.
Definition qgsplot.h:410
void setLabelSuffixPlacement(Qgis::PlotAxisSuffixPlacement placement)
Sets the placement for the axis label suffixes.
Definition qgsplot.cpp:193
void setGridIntervalMinor(double interval)
Sets the interval of minor grid lines for the axis.
Definition qgsplot.h:396
void setLabelInterval(double interval)
Sets the interval of labels for the axis.
Definition qgsplot.h:424
Qgis::PlotAxisType type() const
Returns the axis type.
Definition qgsplot.cpp:107
double labelInterval() const
Returns the interval of labels for the axis.
Definition qgsplot.h:417
QgsLineSymbol * gridMajorSymbol()
Returns the line symbol used to render the major lines in the axis grid.
Definition qgsplot.cpp:198
void setTextFormat(const QgsTextFormat &format)
Sets the text format used for the axis labels.
Definition qgsplot.cpp:223
void setGridMinorSymbol(QgsLineSymbol *symbol)
Sets the symbol used to render the minor lines in the axis grid.
Definition qgsplot.cpp:213
QgsNumericFormat * numericFormat() const
Returns the numeric format used for the axis labels.
Definition qgsplot.cpp:168
Qgis::PlotAxisSuffixPlacement labelSuffixPlacement() const
Returns the placement for the axis label suffixes.
Definition qgsplot.cpp:188
static QgsFillSymbol * chartBorderSymbol()
Returns the default fill symbol to use for the chart area border.
Definition qgsplot.cpp:1271
static QgsColorRamp * pieChartColorRamp()
Returns the default color ramp to use for pie charts.
Definition qgsplot.cpp:1301
static QgsFillSymbol * barChartFillSymbol()
Returns the default fill symbol to use for bar charts.
Definition qgsplot.cpp:1289
static QgsLineSymbol * lineChartLineSymbol()
Returns the default line symbol to use for line charts.
Definition qgsplot.cpp:1283
static QgsLineSymbol * axisGridMinorSymbol()
Returns the default line symbol to use for axis minor grid lines.
Definition qgsplot.cpp:1258
static QgsFillSymbol * pieChartFillSymbol()
Returns the default fill symbol to use for pie charts.
Definition qgsplot.cpp:1295
static QgsMarkerSymbol * lineChartMarkerSymbol()
Returns the default marker symbol to use for line charts.
Definition qgsplot.cpp:1277
static QgsFillSymbol * chartBackgroundSymbol()
Returns the default fill symbol to use for the chart area background fill.
Definition qgsplot.cpp:1265
static QgsLineSymbol * axisGridMajorSymbol()
Returns the default line symbol to use for axis major grid lines.
Definition qgsplot.cpp:1251
QgsPlot * createPlot(const QString &type) const
Creates a new instance of a plot given the type.
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
QgsPropertyCollection mPropertyCollection
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
void updateDataDefinedButton(QgsPropertyOverrideButton *button)
Initiate a data-defined property button tied to a plot widget.
QgsPlotWidget(QWidget *parent=nullptr)
Constructor for QgsPlotWidget.
void initializeDataDefinedButton(QgsPropertyOverrideButton *button, QgsPlot::DataDefinedProperty key)
Initiate a data-defined property button tied to a plot widget.
Base class for plot/chart/graphs.
Definition qgsplot.h:48
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the plot's property collection, used for data defined overrides.
Definition qgsplot.h:151
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the plot property definitions.
Definition qgsplot.cpp:88
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the plot's property collection, used for data defined overrides.
Definition qgsplot.h:136
DataDefinedProperty
Data defined properties for different plot types.
Definition qgsplot.h:96
@ YAxisMinorInterval
Minor grid line interval for Y axis.
Definition qgsplot.h:105
@ YAxisLabelInterval
Label interval for Y axis.
Definition qgsplot.h:106
@ XAxisMajorInterval
Major grid line interval for X axis.
Definition qgsplot.h:101
@ XAxisMaximum
Maximum X axis value.
Definition qgsplot.h:108
@ XAxisMinimum
Minimum X axis value.
Definition qgsplot.h:107
@ XAxisLabelInterval
Label interval for X axis.
Definition qgsplot.h:103
@ MarginBottom
Bottom margin.
Definition qgsplot.h:100
@ XAxisMinorInterval
Minor grid line interval for X axis.
Definition qgsplot.h:102
@ YAxisMajorInterval
Major grid line interval for Y axis.
Definition qgsplot.h:104
@ YAxisMaximum
Maximum Y axis value.
Definition qgsplot.h:110
@ MarginLeft
Left margin.
Definition qgsplot.h:97
@ MarginRight
Right margin.
Definition qgsplot.h:99
@ YAxisMinimum
Minimum Y axis value.
Definition qgsplot.h:109
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
A button for controlling property overrides which may apply to a widget.
QgsProperty toProperty() const
Returns a QgsProperty object encapsulating the current state of the widget.
void changed()
Emitted when property definition changes.
void init(int propertyKey, const QgsProperty &property, const QgsPropertiesDefinition &definitions, const QgsVectorLayer *layer=nullptr, bool auxiliaryStorageEnabled=false)
Initialize a newly constructed property button (useful if button was included in a UI layout).
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
int propertyKey() const
Returns the property key linked to the button.
A button for creating and modifying QgsSymbol settings.
void setFixedSizeConstraints(bool fixedSizeConstraints)
Sets whether the widget adopts fixed size constraints.
void setSymbol(QgsSymbol *symbol)
Sets the symbol for the button.
void setSymbolType(Qgis::SymbolType type)
Sets the symbol type which the button requires.
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
void changed()
Emitted when the symbol's settings are changed.
void setShowNull(bool showNull)
Sets whether a set to null (clear) option is shown in the button's drop-down menu.
SymbolType * clonedSymbol()
Returns a clone of the current symbol (as the specified template type) defined by the button.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition qgis.h:6854
Single variable definition for use within a QgsExpressionContextScope.