Ques
Ques

Reputation: 3

How to get a cylinder effect (2D) Progress Bar using Qt programming?

How to change the colors of the progressbar? Say 40% to red, 20% to green and 40% to yellow etc. I have tried using StyleSheets, but I found that it works only for Flat Progress Bars , not for the 2D bars.

enter image description here

Upvotes: 0

Views: 1106

Answers (1)

eyllanesc
eyllanesc

Reputation: 244013

To be able to generate this effect we draw elliptical, for this we could help us of QPainterPath to give it form, and we put the cover that is an ellipse as shown below:

progressbar2d.h

#ifndef PROGRESSBAR2D_H
#define PROGRESSBAR2D_H

#include <QProgressBar>

class ProgressBar2D : public QProgressBar
{
    Q_OBJECT

public:
    ProgressBar2D(QWidget *parent = 0);
    ~ProgressBar2D();

protected:
    void paintEvent(QPaintEvent *);

private:
    void draw(QPainter *painter, QRect rect, int w);
    void drawEllipticalRectangle(QPainter *painter, QRect rect, int w);
};

#endif // PROGRESSBAR2D_H

progressbar2d.cpp

#include "progressbar2d.h"
#include <QPainter>

ProgressBar2D::ProgressBar2D(QWidget *parent): QProgressBar(parent)
{
}

ProgressBar2D::~ProgressBar2D()
{
}

void ProgressBar2D::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    int borde = height()/10;

    draw(&painter,
         QRect(borde, borde, width()-2*borde, height()-2*borde),
         2*borde);

    painter.drawText(rect(),  Qt::AlignCenter, QString("%1").arg(value()));

}

void ProgressBar2D::draw(QPainter *painter, QRect rect, int w)
{

    int w_percentage = 2*w + value()*(rect.width()-2*w)/maximum();

    painter->setBrush(QBrush(QColor("#81C253")));
    drawEllipticalRectangle(painter,
                            QRect(rect.topLeft(), QSize(w_percentage, rect.height()) ),
                            w);

    painter->setBrush(QBrush(QColor("#C3DDB1")));
    drawEllipticalRectangle(painter,
                            QRect(QPoint(rect.topLeft() + QPoint(w_percentage-2*w, 0)),
                                  QSize(rect.width()-w_percentage+2*w, rect.height()) ),
                            w);

    painter->setBrush(QBrush(QColor("#77896C")));
    painter->drawEllipse(QRect( rect.topLeft() + QPoint(rect.width()-2*w, 0) , QSize(2*w, rect.height())));

}


void ProgressBar2D::drawEllipticalRectangle(QPainter *painter, QRect rect, int w)
{
    painter->translate(rect.topLeft());

    QPainterPath path;

    path.moveTo(w, 0);
    path.arcTo(QRectF(0, 0, 2*w, rect.height()), 90, 180);
    path.lineTo(rect.width()-w, rect.height());

    path.arcTo(QRectF(rect.width()-2*w, 0, 2*w, rect.height()), 270, -180);
    path.lineTo(w, 0);
    painter->drawPath(path);

    painter->translate(-rect.topLeft());
}

main.cpp

#include "progressbar2d.h"
#include <QApplication>
#include <QTimer>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    ProgressBar2D w;

    QTimer *timer = new QTimer(&w);

    QObject::connect(timer, &QTimer::timeout, [&w](){
        w.setValue((w.value()+1)%(1 + w.maximum()));
    });
    timer->start(100);
    w.show();

    return a.exec();
}

enter image description here

Upvotes: 2

Related Questions