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

来源:互联网 发布:结构的刚度矩阵 编辑:程序博客网 时间:2024/06/04 18:16

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

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

心动吗?我们一起来看看。
首先是沙漏进度代码:

[cpp] view plain copy
  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:
[cpp] view plain copy
  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. }  

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

[cpp] view plain copy
  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:

[cpp] view plain copy
  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. }  
下面是调用代码:
[cpp] view plain copy
  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);  
原创粉丝点击