PDA

View Full Version : Circle Progress Bar. Need help to improve



matthieu
4th January 2012, 22:37
Hi everyone,

I am trying to make a circle progress bar. I would like to add it into my future mp3 music player. Here is my first shot :

7236

It's not so bad, heh? Well, actually, it's kind of ugly code :(. How can I reuse "right" QProgressBar elements, like in QStyleOptionProgressBarV2 ? It would be great to improve it to fit for all platforms.

Need to be done:

Reuse code from QStyleOptionProgressBarV2 ?
When drawing path, there are some errors using "groovePath.simplified();"
Add a square layout to keep ratio when resizing
Deploy everywhere!




#ifndef CIRCLEPROGRESSBAR_H
#define CIRCLEPROGRESSBAR_H

#include <QProgressBar>

class CircleProgressBar : public QProgressBar
{
Q_OBJECT

private:
bool transparentCenter;
qreal startAngle;

public:
CircleProgressBar(QWidget *parent = 0);

inline void setTransparentCenter(bool value) { transparentCenter = value; }
inline void setStartAngle(qreal startAngle) { this->startAngle = startAngle; }

protected:
void paintEvent(QPaintEvent *event);
};

#endif // CIRCLEPROGRESSBAR_H




#include "circleprogressbar.h"

#include <QStylePainter>
#include <QDebug>

CircleProgressBar::CircleProgressBar(QWidget *parent) :
QProgressBar(parent), transparentCenter(false), startAngle(90.0)
{
this->setMinimumWidth(400);
this->setMinimumHeight(400);
}

void CircleProgressBar::paintEvent(QPaintEvent * /*event*/)
{
//TODO
static double coefOuter = 0.6;
static double coefInner = 0.4;
static double penSize = 1.0;
static QColor borderColor(178, 178, 178);
static QColor grooveColor(202, 202, 202);
static QColor chunkColor(0, 211, 40);

QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);

QRectF outerRect(rect().x()*coefOuter, rect().y()*coefOuter, rect().width()*coefOuter, rect().height()*coefOuter);
QRectF innerRect(rect().x()*coefInner, rect().y()*coefInner, rect().width()*coefInner, rect().height()*coefInner);
outerRect.moveCenter(rect().center());
innerRect.moveCenter(rect().center());

if (isTextVisible()) {
painter.save();
}

QPainterPath borderInAndOut;
borderInAndOut.addEllipse(rect().center(), rect().width()/2*coefOuter, rect().height()/2*coefOuter);
borderInAndOut.addEllipse(rect().center(), rect().width()/2*coefInner, rect().height()/2*coefInner);

QPen borderPen(borderColor, penSize);
painter.setPen(borderPen);
painter.setBrush(grooveColor);
painter.drawPath(borderInAndOut);

if (value() > 0) {
QPainterPath groovePath(rect().center());
qreal converterAngle = 3.6*value();
groovePath.arcTo(outerRect, startAngle, -converterAngle);
groovePath.moveTo(rect().center());
groovePath.arcTo(innerRect, startAngle, -converterAngle);
groovePath = groovePath.simplified();
painter.setPen(Qt::NoPen);
painter.setBrush(chunkColor);
painter.drawPath(groovePath);
}

if (!transparentCenter) {
QPainterPath painterPathCenter;
painterPathCenter.addEllipse(rect().center(), rect().width()/2*coefInner - penSize/2, rect().height()/2*coefInner - penSize/2);
painter.setPen(Qt::NoPen);
painter.setBrush(QColor(Qt::white));
painter.drawPath(painterPathCenter);
}

if (isTextVisible()) {
painter.restore();
QString val = QString::number(value()).append("%");
//QStyleOptionProgressBarV2 styleOption;
//style()->drawControl(QStyle::CE_ProgressBarGroove, &styleOption, &painter, this);
//style()->drawPrimitive(QStyle::PE_FrameStatusBar, &styleOption, &painter, this);
style()->drawItemText(&painter, rect(), Qt::AlignCenter, palette(), true, val);
}
}