Qt中實現漸變更畫效果

上效果圖

  

一:思路

  (1).利用QTimer不斷的去更新漸變值。app

  

二:代碼實現

testwindow.hless

#ifndef BOXINGBoxingMainWindow_H
#define BOXINGBoxingMainWindow_H

#include "boxingcircle.h"
#include "boxingrectangle.h"
#include "communicate\communicatethreadcontroller.h"

#include <QtGui/QApplication>
#include <QtGui/QWidget>
#include <QtGui/QPainter>
#include <QtCore/QTimer>
#include <QtCore/QTime>
#include <QtGui/QShortcut>
#include <QtCore/QList>

class testwindow: public QWidget
{
	Q_OBJECT

public:

	testwindow(QWidget *pParent = 0);

	~testwindow();	

	void Initialize();

public slots:

	void DoTimerEvent();	

	void Test(int pIndex);

	void DoHostConnected();

	void DoHostDisconnected();

protected:

	virtual void paintEvent(QPaintEvent *);

	void DrawCircle(QPainter *pPainter,QPointF pPointF, double pDiameter, int pArrayIndex, QString pText);

	void DrawRectangle(QPainter *pPainter, QPointF pPointF, double pWidth, double pHight);

	QRect GetRect(int pX, int pY, int pWidth, int pHight);

	/*!
		漸變更畫
	*/
	void Tweening(QPainter *pPainter);

	void DrawRightText(QPainter *pPainter);

private:

	BaseShape *mBaseShapeArray[8];
	/*!
		mBaseShapeArray的索引
	*/
	int		 mArrayIndex;

	int		 mDrawTime;

	QTimer	 *mTimer;

	QTimer	 *mDispearTime;

	QTimer	 *mTestTimer;

	bool	 mStarted; 
	
};
#endif //BOXINGBoxingMainWindow_H

testwindow.cppide

#include "testwindow.h"
#include <QtCore/QTime>
#include <QtCore/QDebug>
#include <QtGui/QSound>

#define TIME_INTERVAL 20
#define ARRAY_MAX_INDEX 8
#define DISAPPEAR_TIME_INTERVAL 3000

testwindow::testwindow(QWidget *pParent) :
	 QWidget(pParent)
{
	Initialize();
}

testwindow::~testwindow()
{
	for (int i = 0; i < 4; i++) {
		delete mBaseShapeArray[i];
	}
	delete mBaseShapeArray[4];
	for (int i = 5; i < ARRAY_MAX_INDEX; i++) {
		delete mBaseShapeArray[i];
	}

	if(mTimer) {
		delete mTimer;
		mTimer = NULL;
	}

	if (mTime) {
		delete mTime;
		mTime = NULL;
	}

	if (mDispearTime) {
		delete mDispearTime;
		mDispearTime = NULL;
	}

	if (mF3_Shortcut) {
		delete mF3_Shortcut;
		mF3_Shortcut = NULL;
	}
}

void testwindow::Initialize()
{
	mDrawTime		= 0;
	mCurrentEffort  = 0;
	mMaxEffort		= 0;
	mTime			= NULL;
	mDispearTime    = NULL;
	mF3_Shortcut = new QShortcut(Qt::Key_F3, this, 0, 0, Qt::ApplicationShortcut);
	connect(mF3_Shortcut, SIGNAL(activated()), this, SLOT(OnClearScore()));
	QPalette palette;
	palette.setBrush(this->backgroundRole(),QBrush(Qt::black));
	this->setPalette(palette);
	//隱藏鼠標
	//QApplication::setOverrideCursor(Qt::BlankCursor);
	this->resize(320, 192);
	//設置無邊框
	//setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
	this->setGeometry(0, 0, 320, 192);
	for (int i = 0; i < 4; i++) {	
		mBaseShapeArray[i]  = new BoxingCircle;
	}
	mBaseShapeArray[4] = new BoxingRectangle;

	for (int i = 5; i < ARRAY_MAX_INDEX; i++) {
		mBaseShapeArray[i] = new BoxingCircle;
	}
	
	mArrayIndex = -1;
	mStarted	= false;
	/*QTimer::singleShot(200,this, SLOT(Test()));*/
	mTimer = new QTimer(this);
	connect(mTimer, SIGNAL(timeout()), this, SLOT(DoTimerEvent()));
	mTimer->start(TIME_INTERVAL);

	mCommunicateThreadController = CommunicateThreadController::GetInstance();
	connect(mCommunicateThreadController, SIGNAL(OnHostConnected()), this, SLOT(DoHostConnected()));
	connect(mCommunicateThreadController, SIGNAL(OnHostDisconnected()), this, SLOT(DoHostDisconnected()));
	connect(mCommunicateThreadController, SIGNAL(OnBuffetCommandReceived(int, int, int)), this, SLOT(DoBuffetCommandReceived(int, int, int)));

	/*mTestTimer = new QTimer(this);
	connect(mTestTimer, SIGNAL(timeout()), this, SLOT(Test(int)));
	mTestTimer->start(100);*/

}

