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

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

话不多说来张图片大家就知道了:
心动吗?我们一起来看看。
首先是沙漏进度代码:
#ifndef NPROGRESANDCLOCK_H
#define NPROGRESANDCLOCK_H

#include <QWidget>
#include <QTimer> 
#include <QRect>
#include <QPainter>
#include <QPaintEvent>
#include <QSize>
class NProgreSandClock : public QWidget
{
	Q_OBJECT
public:
	NProgreSandClock(QWidget *parent);
	//设置沙漏外壁的宽
	void setSandClockWidth(int width);
	//设置是否循环旋转
	void setLoop(bool isLoop);
	//设置沙漏外边的颜色
	void setSandClockColor(QColor color);
	//设置沙的颜色
	void setSandColor(QColor color);
	//设置沙漏下去速度(毫秒)
	void setSandDownSpeed(int mes);
	//设置沙漏旋转的速度(毫秒)
	void setSandClockRoteSpeed(int mes);
	//设置当前进度
	void setSandClockProgre(int progre);
	~NProgreSandClock();
protected:
	//重绘事件
	void paintEvent(QPaintEvent *); 
private:
	int m_nNowProgres;
	//设置沙漏外壁的宽
	int m_nSandClockWidth;
	//沙漏旋转的速度
	int m_nSandColorRoteSpeed;
	//设置沙落下的速度
	int m_nSandDowSpeed;
	//沙的颜色
	QColor m_SandColor;
	//沙漏颜色
	QColor  m_sandClockColor;
	//画沙漏
	void drawSandClock(QPainter* painter);
	bool isLoop;
	//旋转沙漏定时器
	QTimer* m_updateTimer;//定时器时间
	bool isFirstRotate;
	//旋转角度
	qreal   m_angle;    
	//外半径
	qreal   m_outerRadius;
	//记录现在的状态
	int m_nNowStatus;
	//是否在画三角形
	bool isDrawTri;
	//记录三角形的高
	qreal triHeight;
	//现在的状态
	enum
	{
		DRAW_UP_TRIANG=0,DRAW_DOWN_TRIANG,DRAW_CIR_ROTETE
	};
signals:
	void onProgres(int);
private slots:
	//自定义槽,更新角度旋转
	void UpdateAngle(); 
};

#endif // NPROGRESANDCLOCK_H
沙漏进度CPP:
#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();
}
首先沙漏进度还是很简单的:那么再来看看水波进度:
#ifndef NPROGRECIRWATER_H
#define NPROGRECIRWATER_H
#define  WATER_HEIGHT 0.06
#include <QWidget>
#include <math.h>
#include <QPainter>
#include <QPixmap>
#include <QTimer>
#include <QFont>
class NProgreCirWater : public QWidget
{
	Q_OBJECT

public:
	NProgreCirWater(QWidget *parent);
	~NProgreCirWater();
	void setWaterProgre(int progre);
protected:
	void paintEvent(QPaintEvent *event);
private: 
	int m_nNowProgre;
	QTimer m_ChangeWaterTimer;
	float m_fPy; 
	void createShader(QPainter &painter); 
	QTimer m_TUpGuiimer;
	// 水波进度
	float DEFAULT_LEVEL_RATIO ; 
	// 水波高度
	float DEFAULT_AMPLITUDE_RATIO ;   
private slots:
	//自动增加
	void  upAutoTime();
	//让波浪动起来
	void upGuiOutTimer();
};

#endif // NPROGRECIRWATER_H
再来看看实现代码CPP:
#include "NProgreCirWater.h"
#include "QTool.h"
#define M_PI 3.14159265358979323846
NProgreCirWater::NProgreCirWater(QWidget *parent)
: QWidget(parent),m_fPy(0)
{
	// 水波进度
	DEFAULT_LEVEL_RATIO = 1.0f; 
	// 水波高度
	DEFAULT_AMPLITUDE_RATIO = 0;   
	connect(&m_ChangeWaterTimer,SIGNAL(timeout()),this,SLOT(upAutoTime()));
	connect(&m_TUpGuiimer,SIGNAL(timeout()),this,SLOT(upGuiOutTimer()));
	m_TUpGuiimer.start(10);
	m_ChangeWaterTimer.start(90);
}

NProgreCirWater::~NProgreCirWater()
{
}
void NProgreCirWater::createShader(QPainter &painter) {
		painter.setRenderHints(QPainter::Antialiasing|QPainter::HighQualityAntialiasing);//设置反锯齿
	int height = this-> height();
	int width = this->width();
	// ω周期  让一个周期的宽度正好是width
	double frequency = 3 * M_PI / width;
	// A振幅  默认的振幅是高度的0.05f
	float amplitude = height * DEFAULT_AMPLITUDE_RATIO;
	// k(y轴偏移量,进度) 默认的进度是50%
	float level = height * DEFAULT_LEVEL_RATIO;
	QPixmap waveBitmap (width,height);
	QPainter drawWaterPainter(&waveBitmap);
	drawWaterPainter.setPen(Qt::NoPen);
	drawWaterPainter.setBrush(Qt::red);
	QPainterPath abovePath ;
	QPainterPath behindPath ;
	abovePath.moveTo(0, height);
	behindPath.moveTo(0, height);
	m_fPy+=0.05;
	if (m_fPy>(width/2))
	{
		m_fPy = 0;
	}
	for(int x = 0; x<=width; x++) {
		// y=Asin(ωx+φ)+k
		float aboveY = (float) (amplitude * sin(frequency * x+m_fPy))+ level;
		// 背面的水波偏移一些,和前面的错开。
		float behindY = (float) (amplitude * sin(frequency * x+width/4*frequency+m_fPy ))+ level;
		abovePath.lineTo(x , aboveY);
		behindPath.lineTo(x, behindY);
	}
	abovePath.lineTo(width+ 1, height);
	behindPath.lineTo(width+1, height);
	drawWaterPainter.setBrush(QColor(169,245,233,255));
	drawWaterPainter.drawPath(behindPath);
	drawWaterPainter.setBrush(QColor(40,230,200,255));
	drawWaterPainter.drawPath(abovePath); 
	int nFontSize = width/6;
	QFont font;
	font.setPixelSize(nFontSize);
	drawWaterPainter.setFont(font);
	drawWaterPainter.setPen(QPen(Qt::white));
	int nNowPro =100 - (int)(DEFAULT_LEVEL_RATIO*100);
	QString strProgre = QString::number(nNowPro);
	strProgre.append("%");
	drawWaterPainter.drawText(width/2-(nFontSize/2-2),height/2+nFontSize/2,strProgre);
	drawWaterPainter.end();
	waveBitmap=QTool::QPixmapToRound(waveBitmap,(float)100); 
	painter.drawPixmap(0,0,waveBitmap); 
}
//重绘事件
void NProgreCirWater::paintEvent(QPaintEvent *event)
{ 
	QPainter painter(this);
	createShader(painter);  
	QWidget::paintEvent(event);
}
void NProgreCirWater::upGuiOutTimer()
{
	update();
}
void NProgreCirWater::upAutoTime()
{
	// 水波高度
	if (DEFAULT_LEVEL_RATIO<=0)
	{
		DEFAULT_LEVEL_RATIO=1;
		DEFAULT_AMPLITUDE_RATIO=0;
	}
	DEFAULT_LEVEL_RATIO-=0.01;

	DEFAULT_AMPLITUDE_RATIO=  (1-DEFAULT_LEVEL_RATIO) * 0.15;
	if (DEFAULT_AMPLITUDE_RATIO>WATER_HEIGHT)
	{ 
		DEFAULT_AMPLITUDE_RATIO =WATER_HEIGHT;
	}
}

void NProgreCirWater::setWaterProgre(int progre)
{
	this->m_nNowProgre = progre;
	m_ChangeWaterTimer.stop();
	DEFAULT_LEVEL_RATIO =1.0 - ((float)this->m_nNowProgre) /100.0;
	DEFAULT_AMPLITUDE_RATIO=  (1-DEFAULT_LEVEL_RATIO) * 0.15;
	if (DEFAULT_AMPLITUDE_RATIO>WATER_HEIGHT)
	{ 
		DEFAULT_AMPLITUDE_RATIO =WATER_HEIGHT;
	}
	update();
}
下面是调用代码:
	resize(800,800); 
	NImageButton *pNImageButton = new NImageButton(this);
	pNImageButton->setGeometry(10,10,120,35); 
	pNImageButton->setMinimumSize(120,35);
	QPixmap pp("Image/button.png");
	QPixmap ppc("Image/button1.png");
	pNImageButton->setNormalImage(pp);
	pNImageButton->setPressImage(ppc); 
	pNImageButton->setImageArc(10); 

	NProgreCirWater *pNCirProgreWater=new NProgreCirWater(this);
	pNCirProgreWater->setWaterProgre(35);
	pNCirProgreWater->setGeometry(110,10,200,200);
	pNCirProgreWater->setMinimumSize(200,200);

	NProgreCirWater *pNCirProgreWater1=new NProgreCirWater(this);
	//pNCirProgreWater1->setWaterProgre(35);
	pNCirProgreWater1->setGeometry(330,10,200,200);
	pNCirProgreWater1->setMinimumSize(200,200);

	NProgreSandClock * pCirProgreWater=new NProgreSandClock(this);
	pCirProgreWater->setSandDownSpeed(10);
	pCirProgreWater->setSandClockProgre(35);
	pCirProgreWater->setSandColor(QColor(Qt::red));
	pCirProgreWater->setGeometry(110,220,200,100);
	pCirProgreWater->setMinimumSize(200,200);

	NProgreSandClock * pCirProgreWater1=new NProgreSandClock(this);
	pCirProgreWater1->setSandDownSpeed(10);
//	pCirProgreWater1->setSandClockProgre(35);
	pCirProgreWater1->setSandColor(QColor(Qt::red));
	pCirProgreWater1->setGeometry(330,220,100,100);
	pCirProgreWater1->setMinimumSize(200,200);
好了还是那句老话,学如逆水行舟不进则退。
 
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一路随云00000

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值