4

Context

I'm using a Qt stylesheet to customise a QProgressBar in my UI. I have a contrasting theme going on, which can be seen below:

enter image description here

I control this via my stylesheet:

QProgressBar {
    color: #FFFFFF;               /* Text color (not highlighted)
    border: 2px solid white;      /* Border color */
    border-radius: 5px;           /* Rounded border edges */
    margin-left: 24px;
    margin-right: 24px;           
    text-align: center            /* Center the X% indicator */
}

QProgressBar::chunk {
    color: #204a87;               /* Highlighted text color!? Not working */
    background-color: #FFFFFF;    /* Color of the 'completed' bar */
}

Problem

Unfortunately, I find myself unable to change the highlighted progress text color once it is eclipsed or covered by the progress bar itself.

enter image description here

This can be seen above.

Solutions

I have attempted to see if I can set a highlight property for the text. I know that from the palette I can set a contrasting highlight color which makes the progress text label switch colors once the progress bar covers it. However, I can't find how to access that property here

QProgressBar::text::highlighted {
    color: #204a87; /* Doesn't do anything */ 
}

I also tried adding a color property to QProgressBar::chunk as you can see above. This also didn't do anything.

How can I set the contrasting highlight color for the progress bar label in the stylesheet? I've been looking mainly at this Qt resource for guidance but it doesn't cover such a situation.

Micrified
  • 3,338
  • 4
  • 33
  • 59

2 Answers2

5

This is my own conclusion, there might be better answer.

According to the progress bar's customization documentation, it seems that only border, chunk, and text-align can be customized using style sheets. Even adding selection-color doesn't work, because the text is not actually selected.

After trying out solutions in this question, I concluded that

  1. Qt does highlighting text in progress bar using painter, not in stylesheet
  2. Any changes to the stylesheet will override the painter

However, there is a solution if you are willing to compromise, using QPalette and fusion style as followed

#include "mainwindow.h"

#include <QStyleFactory>
#include <QProgressBar>
#include <QSlider>
#include <QVBoxLayout>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QWidget *central_widget = new QWidget{this};
    this->setCentralWidget(central_widget);

    QProgressBar *progress_bar = new QProgressBar{central_widget};
    progress_bar->setRange(0, 100);
    progress_bar->setValue(0);
    progress_bar->setStyle(QStyleFactory::create("fusion"));
    QSlider *slider = new QSlider{central_widget};
    slider->setRange(0, 100);
    slider->setValue(0);
    slider->setOrientation(Qt::Orientation::Horizontal);
    connect(slider, &QSlider::valueChanged, progress_bar, &QProgressBar::setValue);

    QVBoxLayout *layout = new QVBoxLayout{central_widget};
    layout->addWidget(progress_bar);
    layout->addWidget(slider);

    QPalette palette = progress_bar->palette();
    palette.setColor(QPalette::Text, QColor::fromRgb(QRgb{0xFFFFFF})); // text, not highlight
    palette.setColor(QPalette::HighlightedText, QColor::fromRgb(QRgb{0x204a87})); // text, highlight
    palette.setColor(QPalette::Base, QColor::fromRgb(QRgb{0x0000FF})); // background, not highlight
    palette.setColor(QPalette::Highlight, QColor::fromRgb(QRgb{0xFFFFFF})); // background, highlight
    progress_bar->setPalette(palette);
}

MainWindow::~MainWindow()
{

}

The fusion style has has the text centered in the progress bar. Text and background colors can be changed using QPalette, but you are giving up changing margin, border size, border color, border radius, and other properties.

Minh
  • 1,630
  • 1
  • 8
  • 18
1

The code for CE_ProgressBarLabel in qstylesheetstyle.cpp simply draws the text using the QPalette::Text color role. It won't ever switch to another role, so indeed this can't be done with QSS. Another limitation of QSS. The fully flexible solution would be to write a QProxyStyle and style progressbars with C++ code, implementing CE_ProgressBarLabel (and whatever else we need) ourselves.

David Faure
  • 1,836
  • 15
  • 19