1. 程式人生 > >Qt模仿網易雲音樂 廣告Banner

Qt模仿網易雲音樂 廣告Banner

文章目錄

環境

vs2013 + Qt5.6.2

程式碼

NetEasyBanner.h

#ifndef NETEASYBANNER_H
#define NETEASYBANNER_H

#include <QWidget>
#include <QPixmap>
#include <QList>
#include <QPropertyAnimation>
#include <QParallelAnimationGroup>		//	動畫並行

enum emAnimationType
{
	UnKnow = -1,
	Next = 0,
	Prev = 1,
	Jump,
};

class QNetEasyBanner : public QWidget
{
	Q_OBJECT

public:
	QNetEasyBanner(QWidget *parent);
	~QNetEasyBanner();

public:
	void addImage(const QString& image);

	public slots:
	void onNext();

	void onPrev();

	void onJump(int index);

protected:
	void paintEvent(QPaintEvent *event);

private:

	void drawLeft(QPainter* painter);

	void drawCenter(QPainter* painter);

	void drawRight(QPainter* painter);

	QImage getGrayImage(const QImage& image);

private slots:
	void slot_ValueChanged(const QVariant& value);
	void slot_finished();

private:
	QStringList x_imageList;
	int x_index;
	bool x_isAnimation;
	QParallelAnimationGroup* x_pAnimationGroup;
	QPropertyAnimation* x_pLeftAnimation;
	QPropertyAnimation* x_pCenterAnimation;
	QPropertyAnimation* x_pRightAnimation;
	emAnimationType x_animationType;

	QRect x_leftRect, x_centerRect, x_rightRect;
};

#endif // NETEASYBANNER_H

NetEasyBanner.cpp

#include "NetEasyBanner.h"

#include <QPainter >
#include <QApplication>
#include <QDebug>

QNetEasyBanner::QNetEasyBanner(QWidget *parent)
	: QWidget(parent)
{
	setCursor(Qt::PointingHandCursor);

	resize(770, 200);
	x_isAnimation = false;
	x_index = 0;
	x_animationType = emAnimationType::UnKnow;

	x_pLeftAnimation = new QPropertyAnimation(this, "");
	x_pCenterAnimation = new QPropertyAnimation(this, "");
	x_pRightAnimation = new QPropertyAnimation(this, "");

	x_pAnimationGroup = new QParallelAnimationGroup(this);

	x_pLeftAnimation->setDuration(300);
	x_pCenterAnimation->setDuration(300);
	x_pRightAnimation->setDuration(300);

	x_pAnimationGroup->addAnimation(x_pLeftAnimation);
	x_pAnimationGroup->addAnimation(x_pCenterAnimation);
	x_pAnimationGroup->addAnimation(x_pRightAnimation);

	connect(x_pLeftAnimation, SIGNAL(valueChanged(const QVariant &)), this, SLOT(slot_ValueChanged(const QVariant&)));
	connect(x_pCenterAnimation, SIGNAL(valueChanged(const QVariant &)), this, SLOT(slot_ValueChanged(const QVariant&)));
	connect(x_pRightAnimation, SIGNAL(valueChanged(const QVariant &)), this, SLOT(slot_ValueChanged(const QVariant&)));
	connect(x_pCenterAnimation, SIGNAL(finished()), this, SLOT(slot_finished()));
}

QNetEasyBanner::~QNetEasyBanner()
{

}

void QNetEasyBanner::addImage(const QString& image)
{
	x_imageList.append(image);
}

void QNetEasyBanner::onNext()
{
	if (!x_isAnimation)
	{
		x_animationType = emAnimationType::Next;
		x_isAnimation = true;

		x_pLeftAnimation->setStartValue(QRect(115, 0, 540, 200));
		x_pLeftAnimation->setEndValue(QRect(0, 10, 503, 190));

		x_pCenterAnimation->setStartValue(QRect(267, 10, 503, 190));
		x_pCenterAnimation->setEndValue(QRect(115, 0, 540, 200));

		x_pRightAnimation->setStartValue(QRect(152, 10, 503, 190));
		x_pRightAnimation->setEndValue(QRect(267, 10, 503, 190));

		x_pLeftAnimation->start();
		x_pRightAnimation->start();
		x_pCenterAnimation->start();
	}
}