void testwindow::DoTimerEvent()
{
	if (! mStarted) {
		return;
	}
	if (mArrayIndex < 0 || mArrayIndex >= ARRAY_MAX_INDEX) {
		return;
	}
	if (mDrawTime -= 1) {
		update();
	}
	else {
		mDrawTime = 0;
		mStarted = false;
	}
}

void testwindow::paintEvent(QPaintEvent *pPaint)
{
	int originwidth = this->width();
	int originhight = this->height();
	int linewidth   = originhight * 0.015;
	int fontsize    = originhight * 0.05;
	//上柱點位置
	double pillarpositionx = originwidth * 0.35;
	double pillarpositiony = originhight * 0.30;
	//底盤
	QPainter painter(this);
	QPointF chassispointf(originwidth * 0.28 + originwidth * 0.07,  originhight * 0.93);
	QLinearGradient linearGradient(chassispointf.x(), chassispointf.y() - originhight * 2 * 0.05,chassispointf.x(),  chassispointf.y() + originhight * 2 * 0.05);
	linearGradient.setColorAt(0.5, Qt::darkGray);
	linearGradient.setColorAt(1.0, Qt::black);
	painter.setBrush(QBrush(linearGradient));
	painter.drawEllipse(originwidth * 0.28, originhight * 0.90, originwidth * 2 * 0.07, originhight * 2 * 0.05);

	//中間粗線
	QPainter linepainter(this);
	linepainter.setPen(QPen(Qt::gray, linewidth * 4, Qt::SolidLine));
	linepainter.drawLine(pillarpositionx, pillarpositiony, chassispointf.x(), chassispointf.y());

	//下左邊斜線
	linepainter.setPen(QPen(Qt::gray, linewidth * 2, Qt::SolidLine));
	QPointF underleftslashpos(originwidth * 0.23, originhight * 0.78);
	linepainter.drawLine(underleftslashpos.x(), underleftslashpos.y(), pillarpositionx, originhight * 0.55 + originhight * 0.25 * 0.5);
	//下右邊斜線
	QPointF toprightslashpos((pillarpositionx - originwidth * 0.23) * 2 + originwidth * 0.23, originhight * 0.78);
	linepainter.drawLine(toprightslashpos.x(), toprightslashpos.y(), pillarpositionx, originhight * 0.55 + originhight * 0.25 * 0.5);
	//開始畫上面的鏈接處 從左到右 1 
	QPointF top1pos(originwidth * 0.23, originhight * 0.25);
	linepainter.drawLine(top1pos.x(), top1pos.y(), pillarpositionx, pillarpositiony);
	//								 4
	QPointF top4pos(originwidth * 0.23 + (pillarpositionx - originwidth * 0.23) * 2,  originhight * 0.25);
	linepainter.drawLine(top4pos.x(), top4pos.y(), pillarpositionx, pillarpositiony);
	//								 2
	QPointF top2pos(originwidth * 0.30, originhight * 0.12);
	linepainter.drawLine(top2pos.x(), top2pos.y(), pillarpositionx, pillarpositiony);
	//								 3
	QPointF top3pos(originwidth * 0.30 + ( originwidth * 0.20 + originwidth * 0.15 - originwidth * 0.30) * 2, originhight * 0.12);
	linepainter.drawLine(top3pos.x(), top3pos.y(), pillarpositionx, pillarpositiony);

	double smalldiameter = originhight * 0.15;
	double smallradius = smalldiameter * 0.5;
	double largecenterdiameter = originhight * 0.25;

	QPainter shapepainter(this);
	shapepainter.setPen(QPen(Qt::gray, 1, Qt::SolidLine)); 
	shapepainter.setBrush(QBrush(Qt::black));
	//中間圓角長方形
	QPointF pointf01(pillarpositionx - originwidth * 0.06, pillarpositiony - originhight * 0.05);
	DrawRectangle(&shapepainter, pointf01, originwidth * 0.12, originhight * 0.25);
	
	Tweening(&shapepainter);
}

void testwindow::DrawCircle(QPainter *pPainter,QPointF pPointF, double pDiameter, int pArrayIndex, QString pText)
{
	int fontsize = this->height() * 0.05;
	QPointF pointf(pPointF.x() - pDiameter * 0.5, pPointF.y() - pDiameter * 0.5);
	pPainter->setPen(QPen(Qt::gray, 1, Qt::SolidLine)); 
	pPainter->setBrush(QBrush(Qt::black));
	mBaseShapeArray[pArrayIndex]->PaintShape(pPainter,pointf, pDiameter, pDiameter);
	pPainter->setPen(QPen(Qt::white, 1, Qt::SolidLine));
	//中間大圓 字體要大一點
	if (pText == "12") {
		pPainter->setFont(QFont("Times", fontsize * 1.5));	
	}
	else {
		pPainter->setFont(QFont("Times", fontsize));	
	}
	mBaseShapeArray[pArrayIndex]->DrawTextNumber(pPainter, GetRect(pointf.x(), pointf.y(), pDiameter, pDiameter), pText);
}

void testwindow::DrawRectangle(QPainter *pPainter, QPointF pPointF, double pWidth, double pHight)
{
	pPainter->setPen(QPen(Qt::gray, 1, Qt::SolidLine));
	pPainter->setBrush(Qt::black);
	mBaseShapeArray[4]->PaintShape(pPainter,pPointF, pWidth, pHight);
}

