按钮进度条,顾名思义,表面上长得像一个按钮,单击之后切换成进度条指示按钮单击动做执行的进度,主要用在一些须要直接在按钮执行动做显示对应进度的场景,在不少网页中常常看到这种效果,这个效果有个优势就是直接在原地显示进度条,不占用其余位置,而后提供各类颜色能够设置。近期大屏电子看板程序接近尾声了,文章末尾贴出几张动图效果。c++
#ifndef PROGRESSBUTTON_H #define PROGRESSBUTTON_H /** * 按钮进度条控件 做者:倪大侠(QQ:393320854 zyb920@hotmail.com) 2019-4-17 * 1:可设置进度线条宽度+颜色 * 2:可设置边框宽度+颜色 * 3:可设置圆角角度+背景颜色 */ #include <QWidget> class QTimer; #ifdef quc #if (QT_VERSION < QT_VERSION_CHECK(5,7,0)) #include <QtDesigner/QDesignerExportWidget> #else #include <QtUiPlugin/QDesignerExportWidget> #endif class QDESIGNER_WIDGET_EXPORT ProgressButton : public QWidget #else class ProgressButton : public QWidget #endif { Q_OBJECT Q_PROPERTY(int lineWidth READ getLineWidth WRITE setLineWidth) Q_PROPERTY(QColor lineColor READ getLineColor WRITE setLineColor) Q_PROPERTY(int borderWidth READ getBorderWidth WRITE setBorderWidth) Q_PROPERTY(QColor borderColor READ getBorderColor WRITE setBorderColor) Q_PROPERTY(int borderRadius READ getBorderRadius WRITE setBorderRadius) Q_PROPERTY(QColor bgColor READ getBgColor WRITE setBgColor) public: explicit ProgressButton(QWidget *parent = 0); protected: void resizeEvent(QResizeEvent *); void mousePressEvent(QMouseEvent *); void paintEvent(QPaintEvent *); void drawBg(QPainter *painter); void drawProgress(QPainter *painter); private: int lineWidth; //线条宽度 QColor lineColor; //线条颜色 int borderWidth; //边框宽度 QColor borderColor; //边框颜色 int borderRadius; //圆角角度 QColor bgColor; //背景颜色 double value; //当前值 int status; //状态 int tempWidth; //动态改变宽度 QTimer *timer; //定时器改变进度 public: int getLineWidth() const; QColor getLineColor() const; int getBorderWidth() const; QColor getBorderColor() const; int getBorderRadius() const; QColor getBgColor() const; QSize sizeHint() const; QSize minimumSizeHint() const; private slots: void progress(); public Q_SLOTS: //设置线条宽度+颜色 void setLineWidth(int lineWidth); void setLineColor(const QColor &lineColor); //设置边框宽度+颜色 void setBorderWidth(int borderWidth); void setBorderColor(const QColor &borderColor); //设置圆角角度+背景颜色 void setBorderRadius(int borderRadius); void setBgColor(const QColor &bgColor); Q_SIGNALS: void valueChanged(int value); }; #endif // PROGRESSBUTTON_H
void ProgressButton::paintEvent(QPaintEvent *) { QPainter painter(this); painter.setRenderHints(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; pen.setWidth(borderWidth); pen.setColor(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; font.setPixelSize(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; pen.setWidth(borderWidth); pen.setColor(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); //绘制圆弧进度 pen.setWidth(lineWidth); pen.setColor(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; font.setPixelSize(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(); }