├── README.md ├── main.cpp ├── waterProcess.pro ├── waterprocess.cpp ├── waterprocess.h ├── widget.cpp ├── widget.h └── widget.ui /README.md: -------------------------------------------------------------------------------- 1 | # waterProcess 2 | 水波进度条 3 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "widget.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | Widget w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /waterProcess.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2019-07-26T17:10:35 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | 9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 10 | 11 | TARGET = waterProcess 12 | TEMPLATE = app 13 | 14 | 15 | SOURCES += main.cpp\ 16 | widget.cpp \ 17 | waterprocess.cpp 18 | 19 | HEADERS += widget.h \ 20 | waterprocess.h 21 | 22 | FORMS += widget.ui 23 | -------------------------------------------------------------------------------- /waterprocess.cpp: -------------------------------------------------------------------------------- 1 | #include "waterprocess.h" 2 | #include 3 | 4 | WaterProcess::WaterProcess(QWidget *parent) 5 | : QWidget(parent) 6 | { 7 | m_minValue = 0; 8 | m_maxValue = 100; 9 | m_value = 66; 10 | 11 | m_borderWidth = 10.0; 12 | m_waterHeight = 0.05; 13 | m_offset = 0.6; 14 | 15 | m_bgColor = QColor(120, 120, 120); 16 | m_borderColor = QColor(80, 80, 80); 17 | m_usedColor = QColor(235, 106, 106); 18 | m_textColor = QColor(255, 255, 255); 19 | 20 | //波浪 21 | m_timer = new QTimer(this); 22 | m_timer->setInterval(100); 23 | 24 | connect(m_timer, SIGNAL(timeout()), this, SLOT(update())); 25 | 26 | m_timer->start(); 27 | 28 | } 29 | 30 | void WaterProcess::setUsedColor(const QColor color) 31 | { 32 | m_usedColor = color; 33 | } 34 | 35 | void WaterProcess::paintEvent(QPaintEvent *ev) 36 | { 37 | Q_UNUSED(ev) 38 | 39 | QPainter painter(this); 40 | painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing); 41 | 42 | //背景 43 | drawBg(&painter); 44 | 45 | //进度、水波 46 | drawProcess(&painter); 47 | 48 | //进度数字 49 | drawValue(&painter); 50 | } 51 | 52 | void WaterProcess::drawBg(QPainter *painter) 53 | { 54 | int width = this->width(); 55 | int height = this->height(); 56 | int side = qMin(width, height) - m_borderWidth; 57 | 58 | int startX = (width - side) * 0.5; 59 | int startY = (height - side) * 0.5; 60 | 61 | painter->save(); 62 | painter->setBrush(QBrush(m_bgColor)); 63 | if (m_borderWidth == 0) { 64 | painter->setPen(Qt::NoPen); 65 | } else { 66 | QBrush brush(m_borderColor); 67 | painter->setPen(QPen(brush, m_borderWidth, Qt::SolidLine)); 68 | } 69 | 70 | painter->drawEllipse(startX, startY, side, side); 71 | painter->restore(); 72 | } 73 | 74 | void WaterProcess::drawProcess(QPainter *painter) 75 | { 76 | int width = this->width(); 77 | int height = this->height(); 78 | int side = qMin(width, height) - (2 * m_borderWidth); //直径 79 | 80 | int startX = (width - side) * 0.5; 81 | int startY = (height - side) *0.5; 82 | int endX = startX + side; 83 | int endY = startY + side; 84 | 85 | double percent = (m_value * 1.0) / (m_maxValue - m_minValue); 86 | 87 | double w = 2 * M_PI / endX; 88 | double A = endY * m_waterHeight; 89 | double k = endY * (1.0 - percent); 90 | 91 | painter->save(); 92 | painter->setPen(Qt::NoPen); 93 | painter->setBrush(m_usedColor); 94 | 95 | QPainterPath totalPath; 96 | //加入圆形路径 97 | totalPath.addEllipse(startX, startY, side, side); 98 | 99 | //水波路径 100 | QPainterPath water1; 101 | QPainterPath water2; 102 | 103 | water1.moveTo(startX, endY); 104 | water2.moveTo(startX, endY); 105 | 106 | m_offset += 0.6; 107 | if (m_offset > (endX / 2)) { 108 | m_offset = 0; 109 | } 110 | 111 | for(int i = startX; i < endX; i++) { 112 | //第一条波浪Y轴 113 | double waterY1 = (double)(A * qSin(w * i + m_offset)) + k; 114 | //第二条波浪Y轴 115 | double waterY2; 116 | waterY2 = (double)(A * qSin(w * i + m_offset + (endX / 2 * w))) + k; 117 | 118 | water1.lineTo(i, waterY1); 119 | water2.lineTo(i, waterY2); 120 | 121 | if (m_value == m_minValue) { 122 | waterY1 = endY; 123 | } 124 | 125 | if (m_value == m_maxValue) { 126 | waterY1 = startY; 127 | } 128 | } 129 | //封闭 130 | water1.lineTo(endX, endY); 131 | water2.lineTo(endX, endY); 132 | 133 | QPainterPath path; 134 | QColor waterColor1 = m_usedColor; 135 | waterColor1.setAlpha(100); 136 | QColor waterColor2 = m_usedColor; 137 | waterColor2.setAlpha(200); 138 | 139 | //第一条波浪 140 | path = totalPath.intersected(water1); 141 | painter->setBrush(waterColor1); 142 | painter->drawPath(path); 143 | 144 | //第二条波浪挖去后的路径 145 | path = totalPath.intersected(water2); 146 | painter->setBrush(waterColor2); 147 | painter->drawPath(path); 148 | 149 | 150 | painter->restore(); 151 | } 152 | 153 | void WaterProcess::drawValue(QPainter *painter) 154 | { 155 | painter->save(); 156 | int width = this->width(); 157 | int height = this->height(); 158 | int side = qMin(width, height) - m_borderWidth; 159 | 160 | int startX = (width - side) * 0.5; 161 | int startY = (height - side) * 0.5; 162 | 163 | int fontSize = side / 3; 164 | 165 | 166 | QFont font; 167 | font.setFamily("微软雅黑"); 168 | font.setPixelSize(fontSize); 169 | font.setBold(true); 170 | 171 | painter->setFont(font); 172 | painter->setPen(Qt::white); 173 | painter->drawText(QRectF(startX, startY, side, side), Qt::AlignCenter, QString("%1%").arg(m_value)); 174 | 175 | painter->restore(); 176 | } 177 | 178 | void WaterProcess::setMinValue(int value) 179 | { 180 | m_minValue = value; 181 | update(); 182 | } 183 | 184 | void WaterProcess::setMaxValue(int value) 185 | { 186 | m_maxValue = value; 187 | update(); 188 | } 189 | 190 | void WaterProcess::setValue(int v) 191 | { 192 | m_value = v; 193 | update(); 194 | } 195 | 196 | void WaterProcess::setBorderWidth(int width) 197 | { 198 | m_borderWidth = width; 199 | update(); 200 | } 201 | 202 | void WaterProcess::setWaterHeight(int height) 203 | { 204 | m_waterHeight = height; 205 | update(); 206 | } 207 | 208 | void WaterProcess::start() 209 | { 210 | if (m_timer) { 211 | m_timer->start(); 212 | } 213 | } 214 | 215 | void WaterProcess::stop() 216 | { 217 | if (m_timer) { 218 | m_timer->stop(); 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /waterprocess.h: -------------------------------------------------------------------------------- 1 | #ifndef WATERPROCESS_H 2 | #define WATERPROCESS_H 3 | 4 | #include 5 | #include 6 | 7 | class WaterProcess : public QWidget 8 | { 9 | Q_OBJECT 10 | public: 11 | explicit WaterProcess(QWidget *parent = nullptr); 12 | 13 | ~WaterProcess(){} 14 | 15 | void setUsedColor (const QColor color); 16 | 17 | protected: 18 | void paintEvent(QPaintEvent *ev); 19 | 20 | private: 21 | //画背景 22 | void drawBg(QPainter *painter); 23 | 24 | //画水波 25 | void drawProcess(QPainter *painter); 26 | 27 | //画文字 28 | void drawValue(QPainter *painter); 29 | 30 | public Q_SLOTS: 31 | void setMinValue(int value); 32 | void setMaxValue(int value); 33 | void setValue(int v); 34 | 35 | void setBorderWidth(int width); 36 | void setWaterHeight(int height); 37 | 38 | void start(); 39 | void stop(); 40 | 41 | private: 42 | int m_minValue; //最小值 43 | int m_maxValue; //最大值 44 | int m_value; //当前值 45 | 46 | double m_borderWidth; //边框宽度 47 | double m_waterHeight; //水波高度 48 | double m_offset; //水波偏移量 49 | 50 | QColor m_bgColor; //背景颜色 51 | QColor m_borderColor; //边框颜色 52 | QColor m_usedColor; //进度颜色 53 | QColor m_textColor; //文字颜色 54 | 55 | QTimer *m_timer; //水波定时器 56 | }; 57 | 58 | #endif // WATERPROCESS_H 59 | -------------------------------------------------------------------------------- /widget.cpp: -------------------------------------------------------------------------------- 1 | #include "widget.h" 2 | #include "ui_widget.h" 3 | 4 | Widget::Widget(QWidget *parent) : 5 | QWidget(parent), 6 | ui(new Ui::Widget) 7 | { 8 | ui->setupUi(this); 9 | ui->waterProcess2->setUsedColor(QColor(79, 175, 243)); 10 | } 11 | 12 | Widget::~Widget() 13 | { 14 | delete ui; 15 | } 16 | 17 | void Widget::on_borderWidthSlider_valueChanged(int value) 18 | { 19 | ui->waterProcess1->setBorderWidth(value); 20 | ui->waterProcess2->setBorderWidth(value); 21 | } 22 | 23 | void Widget::on_processSlider_valueChanged(int value) 24 | { 25 | ui->waterProcess1->setValue(value); 26 | ui->waterProcess2->setValue(value); 27 | } 28 | -------------------------------------------------------------------------------- /widget.h: -------------------------------------------------------------------------------- 1 | #ifndef WIDGET_H 2 | #define WIDGET_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class Widget; 8 | } 9 | 10 | class Widget : public QWidget 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit Widget(QWidget *parent = 0); 16 | ~Widget(); 17 | 18 | private slots: 19 | void on_borderWidthSlider_valueChanged(int value); 20 | 21 | void on_processSlider_valueChanged(int value); 22 | 23 | private: 24 | Ui::Widget *ui; 25 | }; 26 | 27 | #endif // WIDGET_H 28 | -------------------------------------------------------------------------------- /widget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Widget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 560 10 | 418 11 | 12 | 13 | 14 | Widget 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | QLayout::SetFixedSize 31 | 32 | 33 | 34 | 35 | 边框大小 36 | 37 | 38 | 39 | 40 | 41 | 42 | 40 43 | 44 | 45 | 10 46 | 47 | 48 | Qt::Horizontal 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | QLayout::SetMinimumSize 58 | 59 | 60 | 61 | 62 | 进度 63 | 64 | 65 | 66 | 67 | 68 | 69 | 100 70 | 71 | 72 | 1 73 | 74 | 75 | 66 76 | 77 | 78 | Qt::Horizontal 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | WaterProcess 90 | QWidget 91 |
waterprocess.h
92 | 1 93 |
94 |
95 | 96 | 97 |
98 | --------------------------------------------------------------------------------