Qt沙漏进度和水波进度发布(重写Qwidget实现)

https://blog.csdn.net/li491093957/article/details/61204422

Qwidget很强大可以重写任何东西。不信我会让你相信。

话不多说来张图片大家就知道了:

 

心动吗?我们一起来看看。

首先是沙漏进度代码:

 

 
  1. #ifndef NPROGRESANDCLOCK_H

  2. #define NPROGRESANDCLOCK_H

  3.  
  4. #include <QWidget>

  5. #include <QTimer>

  6. #include <QRect>

  7. #include <QPainter>

  8. #include <QPaintEvent>

  9. #include <QSize>

  10. class NProgreSandClock : public QWidget

  11. {

  12. Q_OBJECT

  13. public:

  14. NProgreSandClock(QWidget *parent);

  15. //设置沙漏外壁的宽

  16. void setSandClockWidth(int width);

  17. //设置是否循环旋转

  18. void setLoop(bool isLoop);

  19. //设置沙漏外边的颜色

  20. void setSandClockColor(QColor color);

  21. //设置沙的颜色

  22. void setSandColor(QColor color);

  23. //设置沙漏下去速度(毫秒)

  24. void setSandDownSpeed(int mes);

  25. //设置沙漏旋转的速度(毫秒)

  26. void setSandClockRoteSpeed(int mes);

  27. //设置当前进度

  28. void setSandClockProgre(int progre);

  29. ~NProgreSandClock();

  30. protected:

  31. //重绘事件

  32. void paintEvent(QPaintEvent *);

  33. private:

  34. int m_nNowProgres;

  35. //设置沙漏外壁的宽

  36. int m_nSandClockWidth;

  37. //沙漏旋转的速度

  38. int m_nSandColorRoteSpeed;

  39. //设置沙落下的速度

  40. int m_nSandDowSpeed;

  41. //沙的颜色

  42. QColor m_SandColor;

  43. //沙漏颜色

  44. QColor m_sandClockColor;

  45. //画沙漏

  46. void drawSandClock(QPainter* painter);

  47. bool isLoop;

  48. //旋转沙漏定时器

  49. QTimer* m_updateTimer;//定时器时间

  50. bool isFirstRotate;

  51. //旋转角度

  52. qreal m_angle;

  53. //外半径

  54. qreal m_outerRadius;

  55. //记录现在的状态

  56. int m_nNowStatus;

  57. //是否在画三角形

  58. bool isDrawTri;

  59. //记录三角形的高

  60. qreal triHeight;

  61. //现在的状态

  62. enum

  63. {

  64. DRAW_UP_TRIANG=0,DRAW_DOWN_TRIANG,DRAW_CIR_ROTETE

  65. };

  66. signals:

  67. void onProgres(int);

  68. private slots:

  69. //自定义槽,更新角度旋转

  70. void UpdateAngle();

  71. };

  72.  
  73. #endif // NPROGRESANDCLOCK_H

 

 

