Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to save and restore QPen and QBrush states?

How to save and restore QPen and QBrush states?

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 2 Posters 658 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    ntos
    wrote on last edited by
    #1

    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.

    Pl45m4P 1 Reply Last reply
    0
    • N ntos

      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.

      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote on last edited by Pl45m4
      #2

      @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 defaultPen and defaultBrush.
      You capture them, but when the signal is emitted they are "default" default (which is white, I think), because the actual data from your slice cannot be accessed.


      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      1 Reply Last reply
      0
      • N Offline
        N Offline
        ntos
        wrote on last edited by
        #3

        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.

        Pl45m4P 1 Reply Last reply
        0
        • N ntos

          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.

          Pl45m4P Offline
          Pl45m4P Offline
          Pl45m4
          wrote on last edited by Pl45m4
          #4

          @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 white

                  qDebug() << "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.


          If debugging is the process of removing software bugs, then programming must be the process of putting them in.

          ~E. W. Dijkstra

          1 Reply Last reply
          2
          • N Offline
            N Offline
            ntos
            wrote on last edited by ntos
            #5

            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.

            Pl45m4P 1 Reply Last reply
            0
            • N Offline
              N Offline
              ntos
              wrote on last edited by ntos
              #6

              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);
              
              
              }
              
              1 Reply Last reply
              0
              • N ntos

                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.

                Pl45m4P Offline
                Pl45m4P Offline
                Pl45m4
                wrote on last edited by Pl45m4
                #7

                @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 for loop.
                The series don't have any color by default and they are designed by the chart/chartview and its applied theme.
                The default theme (0 or "QChart::ChartThemeLight") is what you see when you don't set any color.
                ChartThemeTest.png

                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.


                If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                ~E. W. Dijkstra

                1 Reply Last reply
                1
                • N Offline
                  N Offline
                  ntos
                  wrote on last edited by
                  #8

                  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().

                  1 Reply Last reply
                  0
                  • N ntos has marked this topic as solved on

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved