How to save and restore QPen and QBrush states?
-
Hi,
Here is my code to explode a slice when hovering the mouse over and then restore the slice to its original position. The problem is when the mouse moves away, the colour of the slice is blank(white). Why?for (auto* slice : series->slices()) { slice->setLabelVisible(); QPen defaultPen = slice->pen(); QBrush defaultBrush = slice->brush(); connect(slice, &QPieSlice::hovered, [slice, defaultBrush, defaultPen](bool hovered){ if (hovered) { slice->setPen(QPen(Qt::darkGreen, 2)); slice->setBrush(QBrush(Qt::green)); slice->setExploded(hovered); } else { slice->setPen(defaultPen); slice->setBrush(defaultBrush); slice->setExploded(hovered); } }); }Thank you very much.
-
Hi,
Here is my code to explode a slice when hovering the mouse over and then restore the slice to its original position. The problem is when the mouse moves away, the colour of the slice is blank(white). Why?for (auto* slice : series->slices()) { slice->setLabelVisible(); QPen defaultPen = slice->pen(); QBrush defaultBrush = slice->brush(); connect(slice, &QPieSlice::hovered, [slice, defaultBrush, defaultPen](bool hovered){ if (hovered) { slice->setPen(QPen(Qt::darkGreen, 2)); slice->setBrush(QBrush(Qt::green)); slice->setExploded(hovered); } else { slice->setPen(defaultPen); slice->setBrush(defaultBrush); slice->setExploded(hovered); } }); }Thank you very much.
@ntos said in How to save and restore QPen and QBrush states?:
The problem is when the mouse moves away, the colour of the slice is blank(white). Why?
Think about the scope of your local variables
defaultPenanddefaultBrush.
You capture them, but when the signal is emitted they are "default" default (which is white, I think), because the actual data from yourslicecannot be accessed. -
Thank you. I have found a workaround by setting the pen and brush to a certain colour. Then slice->pen() will return that exact colour in the for loop. Don't know why Qt devs decided on pen()/brush() returning a light grey colour instead of a slice's default one.
-
Thank you. I have found a workaround by setting the pen and brush to a certain colour. Then slice->pen() will return that exact colour in the for loop. Don't know why Qt devs decided on pen()/brush() returning a light grey colour instead of a slice's default one.
@ntos said in How to save and restore QPen and QBrush states?:
Don't know why Qt devs decided on pen()/brush() returning a light grey colour instead of a slice's default one.
Don't blame Qt for your wrong code :)
If you add this before your connect, you will see that there is no data for
defaultBrush.
Therefore it's just whiteqDebug() << "Default Brush is: " << defaultBrush; qDebug() << "Slice label: " << slicees->label();Output:
Default Brush is: QBrush(QColor(ARGB 1, 0, 0, 0),NoBrush)
Slice label: "Jane"It's even mentioned in the documentation:
By default, the visual appearance of the slice is set by a theme, but the theme can be overridden by specifying slice properties. However, if the theme is changed after the slices are customized, all customization will be lost.( https://doc.qt.io/qt-6/qpieslice.html#details )
The "default" colors you see are the theme colors... the slice brush is still white.
-
Thank you.
QPieSlice* slice2 = series->slices().at(2); QBrush brush = slice2->brush(); qDebug() << "Default Brush is: " << pen; for { to change brush when mouse hovers over a slice and reuse brush when mouse moves away. }console output: Default Brush is: QBrush(QColor(ARGB 1, 0, 0, 0),NoBrush).
But as you see, I stored the brush before changing the slice properties, and the result was QColor(ARGB 1, 0, 0, 0). At this point, I hadn't hovered the mouse over the chart yet. Why was the result QColor(ARGB 1, 0, 0, 0)?
Further more, I didn't change any theme. This app is very simple. All it does is show a pie chart of 5 slices. I have no chance to change any theme. -
Here is the whole code:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); QPieSeries* series = new QPieSeries(); series->append("Vegetables", 0.4); series->append("Beans", 0.2); series->append("Fruit", 0.15); series->append("Seeds/Nuts", 0.1); series->append("Whole grains", 0.15); QPieSlice* slice0 = series->slices().at(0); slice0->setPen(QPen(Qt::darkMagenta, 2)); slice0->setBrush(QBrush(Qt::magenta)); QPieSlice* slice1 = series->slices().at(1); // set the pen to draw the border of the slice slice1->setPen(QPen(Qt::darkGreen, 2)); // set the brush to brush the whole slice. slice1->setBrush(QBrush(Qt::green)); QPieSlice* slice2 = series->slices().at(2); slice2->setPen(QPen(Qt::darkBlue, 2)); slice2->setBrush(QBrush(Qt::blue)); QPieSlice* slice3 = series->slices().at(3); slice3->setPen(QPen(Qt::darkYellow, 2)); slice3->setBrush(QBrush(Qt::yellow)); QPieSlice* slice4 = series->slices().at(4); slice4->setPen(QPen(Qt::darkCyan, 2)); slice4->setBrush(QBrush(Qt::cyan)); // Calculate the total value of the series qreal total = 0; for (const auto* slice : series->slices()) { total += slice->value(); } for (auto* slice : series->slices()) { // Calculate percentage double percentage = (slice->value() / total) * 100; QBrush defaultBrush = slice->brush(); QPen defaultPen = slice->pen(); slice->setLabel(QString("%1 (%2%)").arg(slice->label()).arg(percentage, 1, 'f',1)); slice->setLabelVisible(); slice->setLabelPosition(QPieSlice::LabelInsideNormal); connect(slice, &QPieSlice::hovered, [slice, defaultBrush, defaultPen](bool hovered){ if (hovered) { slice->setPen(QPen(Qt::darkGreen, 2)); slice->setBrush(QBrush(Qt::green)); slice->setExploded(hovered); } else { slice->setPen(defaultPen); slice->setBrush(defaultBrush); slice->setExploded(hovered); } }); } QChart* chart = new QChart(); chart->addSeries(series); chart->setTitle("What Derek ate this week"); chart->legend()->hide(); chart->setAnimationOptions(QChart::AllAnimations); QChartView* chartView = new QChartView(chart); chartView->setRenderHint(QPainter::Antialiasing); //set chartView as the main central widget this->setCentralWidget(chartView); } -
Thank you.
QPieSlice* slice2 = series->slices().at(2); QBrush brush = slice2->brush(); qDebug() << "Default Brush is: " << pen; for { to change brush when mouse hovers over a slice and reuse brush when mouse moves away. }console output: Default Brush is: QBrush(QColor(ARGB 1, 0, 0, 0),NoBrush).
But as you see, I stored the brush before changing the slice properties, and the result was QColor(ARGB 1, 0, 0, 0). At this point, I hadn't hovered the mouse over the chart yet. Why was the result QColor(ARGB 1, 0, 0, 0)?
Further more, I didn't change any theme. This app is very simple. All it does is show a pie chart of 5 slices. I have no chance to change any theme.@ntos said in How to save and restore QPen and QBrush states?:
Why was the result QColor(ARGB 1, 0, 0, 0)?
As I've said above, because you don't have access to the color in your
forloop.
The series don't have any color by default and they are designed by the chart/chartview and its applied theme.
The default theme (0or "QChart::ChartThemeLight") is what you see when you don't set any color.

Without making any further specifications, the slices' "own" brush is still the default one, which is
( 1, 0, 0, 0)(= 255, 0, 0, 0) in ARGB.
And (0, 0, 0) in RGB is... surprise... white.@ntos said in How to save and restore QPen and QBrush states?:
Here is the whole code:
Great, then mark the topic as resolved please.
-
Thank you Pl45m4.
The key to understanding how the colour works is "The series don't have any color by default and they are designed by the chart/chartview and its applied theme.". It took me a good time to understand what it meant. Now I put the for loop after the chart declaration and I can get the chart theme colour with slice->brush(). -
N ntos has marked this topic as solved on