前言
按钮进度条,顾名思义,表面上长得像一个按钮,单击以后切换成进度条指示按钮单击动作执行的进度,主要用在一些需要直接在按钮执行动作显示对应进度的场景,在很多网页中经常看到这种效果,这个效果有个优点就是直接在原地显示进度条,不占用其他位置,然后提供各种颜色可以设置。近期大屏电子看板程序接近尾声了,文章末尾贴出几张动图效果。
实现的功能
* 1:可设置进度线条宽度+颜色
* 2:可设置边框宽度+颜色
* 3:可设置圆角角度+背景颜色
效果图
核心代码
void ProgressButton::paintEvent(QPaintEvent *) { QPainter painter(this); (QPainter::Antialiasing | QPainter::TextAntialiasing); if (1 == status) { //绘制当前进度 drawProgress(&painter); } else { //绘制按钮背景 drawBg(&painter); } } void ProgressButton::drawBg(QPainter *painter) { painter->save(); int width = this->width(); int height = this->height(); int side = qMin(width, height); QPen pen; (borderWidth); (borderColor); painter->setPen(borderWidth > 0 ? pen : Qt::NoPen); painter->setBrush(bgColor); QRect rect(((width - tempWidth) / 2) + borderWidth, borderWidth, tempWidth - (borderWidth * 2), height - (borderWidth * 2)); painter->drawRoundedRect(rect, borderRadius, borderRadius); QFont font; (side - 18); painter->setFont(font); painter->setPen(lineColor); painter->drawText(rect, Qt::AlignCenter, status == 2 ? "完 成" : "开 始"); painter->restore(); } void ProgressButton::drawProgress(QPainter *painter) { painter->save(); int width = this->width(); int height = this->height(); int side = qMin(width, height); int radius = 99 - borderWidth; //绘制外圆 QPen pen; (borderWidth); (borderColor); painter->setPen(borderWidth > 0 ? pen : Qt::NoPen); painter->setBrush(bgColor); //平移坐标轴中心,等比例缩放 QRect rectCircle(-radius, -radius, radius * 2, radius * 2); painter->translate(width / 2, height / 2); painter->scale(side / 200.0, side / 200.0); painter->drawEllipse(rectCircle); //绘制圆弧进度 (lineWidth); (lineColor); painter->setPen(pen); int offset = radius - lineWidth - 5; QRectF rectArc(-offset, -offset, offset * 2, offset * 2); int startAngle = offset * 16; int spanAngle = -value * 16; painter->drawArc(rectArc, startAngle, spanAngle); //绘制进度文字 QFont font; (offset - 15); painter->setFont(font); QString strValue = QString("%1%").arg((int)value * 100 / 360); painter->drawText(rectCircle, Qt::AlignCenter, strValue); painter->restore(); } void ProgressButton::progress() { if (0 == status) { tempWidth -= 5; if (tempWidth < this->height() / 2) { tempWidth = this->height() / 2; status = 1; } } else if (1 == status) { value += 1.0; if (value >= 360) { value = 360.0; status = 2; } } else if (2 == status) { tempWidth += 5; if (tempWidth > this->width()) { tempWidth = this->width(); timer->stop(); } } this->update(); }