QRect testwindow::GetRect(int pX, int pY, int pWidth, int pHight)
{
	QRect rect(pX, pY, pWidth, pHight);
	return rect;
}

void testwindow::Tweening(QPainter *pPainter)
{
	if (mArrayIndex < 0 || mStarted == false) {
		mDrawTime = 0;
		mStarted = false;
		return;
	}
	BaseShape * baseshape = mBaseShapeArray[mArrayIndex];
	if (baseshape == NULL) {
		mDrawTime = 0;
		//mArrayIndex = -1;
		mStarted = false;
		return;
	}
	QPointF pointf  = baseshape->GetPointF();
	double diameter = 0;
	double xaxis    = 0;
	double yaxis    = 0;
	int fontsize	= this->height() * 0.05;
	QString text	= mBaseShapeArray[mArrayIndex]->GetText();
	QLinearGradient linearGradient;
	int darkred = 102;
	if (mTime != NULL && mTime->elapsed() < 500) {
		linearGradient.setColorAt(0.0,QColor(darkred, 0, 0));
	}
	else {
		if (mTime) {
			delete mTime;
			mTime = NULL;
		}
		for (int i = 0; i < darkred / 4; i++) {
			if ( mBaseShapeArray[mArrayIndex]->GetDarkRed() < 4) {
				 mBaseShapeArray[mArrayIndex]->SetDarkRed(4);
			}
			int tempcolor = mBaseShapeArray[mArrayIndex]->GetDarkRed() - 4;
			linearGradient.setColorAt(0.0,QColor(tempcolor, 0, 0));
			mBaseShapeArray[mArrayIndex]->SetDarkRed(tempcolor);
			break;
		}
	}
	
	//圓角矩形
	if (4 == mArrayIndex) {
		xaxis = baseshape->GetWidth();
		yaxis = baseshape->GetHight();
	}
	else {
		 diameter = baseshape->GetDiameter();
		 xaxis = yaxis = diameter;
	}
	linearGradient.setStart(pointf.x(), pointf.y());
	linearGradient.setFinalStop(pointf.x() + xaxis, pointf.y() + yaxis);
	pPainter->setBrush(linearGradient);
	//圓角矩形
	if (4 != mArrayIndex) {
		pPainter->drawEllipse(pointf.x(), pointf.y(), diameter, diameter);
	}
	else {
		QRectF rectf(pointf.x(), pointf.y(), xaxis, yaxis);
		pPainter->drawRoundedRect(rectf, xaxis * 0.1, yaxis * 0.1);
	}
	pPainter->setPen(QPen(Qt::white, 1, Qt::SolidLine));
	//7號圓字體 大一點
	if (7 == mArrayIndex) {
		pPainter->setFont(QFont("times", fontsize * 1.5));
	}
	else {
		pPainter->setFont(QFont("times", fontsize));
	}
	mBaseShapeArray[mArrayIndex]->DrawTextNumber(pPainter, GetRect(pointf.x(), pointf.y(), diameter, diameter),text);
	if ( mBaseShapeArray[mArrayIndex]->GetDarkRed() <= 0) {
		mBaseShapeArray[mArrayIndex]->SetDarkRed(102);
		mDrawTime = 0;
		//mArrayIndex = -1;
		mStarted  = false;
	}
}

void testwindow::OnClearScore()
{
	mCurrentEffort = 0;
	mMaxEffort	   = 0;
	mEffortsList.clear();
	update();
}

void testwindow::Test(int pIndex)
{
	mDrawTime   = 40;
	mStarted    = true;
	mArrayIndex = pIndex;
	mCurrentEffort = pIndex * 10 + 1;
	mEffortsList.append(mCurrentEffort);
	if (mMaxEffort < mCurrentEffort) {
		mMaxEffort = mCurrentEffort;
	}
	if (mArrayIndexlist.contains(pIndex)) {
		mBaseShapeArray[pIndex]->SetDarkRed(102);
		mBaseShapeArray[pIndex]->SetStart(true);
	}
	else {
		mArrayIndexlist.append(pIndex);
		mBaseShapeArray[pIndex]->SetStart(true);
	}
	if (mTime) {
		delete mTime;
		mTime = NULL;
	}
	QSound::play("hit.wav");
	mTime = new QTime;
	mTime->start();
	if (mDispearTime) {
		delete mDispearTime;
		mDispearTime = NULL;
	}
	mDispearTime = new QTimer(this);
	mDispearTime->setInterval(DISAPPEAR_TIME_INTERVAL);
	connect(mDispearTime,SIGNAL(timeout()), this, SLOT(OnResetEffort()));
	mDispearTime->start();
}

void testwindow::DoHostConnected()
{
	//TODO DoHostConnected do something
	//qDebug("Device connected.\n");
}

void testwindow::DoHostDisconnected()
{
	//TODO DoHostDisconnected do something
	//qDebug("Device disconnected.\n");
}

#include "moc_testwindow.cpp"
相關文章
相關標籤/搜索