Qt沙漏進度和水波進度釋出(重寫Qwidget實現)
阿新 • • 發佈:2019-01-31
#include "NProgreSandClock.h" NProgreSandClock::NProgreSandClock(QWidget *parent) : QWidget(parent) ,m_nNowStatus(2) ,isLoop(true), m_angle(0), m_outerRadius(0), isDrawTri(false) ,m_sandClockColor(QColor(63,107,157,255)) ,m_SandColor(QColor(224,143,36,255)) ,m_nSandDowSpeed(5) ,m_nSandColorRoteSpeed(2) ,m_nSandClockWidth(4) { //無窗體 setWindowFlags(Qt::FramelessWindowHint); //背景透明 setAttribute(Qt::WA_TranslucentBackground); m_updateTimer = new QTimer(this); //間隔,微妙微單位,大家可以改一下這個值看看轉動速度。 m_updateTimer->setInterval(m_nSandColorRoteSpeed); connect(m_updateTimer,SIGNAL(timeout()),this,SLOT(UpdateAngle())); //啟動定時器 m_updateTimer->start(); } //重繪事件 void NProgreSandClock::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing|QPainter::HighQualityAntialiasing);//設定反鋸齒 drawSandClock(&painter);//畫沙漏 } //畫沙漏和三角形 void NProgreSandClock::drawSandClock(QPainter *painter) { m_outerRadius = width() > height() ? (qreal)height()/2 : (qreal)width()/2; if (m_nNowStatus== DRAW_CIR_ROTETE) { triHeight=m_outerRadius; } painter->save(); // move to center painter->translate(m_outerRadius,m_outerRadius); painter->setPen(QPen(m_sandClockColor,m_nSandClockWidth,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin)); //旋轉 painter->rotate(m_angle); QRect widgetRect =this->rect(); QPainterPath sandClockPath; sandClockPath.moveTo(-m_outerRadius*0.05,m_outerRadius*0.05); sandClockPath.lineTo(m_outerRadius*0.1,m_outerRadius); sandClockPath.lineTo(m_outerRadius,m_outerRadius*0.1); sandClockPath.lineTo(m_outerRadius*0.05,-m_outerRadius*0.05); sandClockPath.lineTo(-m_outerRadius*0.1,-m_outerRadius); sandClockPath.lineTo(-m_outerRadius,-m_outerRadius*0.1); sandClockPath.lineTo(-m_outerRadius*0.05,m_outerRadius*0.05); painter->drawPath(sandClockPath); painter->setPen(Qt::NoPen); if (isLoop) { emit onProgres(-1); QPoint triangle[3]; painter->setBrush(QBrush(m_SandColor,Qt::SolidPattern));//設定畫刷形式 if (m_nNowStatus==DRAW_UP_TRIANG) { if (isDrawTri) { triangle[0]=QPoint(0,0); triangle[1]=QPoint(-triHeight*0.1,-triHeight); triangle[2]=QPoint(-triHeight,-triHeight*0.1); triHeight-=1; painter->drawPolygon(triangle,3); triangle[0]=QPoint(0,0); triangle[1]=QPoint((m_outerRadius*0.1)-triHeight*0.1,m_outerRadius-triHeight); triangle[2]=QPoint(m_outerRadius-triHeight,(m_outerRadius*0.1)-triHeight*0.1); if (triHeight<0) { isDrawTri=false; triHeight=m_outerRadius; m_nNowStatus= DRAW_CIR_ROTETE; m_angle+=1; } painter->drawPolygon(triangle,3); } } else if(m_nNowStatus==DRAW_DOWN_TRIANG) { if (isDrawTri) { triangle[0]=QPoint(0,0); triangle[1]=QPoint(triHeight*0.1,triHeight); triangle[2]=QPoint(triHeight,triHeight*0.1); triHeight-=1; painter->drawPolygon(triangle,3); triangle[0]=QPoint(0,0); triangle[1]=QPoint(-(m_outerRadius*0.1)+triHeight*0.1,-m_outerRadius+triHeight); triangle[2]=QPoint(-m_outerRadius+triHeight,-(m_outerRadius*0.1)+triHeight*0.1); if (triHeight<=0) { isDrawTri=false; triHeight=m_outerRadius; m_nNowStatus= DRAW_CIR_ROTETE; m_angle+=1; } painter->drawPolygon(triangle,3); } } else { if(m_angle>45&&m_angle<=225) { triangle[0]=QPoint(0,0); triangle[1]=QPoint(m_outerRadius*0.1-m_nSandClockWidth/3,m_outerRadius-m_nSandClockWidth/3); triangle[2]=QPoint(m_outerRadius-m_nSandClockWidth/3,m_outerRadius*0.1-m_nSandClockWidth/3); } else { triangle[0]=QPoint(0,0); triangle[1]=QPoint(-m_outerRadius*0.1+m_nSandClockWidth/3,-m_outerRadius+m_nSandClockWidth/3); triangle[2]=QPoint(-m_outerRadius+m_nSandClockWidth/3,-m_outerRadius*0.1+m_nSandClockWidth/3); } painter->drawPolygon(triangle,3); } } else { qreal nTriHeight=((float)(m_nNowProgres/100.0)*triHeight); emit onProgres(m_nNowProgres); painter->setBrush(QBrush(m_SandColor,Qt::SolidPattern));//設定畫刷形式 QPoint triangle[3]; triangle[0]=QPoint(0,0); triangle[1]=QPoint(nTriHeight*0.1,nTriHeight); triangle[2]=QPoint(nTriHeight,nTriHeight*0.1); painter->drawPolygon(triangle,3); triangle[0]=QPoint(0,0); triangle[1]=QPoint(-(m_outerRadius*0.1)+nTriHeight*0.1,-m_outerRadius+nTriHeight); triangle[2]=QPoint(-m_outerRadius+nTriHeight,-(m_outerRadius*0.1)+nTriHeight*0.1); painter->drawPolygon(triangle,3); } painter->restore(); } //更新畫面 void NProgreSandClock::UpdateAngle() { if ((m_angle==45) ) { m_nNowStatus=DRAW_UP_TRIANG; m_updateTimer->start(m_nSandDowSpeed); isDrawTri=true; } else if (m_angle==225) { m_nNowStatus=DRAW_DOWN_TRIANG; m_updateTimer->start(m_nSandDowSpeed); isDrawTri=true; } else { m_nNowStatus= DRAW_CIR_ROTETE; m_updateTimer->setInterval(m_nSandColorRoteSpeed); } if (!isDrawTri) { m_angle += 1; if(m_angle > 360) { m_angle = 0; } } //重新整理控制元件,會呼叫paintEvent函式 update(); } NProgreSandClock::~NProgreSandClock() { m_updateTimer->stop(); } //設定是否迴圈 void NProgreSandClock::setLoop(bool isLoop) { this->isLoop=isLoop; } //設定沙漏顏色 void NProgreSandClock::setSandClockColor(QColor color) { this->m_sandClockColor= color; } //設定沙的顏色 void NProgreSandClock::setSandColor(QColor color) { this->m_SandColor = color; } //設定沙下降的速度 void NProgreSandClock::setSandDownSpeed(int mes) { this->m_nSandDowSpeed=mes; } //設定沙漏旋轉的速度 void NProgreSandClock::setSandClockRoteSpeed(int mes) { this->m_nSandColorRoteSpeed= mes; } //設定沙漏的寬度 void NProgreSandClock::setSandClockWidth(int width) { this->m_nSandClockWidth=width; } //設定當前進度 void NProgreSandClock::setSandClockProgre(int progre) { this->m_nNowProgres = progre; if (progre>100) { this->m_nNowProgres=100; } m_angle = 45; m_updateTimer->stop(); isLoop = false; update(); }