沙漏进度CPP:

 
  1. #include "NProgreSandClock.h"

  2.  
  3. NProgreSandClock::NProgreSandClock(QWidget *parent)

  4. : QWidget(parent)

  5. ,m_nNowStatus(2)

  6. ,isLoop(true),

  7. m_angle(0),

  8. m_outerRadius(0),

  9. isDrawTri(false)

  10. ,m_sandClockColor(QColor(63,107,157,255))

  11. ,m_SandColor(QColor(224,143,36,255))

  12. ,m_nSandDowSpeed(5)

  13. ,m_nSandColorRoteSpeed(2)

  14. ,m_nSandClockWidth(4)

  15. {

  16. //无窗体

  17. setWindowFlags(Qt::FramelessWindowHint);

  18. //背景透明

  19. setAttribute(Qt::WA_TranslucentBackground);

  20. m_updateTimer = new QTimer(this);

  21. //间隔,微妙微单位,大家可以改一下这个值看看转动速度。

  22. m_updateTimer->setInterval(m_nSandColorRoteSpeed);

  23. connect(m_updateTimer,SIGNAL(timeout()),this,SLOT(UpdateAngle()));

  24. //启动定时器

  25. m_updateTimer->start();

  26. }

  27. //重绘事件

  28. void NProgreSandClock::paintEvent(QPaintEvent *event)

  29. {

  30. QPainter painter(this);

  31. painter.setRenderHints(QPainter::Antialiasing|QPainter::HighQualityAntialiasing);//设置反锯齿

  32. drawSandClock(&painter);//画沙漏

  33. }

  34. //画沙漏和三角形

  35. void NProgreSandClock::drawSandClock(QPainter *painter)

  36. {

  37. m_outerRadius = width() > height() ? (qreal)height()/2 : (qreal)width()/2;

  38. if (m_nNowStatus== DRAW_CIR_ROTETE)

  39. {

  40. triHeight=m_outerRadius;

  41. }

  42. painter->save();

  43. // move to center

  44. painter->translate(m_outerRadius,m_outerRadius);

  45. painter->setPen(QPen(m_sandClockColor,m_nSandClockWidth,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));

  46. //旋转

  47. painter->rotate(m_angle);

  48. QRect widgetRect =this->rect();

  49. QPainterPath sandClockPath;

  50. sandClockPath.moveTo(-m_outerRadius*0.05,m_outerRadius*0.05);

  51. sandClockPath.lineTo(m_outerRadius*0.1,m_outerRadius);

  52. sandClockPath.lineTo(m_outerRadius,m_outerRadius*0.1);

  53. sandClockPath.lineTo(m_outerRadius*0.05,-m_outerRadius*0.05);

  54. sandClockPath.lineTo(-m_outerRadius*0.1,-m_outerRadius);

  55. sandClockPath.lineTo(-m_outerRadius,-m_outerRadius*0.1);

  56. sandClockPath.lineTo(-m_outerRadius*0.05,m_outerRadius*0.05);

  57. painter->drawPath(sandClockPath);

  58. painter->setPen(Qt::NoPen);

  59. if (isLoop)

  60. {

  61. emit onProgres(-1);

  62. QPoint triangle[3];

  63. painter->setBrush(QBrush(m_SandColor,Qt::SolidPattern));//设置画刷形式

  64. if (m_nNowStatus==DRAW_UP_TRIANG)

  65. {

  66. if (isDrawTri)

  67. {

  68. triangle[0]=QPoint(0,0);

  69. triangle[1]=QPoint(-triHeight*0.1,-triHeight);

  70. triangle[2]=QPoint(-triHeight,-triHeight*0.1);

  71. triHeight-=1;

  72. painter->drawPolygon(triangle,3);

  73. triangle[0]=QPoint(0,0);

  74. triangle[1]=QPoint((m_outerRadius*0.1)-triHeight*0.1,m_outerRadius-triHeight);

  75. triangle[2]=QPoint(m_outerRadius-triHeight,(m_outerRadius*0.1)-triHeight*0.1);

  76. if (triHeight<0)

  77. {

  78. isDrawTri=false;

  79. triHeight=m_outerRadius;

  80. m_nNowStatus= DRAW_CIR_ROTETE;

  81. m_angle+=1;

  82. }

  83. painter->drawPolygon(triangle,3);

  84. }

  85. }

  86. else if(m_nNowStatus==DRAW_DOWN_TRIANG)

  87. {

  88. if (isDrawTri)

  89. {

  90. triangle[0]=QPoint(0,0);

  91. triangle[1]=QPoint(triHeight*0.1,triHeight);

  92. triangle[2]=QPoint(triHeight,triHeight*0.1);

  93. triHeight-=1;

  94. painter->drawPolygon(triangle,3);

  95. triangle[0]=QPoint(0,0);

  96. triangle[1]=QPoint(-(m_outerRadius*0.1)+triHeight*0.1,-m_outerRadius+triHeight);

  97. triangle[2]=QPoint(-m_outerRadius+triHeight,-(m_outerRadius*0.1)+triHeight*0.1);

  98. if (triHeight<=0)

  99. {

  100. isDrawTri=false;

  101. triHeight=m_outerRadius;

  102. m_nNowStatus= DRAW_CIR_ROTETE;

  103. m_angle+=1;

  104. }

  105. painter->drawPolygon(triangle,3);

  106. }

  107. }

  108. else

  109. {

  110. if(m_angle>45&&m_angle<=225)

  111. {

  112. triangle[0]=QPoint(0,0);

  113. triangle[1]=QPoint(m_outerRadius*0.1-m_nSandClockWidth/3,m_outerRadius-m_nSandClockWidth/3);

  114. triangle[2]=QPoint(m_outerRadius-m_nSandClockWidth/3,m_outerRadius*0.1-m_nSandClockWidth/3);

  115. }

  116. else

  117. {

  118. triangle[0]=QPoint(0,0);

  119. triangle[1]=QPoint(-m_outerRadius*0.1+m_nSandClockWidth/3,-m_outerRadius+m_nSandClockWidth/3);

  120. triangle[2]=QPoint(-m_outerRadius+m_nSandClockWidth/3,-m_outerRadius*0.1+m_nSandClockWidth/3);

  121. }

  122. painter->drawPolygon(triangle,3);

  123. }

  124. }

  125. else

  126. {

  127. qreal nTriHeight=((float)(m_nNowProgres/100.0)*triHeight);

  128. emit onProgres(m_nNowProgres);

  129. painter->setBrush(QBrush(m_SandColor,Qt::SolidPattern));//设置画刷形式

  130. QPoint triangle[3];

  131. triangle[0]=QPoint(0,0);

  132. triangle[1]=QPoint(nTriHeight*0.1,nTriHeight);

  133. triangle[2]=QPoint(nTriHeight,nTriHeight*0.1);

  134. painter->drawPolygon(triangle,3);

  135. triangle[0]=QPoint(0,0);

  136. triangle[1]=QPoint(-(m_outerRadius*0.1)+nTriHeight*0.1,-m_outerRadius+nTriHeight);

  137. triangle[2]=QPoint(-m_outerRadius+nTriHeight,-(m_outerRadius*0.1)+nTriHeight*0.1);

  138. painter->drawPolygon(triangle,3);

  139. }

  140. painter->restore();

  141.  
  142. }

  143. //更新画面

  144. void NProgreSandClock::UpdateAngle()

  145. {

  146. if ((m_angle==45) )

  147. {

  148. m_nNowStatus=DRAW_UP_TRIANG;

  149. m_updateTimer->start(m_nSandDowSpeed);

  150. isDrawTri=true;

  151. }

  152. else if (m_angle==225)

  153. {

  154. m_nNowStatus=DRAW_DOWN_TRIANG;

  155. m_updateTimer->start(m_nSandDowSpeed);

  156. isDrawTri=true;

  157. }

  158. else

  159. {

  160. m_nNowStatus= DRAW_CIR_ROTETE;

  161. m_updateTimer->setInterval(m_nSandColorRoteSpeed);

  162. }

  163. if (!isDrawTri)

  164. {

  165. m_angle += 1;

  166. if(m_angle > 360)

  167. {

  168. m_angle = 0;

  169. }

  170. }

  171. //刷新控件,会调用paintEvent函数

  172. update();

  173. }

  174.  
  175. NProgreSandClock::~NProgreSandClock()

  176. {

  177. m_updateTimer->stop();

  178. }

  179. //设置是否循环

  180. void NProgreSandClock::setLoop(bool isLoop)

  181. {

  182. this->isLoop=isLoop;

  183. }

  184. //设置沙漏颜色

  185. void NProgreSandClock::setSandClockColor(QColor color)

  186. {

  187. this->m_sandClockColor= color;

  188. }

  189. //设置沙的颜色

  190. void NProgreSandClock::setSandColor(QColor color)

  191. {

  192. this->m_SandColor = color;

  193. }

  194. //设置沙下降的速度

  195. void NProgreSandClock::setSandDownSpeed(int mes)

  196. {

  197. this->m_nSandDowSpeed=mes;

  198. }

  199. //设置沙漏旋转的速度

  200. void NProgreSandClock::setSandClockRoteSpeed(int mes)

  201. {

  202. this->m_nSandColorRoteSpeed= mes;

  203. }

  204. //设置沙漏的宽度

  205. void NProgreSandClock::setSandClockWidth(int width)

  206. {

  207. this->m_nSandClockWidth=width;

  208. }

  209. //设置当前进度

  210. void NProgreSandClock::setSandClockProgre(int progre)

  211. {

  212. this->m_nNowProgres = progre;

  213. if (progre>100)

  214. {

  215. this->m_nNowProgres=100;

  216. }

  217. m_angle = 45;

  218. m_updateTimer->stop();

  219. isLoop = false;

  220. update();

  221. }

 

