环境
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)
{
if (index < x_imageList.size())
{
x_index = index;
}
else
{
return;
}
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 + x_imageList.size() - 1) % x_imageList.size();
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 + x_imageList.size() - 2) % x_imageList.size();
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 + x_imageList.size() - 1) % x_imageList.size();
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 + x_imageList.size() + 1) % x_imageList.size();
QImage _centerImage = QImage(x_imageList.at(_centerIndex));
painter->drawImage(x_centerRect, _centerImage);
}
else if (x_animationType == Prev)
{
int _centerIndex = (x_index + x_imageList.size() - 1) % x_imageList.size();
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 + x_imageList.size() + 1) % x_imageList.size();
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 + x_imageList.size() + 2) % x_imageList.size();
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 + x_imageList.size() + 1) % x_imageList.size();
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()));