按鈕進度條,顧名思義,表面上長得像一個按鈕,單擊之後切換成進度條指示按鈕單擊動做執行的進度,主要用在一些須要直接在按鈕執行動做顯示對應進度的場景,在不少網頁中常常看到這種效果,這個效果有個優勢就是直接在原地顯示進度條,不佔用其餘位置,而後提供各類顏色能夠設置。近期大屏電子看板程序接近尾聲了,文章末尾貼出幾張動圖效果。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(); }