首先沙漏进度还是很简单的:那么再来看看水波进度:

 

 
  1. #ifndef NPROGRECIRWATER_H

  2. #define NPROGRECIRWATER_H

  3. #define WATER_HEIGHT 0.06

  4. #include <QWidget>

  5. #include <math.h>

  6. #include <QPainter>

  7. #include <QPixmap>

  8. #include <QTimer>

  9. #include <QFont>

  10. class NProgreCirWater : public QWidget

  11. {

  12. Q_OBJECT

  13.  
  14. public:

  15. NProgreCirWater(QWidget *parent);

  16. ~NProgreCirWater();

  17. void setWaterProgre(int progre);

  18. protected:

  19. void paintEvent(QPaintEvent *event);

  20. private:

  21. int m_nNowProgre;

  22. QTimer m_ChangeWaterTimer;

  23. float m_fPy;

  24. void createShader(QPainter &painter);

  25. QTimer m_TUpGuiimer;

  26. // 水波进度

  27. float DEFAULT_LEVEL_RATIO ;

  28. // 水波高度

  29. float DEFAULT_AMPLITUDE_RATIO ;

  30. private slots:

  31. //自动增加

  32. void upAutoTime();

  33. //让波浪动起来

  34. void upGuiOutTimer();

  35. };

  36.  
  37. #endif // NPROGRECIRWATER_H

 

