QStackedWidget QPropertyAnimation QPainter custom image carousel animation control (C)

First, renderings
Here Insert Picture Description
Second, the construction project ideas
before QStackedWidget switch interface, the animation will start the transition interface between the two interfaces drawn. To be drawn after completion of the call setCurrentIndex container interface to achieve a real switch.
Third, code snippets

#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]

Published 30 original articles · won praise 1 · views 1162

Guess you like

Origin blog.csdn.net/u010906468/article/details/102938838