void QNetEasyBanner::onPrev()
{
	if (!x_isAnimation)
	{
		x_animationType = emAnimationType::Prev;
		x_isAnimation = true;

		x_pLeftAnimation->setStartValue(QRect(115, 10, 503, 190));
		x_pLeftAnimation->setEndValue(QRect(0, 10, 503, 190));

		x_pCenterAnimation->setStartValue(QRect(0, 10, 503, 190));
		x_pCenterAnimation->setEndValue(QRect(115, 0, 540, 200));

		x_pRightAnimation->setStartValue(QRect(115, 0, 540, 200));
		x_pRightAnimation->setEndValue(QRect(267, 10, 503, 190));

		x_pLeftAnimation->start();
		x_pRightAnimation->start();
		x_pCenterAnimation->start();

		update();
	}
}

void QNetEasyBanner::onJump(int index)
{
	if (!x_isAnimation)
	{
		x_index = index;

		x_animationType = Jump;
		x_isAnimation = true;

		x_pLeftAnimation->setStartValue(QRect(115, 10, 503, 190));
		x_pLeftAnimation->setEndValue(QRect(0, 10, 503, 190));

		x_pCenterAnimation->setStartValue(QRect(this->rect().center().x(), this->rect().center().y(), 0, 0));
		x_pCenterAnimation->setEndValue(QRect(115, 0, 540, 200));

		x_pRightAnimation->setStartValue(QRect(115, 10, 503, 190));
		x_pRightAnimation->setEndValue(QRect(267, 10, 503, 190));

		x_pLeftAnimation->start();
		x_pRightAnimation->start();
		x_pCenterAnimation->start();

		update();
	}
}

void QNetEasyBanner::paintEvent(QPaintEvent *event)
{
	QPainter painter(this);

	painter.setRenderHint(QPainter::Antialiasing);

	if (x_imageList.count() < 3)
	{
		painter.drawText(this->geometry(), Qt::AlignCenter, QString::fromLocal8Bit("要求3張圖片以上"));
	}
	else
	{
		drawLeft(&painter);

		drawRight(&painter);

		drawCenter(&painter);
	}
}

void QNetEasyBanner::drawLeft(QPainter* painter)
{
	
	painter->save();
	if (!x_isAnimation)
	{
		int _leftIndex = (x_index + 8 - 1) % 8;
		QImage _leftImage = QImage(x_imageList.at(_leftIndex)).scaled(503, 190);
		painter->drawImage(QRect(0, 10, 503, 190), getGrayImage(_leftImage));
	}
	else 
	{
		if (x_animationType == Next)
		{
			QImage _leftImage = QImage(x_imageList.at(x_index)).scaled(503, 190);
			painter->drawImage(x_leftRect, getGrayImage(_leftImage));
		}
		else if (x_animationType == Prev)
		{
			int _leftIndex = (x_index + 8 - 2) % 8;
			QImage _leftImage = QImage(x_imageList.at(_leftIndex)).scaled(503, 190);
			painter->drawImage(x_leftRect, getGrayImage(_leftImage));
		}
		else if (x_animationType == Jump)
		{
			int _leftIndex = (x_index + 8 - 1) % 8;
			QImage _leftImage = QImage(x_imageList.at(_leftIndex)).scaled(503, 190);
			painter->drawImage(x_leftRect, getGrayImage(_leftImage));
		}
	}

	painter->restore();
}

void QNetEasyBanner::drawCenter(QPainter* painter)
{
	painter->save();
	if (!x_isAnimation)
	{
		painter->drawImage(QRect(115, 0, 540, 200), QImage(x_imageList.at(x_index)));
	}
	else
	{
		if (x_animationType == Next)
		{
			int _centerIndex = (x_index + 8 + 1) % 8;
			QImage _centerImage = QImage(x_imageList.at(_centerIndex));
			painter->drawImage(x_centerRect, _centerImage);
		}
		else if (x_animationType == Prev)
		{
			int _centerIndex = (x_index + 8 - 1) % 8;
			QImage _centerImage = QImage(x_imageList.at(_centerIndex));
			painter->drawImage(x_centerRect, _centerImage);
		}
		else if (x_animationType == Jump)
		{
			painter->drawImage(x_centerRect, QImage(x_imageList.at(x_index)));
		}
	}

	painter->restore();
}

