进度条应该是界面开发中最常用来做传输文件,加载配置等等待操作并可以提供一个直观的进度。
核心代码:
头文件
class RoundProgressBarPrivate;
class LIB_CUSTOMCONTROLSSHARED_EXPORT RoundProgressBar : public QWidget
{
Q_OBJECT
Q_PROPERTY(double minimum READ minimum WRITE setMinimum)
Q_PROPERTY(double maximum READ maximum WRITE setMaximum)
Q_PROPERTY(quint16 progressWidth READ progressWidth WRITE setProgressWidth)
Q_PROPERTY(double value READ value WRITE setValue NOTIFY valueChanged)
Q_PROPERTY(bool textVisible READ isTextVisible WRITE setTextVisible)
Q_PROPERTY(QColor progressColor READ progressColor WRITE setProgressColor)
Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
public:
explicit RoundProgressBar(QWidget *parent = 0);
//设置最大最小值,默认0~100
void setMinimum(double minimum);
void setMaximum(double maximum);
double minimum();
double maximum();
//设置进度条宽度
void setProgressWidth(quint16 width);
quint16 progressWidth();
//设置文本显示格式,与普通的qprogressbar使用方法相同
void setFormat(const QString &format);
QString format() const;
//大小值
double value();
//百分比值
double percent();
//是否显示文本
bool isTextVisible();
void setTextVisible(bool visible);
//进度条颜色
QColor progressColor() const;
void setProgressColor(const QColor &color);
//背景颜色
QColor backgroundColor() const;
void setBackgroundColor(const QColor &color);
signals:
void valueChanged(int);
public Q_SLOTS:
//设置当前值
void setValue(double value);
//设置范围
void setRange(double minimum, double maximum);
protected:
void paintEvent(QPaintEvent *event);
private:
QSharedPointer<RoundProgressBarPrivate> d_ptr;
Q_DECLARE_PRIVATE(RoundProgressBar)
Q_DISABLE_COPY(RoundProgressBar)
};
核心实现代码
绘制事件
void RoundProgressBar::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
Q_D(RoundProgressBar);
QStylePainter painter(this);
//设置反锯齿
// painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::Qt4CompatiblePainting);
d->drawRound(&painter);
if(d->bTextVisible)
d->drawText(&painter);
}
void RoundProgressBarPrivate::drawRound(QStylePainter *p)
{
Q_Q(RoundProgressBar);
p->setRenderHint(QPainter::Antialiasing,true);
QRect drawRect = q->rect();
int radius = qMin(q->rect().width(),q->rect().height());
drawRect.setSize(QSize(radius,radius));
drawRect.moveCenter(q->rect().center());
QRect borderRect = drawRect;
QRect backGroundRect = drawRect;
QRegion region(drawRect,QRegion::Ellipse);
//计算背景区域
backGroundRect.setSize(QSize(drawRect.width()-m_progressWidth-default_border,drawRect.height()-m_progressWidth-default_border));
backGroundRect.moveCenter(drawRect.center());
//计算border区域
borderRect.setSize(QSize(drawRect.width()-m_progressWidth,drawRect.height()-m_progressWidth));
borderRect.moveCenter(drawRect.center());
QRegion region_backGround(backGroundRect,QRegion::Ellipse);
QRegion region_border(borderRect,QRegion::Ellipse);
//外部圆环路径
QPainterPath backGroundPath;
backGroundPath.addRegion(region.subtracted(region_border));
//border路径
QPainterPath borderPath;
borderPath.addRegion(region_border.subtracted(region_backGround));
//绘制外部圆环
p->fillPath(backGroundPath,QColor(255,255,255));
//绘制border
// p->fillPath(borderPath,m_progressColor);//不需要绘制
//绘制内部圆
p->setPen(m_backgroundColor);
p->drawEllipse(borderRect);
//计算进度
int angle = q->percent()*360;
//绘制进度条
p->setBrush(QBrush(m_progressColor));
p->setPen(Qt::NoPen);
if(angle > 0)
p->drawPath(arcPath(drawRect,90,-angle,m_progressWidth/2));
}
//计算进度路径
QPainterPath RoundProgressBarPrivate::arcPath(QRectF rect, int startAngle, int angleLength, int arcHeight)
{
QPainterPath path;
path.moveTo(rect.center());
path.arcTo(rect, startAngle, angleLength);
QPainterPath subPath;
subPath.addEllipse(rect.adjusted(arcHeight, arcHeight, -arcHeight, -arcHeight));
// path为扇形 subPath为椭圆
path -= subPath;
return path;
}