再来看看实现代码CPP:

 

 
  1. #include "NProgreCirWater.h"

  2. #include "QTool.h"

  3. #define M_PI 3.14159265358979323846

  4. NProgreCirWater::NProgreCirWater(QWidget *parent)

  5. : QWidget(parent),m_fPy(0)

  6. {

  7. // 水波进度

  8. DEFAULT_LEVEL_RATIO = 1.0f;

  9. // 水波高度

  10. DEFAULT_AMPLITUDE_RATIO = 0;

  11. connect(&m_ChangeWaterTimer,SIGNAL(timeout()),this,SLOT(upAutoTime()));

  12. connect(&m_TUpGuiimer,SIGNAL(timeout()),this,SLOT(upGuiOutTimer()));

  13. m_TUpGuiimer.start(10);

  14. m_ChangeWaterTimer.start(90);

  15. }

  16.  
  17. NProgreCirWater::~NProgreCirWater()

  18. {

  19. }

  20. void NProgreCirWater::createShader(QPainter &painter) {

  21. painter.setRenderHints(QPainter::Antialiasing|QPainter::HighQualityAntialiasing);//设置反锯齿

  22. int height = this-> height();

  23. int width = this->width();

  24. // ω周期 让一个周期的宽度正好是width

  25. double frequency = 3 * M_PI / width;

  26. // A振幅 默认的振幅是高度的0.05f

  27. float amplitude = height * DEFAULT_AMPLITUDE_RATIO;

  28. // k(y轴偏移量,进度) 默认的进度是50%

  29. float level = height * DEFAULT_LEVEL_RATIO;

  30. QPixmap waveBitmap (width,height);

  31. QPainter drawWaterPainter(&waveBitmap);

  32. drawWaterPainter.setPen(Qt::NoPen);

  33. drawWaterPainter.setBrush(Qt::red);

  34. QPainterPath abovePath ;

  35. QPainterPath behindPath ;

  36. abovePath.moveTo(0, height);

  37. behindPath.moveTo(0, height);

  38. m_fPy+=0.05;

  39. if (m_fPy>(width/2))

  40. {

  41. m_fPy = 0;

  42. }

  43. for(int x = 0; x<=width; x++) {

  44. // y=Asin(ωx+φ)+k

  45. float aboveY = (float) (amplitude * sin(frequency * x+m_fPy))+ level;

  46. // 背面的水波偏移一些,和前面的错开。

  47. float behindY = (float) (amplitude * sin(frequency * x+width/4*frequency+m_fPy ))+ level;

  48. abovePath.lineTo(x , aboveY);

  49. behindPath.lineTo(x, behindY);

  50. }

  51. abovePath.lineTo(width+ 1, height);

  52. behindPath.lineTo(width+1, height);

  53. drawWaterPainter.setBrush(QColor(169,245,233,255));

  54. drawWaterPainter.drawPath(behindPath);

  55. drawWaterPainter.setBrush(QColor(40,230,200,255));

  56. drawWaterPainter.drawPath(abovePath);

  57. int nFontSize = width/6;

  58. QFont font;

  59. font.setPixelSize(nFontSize);

  60. drawWaterPainter.setFont(font);

  61. drawWaterPainter.setPen(QPen(Qt::white));

  62. int nNowPro =100 - (int)(DEFAULT_LEVEL_RATIO*100);

  63. QString strProgre = QString::number(nNowPro);

  64. strProgre.append("%");

  65. drawWaterPainter.drawText(width/2-(nFontSize/2-2),height/2+nFontSize/2,strProgre);

  66. drawWaterPainter.end();

  67. waveBitmap=QTool::QPixmapToRound(waveBitmap,(float)100);

  68. painter.drawPixmap(0,0,waveBitmap);

  69. }

  70. //重绘事件

  71. void NProgreCirWater::paintEvent(QPaintEvent *event)

  72. {

  73. QPainter painter(this);

  74. createShader(painter);

  75. QWidget::paintEvent(event);

  76. }

  77. void NProgreCirWater::upGuiOutTimer()

  78. {

  79. update();

  80. }

  81. void NProgreCirWater::upAutoTime()

  82. {

  83. // 水波高度

  84. if (DEFAULT_LEVEL_RATIO<=0)

  85. {

  86. DEFAULT_LEVEL_RATIO=1;

  87. DEFAULT_AMPLITUDE_RATIO=0;

  88. }

  89. DEFAULT_LEVEL_RATIO-=0.01;

  90.  
  91. DEFAULT_AMPLITUDE_RATIO= (1-DEFAULT_LEVEL_RATIO) * 0.15;

  92. if (DEFAULT_AMPLITUDE_RATIO>WATER_HEIGHT)

  93. {

  94. DEFAULT_AMPLITUDE_RATIO =WATER_HEIGHT;

  95. }

  96. }

  97.  
  98. void NProgreCirWater::setWaterProgre(int progre)

  99. {

  100. this->m_nNowProgre = progre;

  101. m_ChangeWaterTimer.stop();

  102. DEFAULT_LEVEL_RATIO =1.0 - ((float)this->m_nNowProgre) /100.0;

  103. DEFAULT_AMPLITUDE_RATIO= (1-DEFAULT_LEVEL_RATIO) * 0.15;

  104. if (DEFAULT_AMPLITUDE_RATIO>WATER_HEIGHT)

  105. {

  106. DEFAULT_AMPLITUDE_RATIO =WATER_HEIGHT;

  107. }

  108. update();

  109. }

