QStackedWidget QPropertyAnimation QPainter 自定义图片轮播控件 动画(三)

一、效果图
在这里插入图片描述
二、工程构造思路
QStackedWidget切换界面之前,启动动画将两个界面之间的过渡界面绘制出来。待绘制完成之后,在调用setCurrentIndex来实现容器界面真正地切换。
三、代码片段

#ifndef ANIMATIONSTACKWIDGET_H
#define ANIMATIONSTACKWIDGET_H

#include <QObject>
#include <QWidget>
#include <QStackedWidget>
#include <QPropertyAnimation>
#include <QPainter>
#include <QPixmap>
#include <QLabel>
#include <QTimer>
#include <QDebug>
#include <QPushButton>
#include <QSequentialAnimationGroup>
#include <QHBoxLayout>

#include "AppWidget/animationbtn.h"
class animationstackwidget : public QStackedWidget
{
    Q_OBJECT
public:
    animationstackwidget(QWidget *par = nullptr);
    ~animationstackwidget();
    void paintEvent(QPaintEvent *e);
private slots:
    void valueChanged_slot(QVariant value);
    void animationFinished();
private:
    void paintPrev(QPainter &painter,int index);
    void paintNext(QPainter &painter,int index);
    void startAnimation();
private:
    QVariant m_AnimationValue;
};

#endif // ANIMATIONSTACKWIDGET_H

#include "animationstackwidget.h"
animationstackwidget::animationstackwidget(QWidget *par)
    :QStackedWidget(par)
{
    resize(par->size());
    show();
    QLabel *label0 = new QLabel;
    QLabel *label1 = new QLabel;
    QLabel *label2 = new QLabel;
    label0->setPixmap(QPixmap(":/image/1.jpg"));
    label1->setPixmap(QPixmap(":/image/2.jpg"));
    label2->setPixmap(QPixmap(":/image/3.jpg"));
    label0->resize(this->size());
    label1->resize(this->size());
    label2->resize(this->size());

    addWidget(label0);
    addWidget(label1);
    addWidget(label2);
    setCurrentIndex(0);
    startAnimation();

    QWidget *w = new QWidget(this);
    w->resize(300,5);
    w->move(10,this->height()-15);
//    w->setStyleSheet("background:red");
    w->show();

    AnimationBtn *btn0 = new AnimationBtn;
    AnimationBtn *btn1 = new AnimationBtn;
    AnimationBtn *btn2 = new AnimationBtn;
    connect(btn0,&AnimationBtn::finished,this,[=](){
        btn1->start();
    });
    connect(btn1,&AnimationBtn::finished,this,[=](){
        btn2->start();
    });
    connect(btn2,&AnimationBtn::finished,this,[=](){
        btn0->start();
    });

    QHBoxLayout *playout = new QHBoxLayout(w);
    playout->addWidget(btn0);
    playout->addWidget(btn1);
    playout->addWidget(btn2);
    playout->addStretch();
    playout->setMargin(0);
    playout->setSpacing(5);

    btn0->start();
}

animationstackwidget::~animationstackwidget()
{
}

void animationstackwidget::paintEvent(QPaintEvent *e)
{
    QPainter painter(this);
    paintPrev(painter,currentIndex());
    paintNext(painter,currentIndex()+1);
}

void animationstackwidget::valueChanged_slot(QVariant value)
{
    m_AnimationValue = value;
    update();
}

void animationstackwidget::animationFinished()
{
    widget(currentIndex())->show();
    if(currentIndex() == 2)
        setCurrentIndex(0);
    else
        setCurrentIndex(currentIndex()+1);
    startAnimation();
}

void animationstackwidget::startAnimation()
{
    QPropertyAnimation *m_pAnimation = new QPropertyAnimation(this, QByteArray());
    connect(m_pAnimation, SIGNAL(valueChanged(QVariant)), this, SLOT(valueChanged_slot(QVariant)));
    connect(m_pAnimation, SIGNAL(finished()), this, SLOT(animationFinished()));
    widget(currentIndex())->hide();
    m_pAnimation->setStartValue(this->geometry().width());
    m_pAnimation->setEndValue(0);
    m_pAnimation->setDuration(2000);
    m_pAnimation->setEasingCurve(QEasingCurve::OutQuad);
    m_pAnimation->start(QAbstractAnimation::DeletionPolicy::DeleteWhenStopped);
}

void animationstackwidget::paintPrev(QPainter &painter, int index)
{
    QWidget* w = widget(index);
    QPixmap pixmap(w->size());
    w->render(&pixmap);
    double value = m_AnimationValue.toDouble();
    QRectF r1(0.0, 0.0, value, w->geometry().height());
    QRectF r2(w->geometry().width() - value, 0, value, w->geometry().height());
    painter.drawPixmap(r1, pixmap, r2);
}

void animationstackwidget::paintNext(QPainter &painter, int index)
{
    QWidget* w = widget(index == 3 ? 0:index);
    QPixmap pixmap(w->size());
    w->render(&pixmap);
    double value = m_AnimationValue.toDouble();
    QRectF r1(value, 0.0, w->geometry().width()-value, w->geometry().height());
    QRectF r2(0.0, 0.0, w->geometry().width()-value, w->geometry().height());
    painter.drawPixmap(r1, pixmap, r2);
}


e-mail:[email protected]

发布了30 篇原创文章 · 获赞 1 · 访问量 1162

猜你喜欢

转载自blog.csdn.net/u010906468/article/details/102938838