chikuba
chikuba

Reputation: 4357

Customized color on progressbar delegate

Been trying to do this for quite a while and took advice from every forum post i could find but i still cant solve it. This is my current code and I would really like to change the color of the chunk on the progress bar. Every other setting is working, except the colors.

In my workspace object that fills up one subview on the MainWindow.

Workspace::Workspace( QWidget* parent) : QWidget( parent )
{
    QTableView* tableView = new QTableView();
    // ...
    tableView->setItemDelegate(new ProgressBarDelegate);
}

The delegate.cpp looks like this:

ProgressBarDelegate::ProgressBarDelegate( QObject* parent )
: QStyledItemDelegate(parent)
{
}

void ProgressBarDelegate::paint( QPainter *painter,
                                 const QStyleOptionViewItem &option,
                                 const QModelIndex &index) const
{
    if (index.column() == 2)
    {
        int progressPercentage = index.model()->data(index, Qt::DisplayRole).toInt();

        QStyleOptionProgressBarV2 progressBarOption;
        progressBarOption.rect = QRect(option.rect.x(), option.rect.y() + 5 , option.rect.width(), option.rect.height() / 1.5);
        progressBarOption.minimum = 0;
        progressBarOption.maximum = 100;
        progressBarOption.progress = progressPercentage;
        QPalette pal = progressBarOption.palette;
        QColor col = QColor(35, 35,25);
        pal.setColor(QPalette::Highlight, col); // or QPalette::Window doesnt matter
        progressBarOption.palette = pal;

        if(option.state & QStyle::State_Selected)
        {
        }

        QApplication::style()->drawControl( QStyle::CE_ProgressBar,
                                            &progressBarOption,
                                            painter);
    }
    else
    {
        QStyledItemDelegate::paint(painter, option, index);
    }
}

Currently, no matter what I do the color doesnt change from OSX standard light-gray.

Running OSX 10.6.7 and Qt 4.8.1 if that matters. thank you!

Edit:

I was able to do the following:

app.setStyleSheet("QScrollBar:horizontal { border: 2px solid green;background: cyan;height: 15px;margin: 0px 20px 0 20px;}");

But when I do this:

app.setStyleSheet("QProgressBar:horizontal { border: 1px solid gray; border-radius: 3px; background: white; padding: 1px; }");

NOTHING changes on the progressbar. I am in theory not creating any progressbar objects, im just settings a style how I'm viewing my data in my delegate. But surely, I cant be the first person who would want to do this right?

Also, if this doesnt work, how can I do this (having a styled progressbar) in a tableview?

Upvotes: 3

Views: 5601

Answers (2)

Ammar
Ammar

Reputation: 2017

You should use Qt Style Sheet, which allows us to customize UI of many controls to give unique look and feel across platforms. Check this.

Create a new simple Qt Gui project, open UI Form editor and add a Progress Bar control from under 'Display Widgets' in tool window. Now write following code in constructor of MainWindow..

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // Customize progress-bar's style..

    QString style = "QProgressBar {border: 2px solid grey; border-radius: 5px; text-align: center;}";
    style += "QProgressBar::chunk {background-color: #CD96CD; width: 10px; margin: 0.5px;}";

    // Assuming objectName is 'progressBar'..
    ui->progressBar->setStyleSheet(style);
}

Compile and run.

If you just want to change that single QProgressBar control, then above method is sufficient, but if you want to apply styles at application level (say all QProgressBar controls and some other controls), then proper way is to create a *.css file, write styles using Qt Style Sheet Reference and then read that file in Qt and call

QApplication::setStyleSheet(QString style).

Besides, style sheet uses the same syntax as CSS and also supports various selectors.

Edit:

I agree that above method works only with controls and not delegates. I found something for delegates also. Try following paint function.

void ProgressBarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if (index.column() == 2)
    {
        QProgressBar renderer;
        int progressPercentage = index.model()->data(index, Qt::DisplayRole).toInt();

        // Customize style using style-sheet..

        QString style = "QProgressBar { border: 2px solid grey; border-radius: 5px; }";
        style += "QProgressBar::chunk { background-color: #05B8CC; width: 20px; }";

        renderer.resize(option.rect.size());
        renderer.setMinimum(0);
        renderer.setMaximum(100);
        renderer.setValue(progressPercentage);

        renderer.setStyleSheet(style);
        painter->save();
        painter->translate(option.rect.topLeft());
        renderer.render(painter);
        painter->restore();
    }
    else
        QStyledItemDelegate::paint(painter, option, index);
}

So here the point is that instead of using QStyleOption, we can use directly the control itself as a renderer. Hope this helps..

Upvotes: 10

ScarCode
ScarCode

Reputation: 3094

Instead of pal.setColor(QPalette::Window, col);

Use pal.setColor(QPalette::Highlight, col);

This should work.

I used the code in Paintevent

   void Dialog::paintEvent(QPaintEvent *e)
   {
    QPainter painter(this);
    connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(ShowPrintDialog()));
    QStyleOptionProgressBarV2 progressBarOption;
    progressBarOption.rect = QRect(20,20,30,30);
    progressBarOption.minimum = 0;
    progressBarOption.maximum = 100;
    progressBarOption.progress = 75;
    QPalette pal = progressBarOption.palette;
    QColor col = QColor(0,255,0);
    pal.setColor(QPalette::Highlight, col);
    progressBarOption.palette = pal;


    QApplication::style()->drawControl(QStyle::CE_ProgressBar,&progressBarOption, &painter);
    }

Upvotes: 0

Related Questions