下面是调用代码:

 
  1. resize(800,800);

  2. NImageButton *pNImageButton = new NImageButton(this);

  3. pNImageButton->setGeometry(10,10,120,35);

  4. pNImageButton->setMinimumSize(120,35);

  5. QPixmap pp("Image/button.png");

  6. QPixmap ppc("Image/button1.png");

  7. pNImageButton->setNormalImage(pp);

  8. pNImageButton->setPressImage(ppc);

  9. pNImageButton->setImageArc(10);

  10.  
  11. NProgreCirWater *pNCirProgreWater=new NProgreCirWater(this);

  12. pNCirProgreWater->setWaterProgre(35);

  13. pNCirProgreWater->setGeometry(110,10,200,200);

  14. pNCirProgreWater->setMinimumSize(200,200);

  15.  
  16. NProgreCirWater *pNCirProgreWater1=new NProgreCirWater(this);

  17. //pNCirProgreWater1->setWaterProgre(35);

  18. pNCirProgreWater1->setGeometry(330,10,200,200);

  19. pNCirProgreWater1->setMinimumSize(200,200);

  20.  
  21. NProgreSandClock * pCirProgreWater=new NProgreSandClock(this);

  22. pCirProgreWater->setSandDownSpeed(10);

  23. pCirProgreWater->setSandClockProgre(35);

  24. pCirProgreWater->setSandColor(QColor(Qt::red));

  25. pCirProgreWater->setGeometry(110,220,200,100);

  26. pCirProgreWater->setMinimumSize(200,200);

  27.  
  28. NProgreSandClock * pCirProgreWater1=new NProgreSandClock(this);

  29. pCirProgreWater1->setSandDownSpeed(10);

  30. // pCirProgreWater1->setSandClockProgre(35);

  31. pCirProgreWater1->setSandColor(QColor(Qt::red));

  32. pCirProgreWater1->setGeometry(330,220,100,100);

  33. pCirProgreWater1->setMinimumSize(200,200);

 

好了还是那句老话,学如逆水行舟不进则退。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值