void QNetEasyBanner::drawRight(QPainter* painter)
{
	painter->save();
	if (!x_isAnimation)
	{
		int _rightIndex = (x_index + 8 + 1) % 8;
		QImage _rightImage = QImage(x_imageList.at(_rightIndex)).scaled(503, 190);
		painter->drawImage(QRect(267, 10, 503, 190), getGrayImage(_rightImage));
	}
	else
	{
		if (x_animationType == Next)
		{
			int _rightIndex = (x_index + 8 + 2) % 8;
			QImage _rightImage = QImage(x_imageList.at(_rightIndex)).scaled(503, 190);
			painter->drawImage(x_rightRect, getGrayImage(_rightImage));
		}
		else if (x_animationType == Prev)
		{
			QImage _rightImage = QImage(x_imageList.at(x_index)).scaled(503, 190);
			painter->drawImage(x_rightRect, getGrayImage(_rightImage));
		}
		else if (x_animationType == Jump)
		{
			int _rightIndex = (x_index + 8 + 1) % 8;
			QImage _rightImage = QImage(x_imageList.at(_rightIndex)).scaled(503, 190);
			painter->drawImage(x_rightRect, getGrayImage(_rightImage));
		}
	}

	painter->restore();
}

QImage QNetEasyBanner::getGrayImage(const QImage& image)
{
	int w, h;
	w = image.width();
	h = image.height();

	QImage iGray(w, h, QImage::Format_RGB32);

	for (int i = 0; i < w; i++)
	{
		for (int j = 0; j < h; j++)
		{
			QRgb pixel = image.pixel(i, j);
			int gray = qGray(pixel);
			QRgb grayPixel = qRgb(gray, gray, gray);
			iGray.setPixel(i, j, grayPixel);
		}
	}
	return iGray;
}

void QNetEasyBanner::slot_ValueChanged(const QVariant& value)
{
	QPropertyAnimation* _obj = (QPropertyAnimation*)(sender());

	if (_obj == x_pLeftAnimation)
	{
		qDebug() << "left "<< value.toRect();
		x_leftRect = value.toRect();
	}
	else if (_obj == x_pCenterAnimation)
	{
		qDebug() << "Center " << value.toRect();
		x_centerRect = value.toRect();
	}
	else if (_obj == x_pRightAnimation)
	{
		qDebug() << "Right " << value.toRect();
		x_rightRect = value.toRect();
	}

	update();
}

void QNetEasyBanner::slot_finished()
{
	if (x_animationType == Next)
	{
		x_index = (x_index + 8 + 1) % 8;
	}
	else if (x_animationType == Prev)
	{
		x_index = (x_index + 8 - 1) % 8;
	}
	
	x_isAnimation = false;
}

使用

 	x_pNetEasyBanner = new QNetEasyBanner(ui.frame);

	x_pNetEasyBanner->addImage(":/image/1");
	x_pNetEasyBanner->addImage(":/image/2");
	x_pNetEasyBanner->addImage(":/image/3");
	x_pNetEasyBanner->addImage(":/image/4");
	x_pNetEasyBanner->addImage(":/image/5");
	x_pNetEasyBanner->addImage(":/image/6");
	x_pNetEasyBanner->addImage(":/image/7");
	x_pNetEasyBanner->addImage(":/image/8");

	connect(ui.btn_left, SIGNAL(clicked()), x_pNetEasyBanner, SLOT(onPrev()));
	connect(ui.btn_right, SIGNAL(clicked()), x_pNetEasyBanner, SLOT(onNext()));
	connect(ui.btn_jump, SIGNAL(clicked()), this, SLOT(slot_jump()));

效果

在這裡插入圖片描述

程式碼分享