I have a subclass of QProgressBar that draws itself with its bar extending left or right from the center point (to show both positive and negative values). I developed it under Qt5, where it worked fine with all the available styles. With Qt6, however, the CE_ProgressBarContents portion of the control is not drawn consistently between styles. "Windows" and "windowsvista" are rendering it correctly, but "Fusion" is not. It almost looks as though Fusion is not interpreting the coordinates in QStyleOptionProgressBar correctly.

These gifs show the behavior of a test application in which the QProgressBar subclass is getting its value set by a slider. The only difference between the two gifs is the Qt style in use. The code is exactly the same.

windowsvista style:
vista-style.gif

Fusion style:
fusion-style.gif

The min/max values allowed by this widget are -256 and 255. Its paintEvent code is below.

Does anyone know what might be going on here? Was there some change in the Fusion style behavior between Qt5 and Qt6? Or a change in the intended use of QStyleOptionProgressBar? I have tested this on Windows and Linux, with Qt versions 6.4.2 and 6.5.2. The anomalous Fusion behavior appears everywhere.

Qt Code:
  1. const int currentVal = this->value();
  2. const int max = this->maximum();
  3. const int min = this->minimum();
  4. QStylePainter painter(this);
  5.  
  6. opt.initFrom(this);
  7. opt.minimum = min;
  8. opt.maximum = max;
  9. opt.progress = (currentVal >= 0) ? qAbs(max) : qAbs(min);
  10.  
  11. // Draw the groove. This should simply be the same size as the outside dimensions of the widget.
  12. style()->drawControl(QStyle::CE_ProgressBarGroove, &opt, &painter, this);
  13.  
  14. // Get the dimensions for the bar itself (within the groove). Depending on the active graphical
  15. // style, this may be several pixels smaller that the dimensions of the widget, so that there's
  16. // a narrow gutter inside the groove not occupied by the bar.
  17. opt.rect = style()->subElementRect(QStyle::SE_ProgressBarContents, &opt, this);
  18.  
  19. const float percentOfWidth = (float)(qAbs(currentVal)) / (float)(max - min);
  20. const int left = opt.rect.topLeft().x();
  21. const int right = opt.rect.topRight().x();
  22. const int top = opt.rect.topLeft().y();
  23. const int height = opt.rect.bottomLeft().y() - top + 1;
  24. const int barWidth = (right - left) * percentOfWidth;
  25. const int midPoint = left + ((right - left) / 2);
  26. const int startPoint = (currentVal >= 0) ? midPoint : midPoint - barWidth;
  27.  
  28. opt.rect = QRect(startPoint, top, barWidth + 2, height);
  29. style()->drawControl(QStyle::CE_ProgressBarContents, &opt, &painter, this);
To copy to clipboard, switch view to plain text mode