如何使用Qt编程获得圆柱效果(2D)进度条?
How to get a cylinder effect (2D) Progress Bar using Qt programming?
如何改变进度条的颜色?比如说 40% 给红色,20% 给绿色,40% 给黄色等等。
我尝试过使用 StyleSheets,但我发现它仅适用于 Flat Progress Bars ,不适用于 2D 条。
为了产生这个效果我们画了椭圆形,为此我们可以帮QPainterPath
给它定型,我们把它作为椭圆的封面如下图:
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();
}
如何改变进度条的颜色?比如说 40% 给红色,20% 给绿色,40% 给黄色等等。 我尝试过使用 StyleSheets,但我发现它仅适用于 Flat Progress Bars ,不适用于 2D 条。
为了产生这个效果我们画了椭圆形,为此我们可以帮QPainterPath
给它定型,我们把它作为椭圆的封面如下图:
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();
}