1. 程式人生 > >Qt沙漏進度和水波進度釋出(重寫Qwidget實現)

Qt沙漏進度和水波進度釋出(重寫Qwidget實現)

#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();
}