.pro
1 QT += core gui 2 3 greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 4 5 CONFIG += c++11 6 7 # The following define makes your compiler emit warnings if you use 8 # any Qt feature that has been marked deprecated (the exact warnings 9 # depend on your compiler). Please consult the documentation of the 10 # deprecated API in order to know how to port your code away from it. 11 DEFINES += QT_DEPRECATED_WARNINGS 12 13 # You can also make your code fail to compile if it uses deprecated APIs. 14 # In order to do so, uncomment the following line. 15 # You can also select to disable deprecated APIs only up to a certain version of Qt. 16 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 17 18 SOURCES += 19 QProgressBarWater.cpp 20 main.cpp 21 mainwindow.cpp 22 23 HEADERS += 24 QProgressBarWater.h 25 mainwindow.h 26 27 FORMS += 28 mainwindow.ui 29 30 # Default rules for deployment. 31 qnx: target.path = /tmp/$${TARGET}/bin 32 else: unix:!android: target.path = /opt/$${TARGET}/bin 33 !isEmpty(target.path): INSTALLS += target
main.cpp
1 #include "mainwindow.h" 2 3 #include <QApplication> 4 5 int main(int argc, char *argv[]) 6 { 7 QApplication a(argc, argv); 8 MainWindow w; 9 w.show(); 10 return a.exec(); 11 }
mainwindow.h
1 #ifndef MAINWINDOW_H 2 #define MAINWINDOW_H 3 4 #include <QMainWindow> 5 6 #include "QProgressBarWater.h" 7 8 QT_BEGIN_NAMESPACE 9 namespace Ui { class MainWindow; } 10 QT_END_NAMESPACE 11 12 class MainWindow : public QMainWindow 13 { 14 Q_OBJECT 15 16 public: 17 MainWindow(QWidget *parent = nullptr); 18 ~MainWindow(); 19 20 private slots: 21 void on_horizontalSlider_valueChanged(int value); 22 23 private: 24 Ui::MainWindow *ui; 25 QProgressBarWater *m_pQProgressBarWater; 26 }; 27 #endif // MAINWINDOW_H
mainwindow.cpp
1 #include "mainwindow.h" 2 #include "ui_mainwindow.h" 3 4 MainWindow::MainWindow(QWidget *parent) 5 : QMainWindow(parent) 6 , ui(new Ui::MainWindow) 7 { 8 ui->setupUi(this); 9 10 m_pQProgressBarWater = new QProgressBarWater(this); 11 m_pQProgressBarWater->setGeometry(20, 20, 200, 300); 12 m_pQProgressBarWater->setMaxValue(100); 13 m_pQProgressBarWater->setMinValue(0); 14 } 15 16 MainWindow::~MainWindow() 17 { 18 delete ui; 19 } 20 21 void MainWindow::on_horizontalSlider_valueChanged(int value) 22 { 23 m_pQProgressBarWater->setValue(value); 24 }
mainwindow.ui
1 <?xml version="1.0" encoding="UTF-8"?> 2 <ui version="4.0"> 3 <class>MainWindow</class> 4 <widget class="QMainWindow" name="MainWindow"> 5 <property name="geometry"> 6 <rect> 7 <x>0</x> 8 <y>0</y> 9 <width>401</width> 10 <height>345</height> 11 </rect> 12 </property> 13 <property name="windowTitle"> 14 <string>MainWindow</string> 15 </property> 16 <widget class="QWidget" name="centralwidget"> 17 <widget class="QSlider" name="horizontalSlider"> 18 <property name="geometry"> 19 <rect> 20 <x>20</x> 21 <y>250</y> 22 <width>351</width> 23 <height>22</height> 24 </rect> 25 </property> 26 <property name="maximum"> 27 <number>100</number> 28 </property> 29 <property name="orientation"> 30 <enum>Qt::Horizontal</enum> 31 </property> 32 </widget> 33 </widget> 34 <widget class="QMenuBar" name="menubar"> 35 <property name="geometry"> 36 <rect> 37 <x>0</x> 38 <y>0</y> 39 <width>401</width> 40 <height>23</height> 41 </rect> 42 </property> 43 </widget> 44 <widget class="QStatusBar" name="statusbar"/> 45 </widget> 46 <resources/> 47 <connections/> 48 </ui>
QProgressBarWater.h
1 // https://blog.csdn.net/u012156872/article/details/110396056 2 #ifndef QPROGRESSBARWATER_H 3 #define QPROGRESSBARWATER_H 4 5 6 #include <QWidget> 7 #include <QPainter> 8 #include <QPaintEvent> 9 10 class QProgressBarWater : public QWidget 11 { 12 Q_OBJECT 13 14 public: 15 explicit QProgressBarWater(QWidget *parent = nullptr); 16 17 enum PercentStyle_Type{ 18 PercentStyle_Rect = 0, //矩形 19 PercentStyle_Circle, //圆 20 PercentStyle_Ellipse, //椭圆 21 }; 22 23 signals: 24 25 public slots: 26 27 protected: 28 virtual void paintEvent(QPaintEvent *event); 29 virtual void timerEvent(QTimerEvent *event); 30 31 private: 32 PercentStyle_Type m_percentStyle = PercentStyle_Circle; 33 QColor m_frontColor = Qt::green; 34 QColor m_textColor = Qt::white; 35 QColor m_boderColor = Qt::white; 36 QColor m_bgColor = QColor(0, 200, 0, 200); 37 QFont m_font; 38 int m_value = 50; 39 int m_minValue = 0; 40 int m_maxValue = 100; 41 int m_waterDensity = 1; 42 double m_waterHeight = 0.03; 43 double m_offset = 50; 44 int m_borderWidth = 0; 45 46 47 void drawValue(QPainter *painter); 48 49 public: 50 void setValue(int value); 51 int value(); 52 void setMaxValue(int value); 53 int maxValue(); 54 void setMinValue(int value); 55 int minValue(); 56 void setPercentStyle(QProgressBarWater::PercentStyle_Type type); 57 PercentStyle_Type percentStyle(); 58 void setWaterDensity(int val); 59 int waterDensity(); 60 void setColor(QColor col); 61 QColor color(); 62 void setWaterHeight(double val); 63 double waterHeight(); 64 void setBorderWidth(int val); 65 int borderWidth(); 66 void setTextColor(QColor col); 67 QColor textColor(); 68 void setBoderColor(QColor col); 69 QColor boderColor(); 70 void setBgColor(QColor col); 71 QColor bgColor(); 72 }; 73 74 #endif // QPROGRESSBARWATER_H
QProgressBarWater.cpp
1 #include "QProgressBarWater.h" 2 3 4 #include <QPainter> 5 #include <qmath.h> 6 #include <QBrush> 7 #include <QColor> 8 #include <QLinearGradient> 9 10 QProgressBarWater::QProgressBarWater(QWidget *parent) : QWidget(parent) 11 { 12 m_font.setFamily("Microsoft YaHei"); 13 this->startTimer(80); 14 } 15 16 void QProgressBarWater::setValue(int value) 17 { 18 m_value = qMax(m_minValue, qMin(m_maxValue, value)); 19 } 20 21 int QProgressBarWater::value() 22 { 23 return m_value; 24 } 25 26 void QProgressBarWater::setMaxValue(int value) 27 { 28 m_maxValue = value; 29 } 30 31 int QProgressBarWater::maxValue() 32 { 33 return m_maxValue; 34 } 35 36 void QProgressBarWater::setMinValue(int value) 37 { 38 m_minValue = value; 39 } 40 41 int QProgressBarWater::minValue() 42 { 43 return m_minValue; 44 } 45 46 void QProgressBarWater::setPercentStyle(QProgressBarWater::PercentStyle_Type type) 47 { 48 m_percentStyle = type; 49 } 50 51 QProgressBarWater::PercentStyle_Type QProgressBarWater::percentStyle() 52 { 53 return m_percentStyle; 54 } 55 56 void QProgressBarWater::setWaterDensity(int val) 57 { 58 m_waterDensity = val; 59 } 60 61 int QProgressBarWater::waterDensity() 62 { 63 return m_waterDensity; 64 } 65 66 void QProgressBarWater::setColor(QColor col) 67 { 68 m_frontColor = col; 69 } 70 71 QColor QProgressBarWater::color() 72 { 73 return m_frontColor; 74 } 75 76 void QProgressBarWater::setWaterHeight(double val) 77 { 78 m_waterHeight = val; 79 } 80 81 double QProgressBarWater::waterHeight() 82 { 83 return m_waterHeight; 84 } 85 86 void QProgressBarWater::setBorderWidth(int val) 87 { 88 m_borderWidth = val; 89 } 90 91 int QProgressBarWater::borderWidth() 92 { 93 return m_borderWidth; 94 } 95 96 void QProgressBarWater::setTextColor(QColor col) 97 { 98 m_textColor = col; 99 } 100 101 QColor QProgressBarWater::textColor() 102 { 103 return m_textColor; 104 } 105 106 void QProgressBarWater::setBoderColor(QColor col) 107 { 108 m_boderColor = col; 109 } 110 111 QColor QProgressBarWater::boderColor() 112 { 113 return m_boderColor; 114 } 115 116 void QProgressBarWater::setBgColor(QColor col) 117 { 118 m_bgColor = col; 119 } 120 121 QColor QProgressBarWater::bgColor() 122 { 123 return m_bgColor; 124 } 125 126 void QProgressBarWater::timerEvent(QTimerEvent *event) 127 { 128 Q_UNUSED(event); 129 130 this->update(); 131 } 132 133 void QProgressBarWater::drawValue(QPainter *painter) 134 { 135 Q_UNUSED(painter); 136 painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing | QPainter::SmoothPixmapTransform); // 反锯齿; 137 138 int height = this->height(); 139 int width = this->width(); 140 int side = qMin(width, height); 141 142 //计算当前值所占百分比 143 double percent = 1 - (double)(m_value - m_minValue) / (m_maxValue - m_minValue); 144 145 //正弦曲线公式 y = A * sin(ωx + φ) + k 146 //w表示周期,可以理解为水波的密度,值越大密度越大(浪越密集 ^_^),取值 密度*M_PI/宽度 147 double w = 0.038;//m_waterDensity * M_PI * 1.6/ width; 148 149 //A表示振幅,可以理解为水波的高度,值越大高度越高(越浪 ^_^),取值高度的百分比 150 double A = height * m_waterHeight; 151 152 //k表示y轴偏移,可以理解为进度,取值高度的进度百分比 153 double k = height * percent; 154 155 //第一条波浪路径集合 156 QPainterPath waterPath1; 157 158 //第二条波浪路径集合 159 QPainterPath waterPath2; 160 161 //移动到左上角起始点 162 waterPath1.moveTo(0, height); 163 waterPath2.moveTo(0, height); 164 165 m_offset += 0.6; 166 if (m_offset > (width / 2)) { 167 m_offset = 0; 168 } 169 170 double waterY1 = 0.0; 171 double waterY2 = 0.0; 172 for(int x = 0; x <= width; x++) { 173 //第一条波浪Y轴 174 waterY1 = (double)(A * qSin(w * x + m_offset)) + k; 175 176 //第二条波浪Y轴 177 waterY2 = (double)(A * qSin(w * x + m_offset + (width / 2 * w))) + k; 178 179 //如果当前值为最小值则Y轴为高度 180 if (m_value == m_minValue) { 181 waterY1 = height; 182 waterY2 = height; 183 } 184 185 //如果当前值为最大值则Y轴为0 186 if (m_value == m_maxValue) { 187 waterY1 = 0; 188 waterY2 = 0; 189 } 190 191 waterPath1.lineTo(x, waterY1); 192 waterPath2.lineTo(x, waterY2); 193 } 194 195 //移动到右下角结束点,整体形成一个闭合路径 196 waterPath1.lineTo(width, height); 197 waterPath2.lineTo(width, height); 198 199 //画背景,此处由单一色调改为了渐变色 200 QRadialGradient radialGradient(side / 2, height / 2, side / 2, side / 2, side / 2); 201 radialGradient.setColorAt(0, QColor(0, 0, 255, 100)); 202 radialGradient.setColorAt(1.0, QColor(50, 50, 255, 200)); 203 204 QPainterPath bigPath; 205 if (m_percentStyle == PercentStyle_Rect) { 206 width = width - m_borderWidth * 2; 207 height = height - m_borderWidth * 2; 208 bigPath.addRect(m_borderWidth, m_borderWidth, width, height); 209 //painter->setBrush(m_boderColor); 210 painter->setBrush(QBrush(radialGradient)); 211 painter->drawRect(this->rect()); 212 //painter->setBrush(m_bgColor); 213 painter->setBrush(QBrush(radialGradient)); 214 painter->drawRect(m_borderWidth, m_borderWidth, width, height); 215 } 216 else if (m_percentStyle == PercentStyle_Circle) { 217 //painter->setBrush(m_boderColor); 218 // painter->setBrush(QBrush(radialGradient)); 219 // painter->drawEllipse((width - side) / 2, (height - side) / 2, side, height); 220 side = side - m_borderWidth * 2; 221 bigPath.addEllipse((width - side) / 2, m_borderWidth, side, side); 222 //painter->setBrush(m_bgColor); 223 painter->setBrush(QBrush(radialGradient)); 224 painter->setPen(m_bgColor); 225 painter->drawEllipse((width - side) / 2, m_borderWidth, side, side); 226 } 227 else if (m_percentStyle == PercentStyle_Ellipse) { 228 width = width - m_borderWidth * 2; 229 height = height - m_borderWidth * 2; 230 bigPath.addEllipse(m_borderWidth, m_borderWidth, width, height); 231 //painter->setBrush(m_boderColor); 232 painter->setBrush(QBrush(radialGradient)); 233 painter->drawEllipse(this->rect()); 234 //painter->setBrush(m_bgColor); 235 painter->setBrush(QBrush(radialGradient)); 236 painter->drawEllipse(m_borderWidth, m_borderWidth, width, height); 237 } 238 239 painter->save(); 240 241 //新路径,用大路径减去波浪区域的路径,形成遮罩效果 242 QPainterPath path; 243 painter->setPen(Qt::NoPen); 244 QColor waterColor1 = m_frontColor; 245 waterColor1.setAlpha(100); 246 QColor waterColor2 = m_frontColor; 247 waterColor2.setAlpha(180); 248 249 QLinearGradient linearGradient1(0,0,0,side); 250 linearGradient1.setColorAt(0.2,QColor(0, 255, 255, 100)); 251 linearGradient1.setColorAt(0.6,QColor(50, 200, 50, 100)); 252 linearGradient1.setColorAt(1.0,QColor(25, 150, 25, 100)); 253 254 QLinearGradient linearGradient2(0,0,0,side); 255 linearGradient2.setColorAt(0.2,QColor(0, 255, 255, 180)); 256 linearGradient2.setColorAt(0.6,QColor(50, 200, 50, 180)); 257 linearGradient2.setColorAt(1.0,QColor(25, 150, 25, 180)); 258 259 //第一条波浪挖去后的路径 260 path = bigPath.intersected(waterPath1); 261 painter->setBrush(QBrush(linearGradient1)); 262 painter->drawPath(path); 263 264 //第二条波浪挖去后的路径 265 path = bigPath.intersected(waterPath2); 266 painter->setBrush(QBrush(linearGradient2)); 267 painter->drawPath(path); 268 painter->restore(); 269 270 //绘制文字 271 m_font.setPixelSize(this->width()/4); 272 painter->setPen(m_textColor); 273 painter->setFont(m_font); 274 painter->drawText(this->rect(), Qt::AlignCenter, QString("%0%").arg(QString::number(m_value))); 275 } 276 277 void QProgressBarWater::paintEvent(QPaintEvent *event) 278 { 279 Q_UNUSED(event); 280 281 QPainter painter(this); 282 drawValue(&painter); 283 }