使用直接提升为组件为当前组件即可。

.h

#ifndef QANIMATIONSTACKEDWIDGET_H
#define QANIMATIONSTACKEDWIDGET_H
 
#include <QStackedWidget>
#include <QVariant>
 
class QPropertyAnimation;
class QGraphicsOpacityEffect;
class QParallelAnimationGroup;
//class QVariant;
 
class QAnimationStackedWidget : public QStackedWidget
{
    Q_OBJECT
public:
    explicit QAnimationStackedWidget(QWidget *parent = Q_NULLPTR);
 
    ~QAnimationStackedWidget();
 
    void Next();
 
    void SwitchToIndex(int NextIndex, bool bFront = true);
 
    void setCurrentWidget(QWidget* widget);
protected:
    void paintEvent(QPaintEvent *e);
 
private:
    QParallelAnimationGroup* m_ParlGroup;
 
    QPropertyAnimation *m_pAnimPrty;
 
    QGraphicsOpacityEffect* m_pAnimGraphicsEffect;
    QPropertyAnimation* m_pAnimGraphics;
 
    bool m_bAnimation;
 
    int m_nDuration;
 
    int m_nWidgetCount;
 
    int m_nNextIndex;
 
    QVariant m_nCurValue;
 
    bool m_bMoveFront;
 
private:
    void Init();
 
    void paintPrevious(QPainter &paint, int currentIndex);
 
    void paintNext(QPainter &paint, int nextIndex);
 
    void moveAnimationStart(bool bEnter);
 
private slots:
    void slotAnimationValueChanged(QVariant value);
 
    void slotAnimationFinished();
};
 
#endif // QANIMATIONSTACKEDWIDGET_H
 

.cpp

#include "QAnimationStackedWidget.h"
 
#include <QPropertyAnimation>
#include <QPainter>
#include <QParallelAnimationGroup>
#include <QGraphicsOpacityEffect>
 
QAnimationStackedWidget::QAnimationStackedWidget(QWidget *parent) :
    QStackedWidget(parent)
{
    Init();
}
 
QAnimationStackedWidget::~QAnimationStackedWidget()
{
 
}
 
void QAnimationStackedWidget::Init()
{
    m_bAnimation = false;
 
    m_nDuration = 350;
 
    m_ParlGroup = new QParallelAnimationGroup();
 
    m_pAnimGraphicsEffect = new QGraphicsOpacityEffect(this);
    m_pAnimGraphicsEffect->setOpacity(1);
	this->setGraphicsEffect(m_pAnimGraphicsEffect);
 
	m_pAnimGraphics = new QPropertyAnimation(m_pAnimGraphicsEffect, "opacity");
    m_pAnimPrty = new QPropertyAnimation(this, QByteArray());
    connect(m_pAnimPrty, SIGNAL(valueChanged(QVariant)), this, SLOT(slotAnimationValueChanged(QVariant)));
    connect(m_pAnimPrty, SIGNAL(finished()), this, SLOT(slotAnimationFinished()));
 
    m_pAnimPrty->setEasingCurve(QEasingCurve::InOutQuad);
    m_pAnimGraphics->setEasingCurve(QEasingCurve::InOutQuad);
 
	m_ParlGroup->addAnimation(m_pAnimPrty);
	m_ParlGroup->addAnimation(m_pAnimGraphics);
 
}
 
void QAnimationStackedWidget::slotAnimationValueChanged(QVariant value)
{
    m_nCurValue = value;
 
    update();
}
 
void QAnimationStackedWidget::slotAnimationFinished()
{
    m_bAnimation = false;
 
    widget(currentIndex())->show();
 
    setCurrentIndex(m_nNextIndex);
}
 
void QAnimationStackedWidget::paintEvent(QPaintEvent *e)
{
    Q_UNUSED(e)
 
    if(m_bAnimation)
    {
        QPainter paint(this);
 
        if (m_bMoveFront)
        {
            //绘制当前Widget
            paintPrevious(paint, currentIndex());
 
            //绘制下一个widget
            paintNext(paint, m_nNextIndex);
        }
        else
        {
            //绘制当前Widget
            paintPrevious(paint, m_nNextIndex);
 
            //绘制下一个widget
            paintNext(paint, currentIndex());
        }
    }
}
 
void QAnimationStackedWidget::paintPrevious(QPainter &paint, int currentIndex)
{
    //获得当前页面的Widget
    QWidget *w = widget(currentIndex);
 
    // 切换过程窗口的背景色
    QString strStyle = QString("#%1{background-color: #FFFFFF}").arg(w->objectName());
 
    w->setStyleSheet(strStyle);
 
    QPixmap pixmap(w->size());
 
    //将Widget的内容渲染到QPixmap对象中,即将Widget变成一张图片
    w->render(&pixmap);
 
    QRect r = w->geometry();
 
    //绘制当前的Widget
    double value = m_nCurValue.toDouble();
    QRectF r1(0.0, 0.0, value, r.height());
    QRectF r2(r.width() - value, 0, value, r.height());
    paint.drawPixmap(r1, pixmap, r2);
}
 
void QAnimationStackedWidget::paintNext(QPainter &paint, int nextIndex)
{
    QWidget *nextWidget = widget(nextIndex);
 
    QString strStyle = QString("#%1{background-color: #FFFFFF}").arg(nextWidget->objectName());
 
    nextWidget->setStyleSheet(strStyle);
 
    QRect r = geometry();
 
    //这行代码不加会有bug,第一次切换的时候,QStackedWidget并没有为child分配大小
    nextWidget->resize(r.width(), r.height());
    QPixmap nextPixmap(nextWidget->size());
 
    nextWidget->render(&nextPixmap);
    double value = m_nCurValue.toDouble();
    QRectF r1(value, 0.0, r.width() - value, r.height());
    QRectF r2(0.0, 0.0, r.width() - value, r.height());
 
    paint.drawPixmap(r1, nextPixmap, r2);
}
 
void QAnimationStackedWidget::moveAnimationStart(bool bEnter)
{
	if (bEnter)
	{
		m_pAnimPrty->setStartValue(this->width());
		m_pAnimPrty->setEndValue(0);
 
		m_pAnimGraphics->setDuration(m_nDuration);
		m_pAnimGraphics->setStartValue(0);
		m_pAnimGraphics->setEndValue(1);
	}
	else
	{
		m_pAnimPrty->setStartValue(0);
		m_pAnimPrty->setEndValue(this->width());
 
		m_pAnimGraphics->setDuration(m_nDuration);
		m_pAnimGraphics->setStartValue(0);
		m_pAnimGraphics->setEndValue(1);
	}
 
	m_pAnimPrty->setDuration(m_nDuration);
 
	// m_pAnimPrty->start();
 
	m_ParlGroup->start();
}
 
void QAnimationStackedWidget::SwitchToIndex(int index, bool bFront)
{
    //如果正在动画,那么return
    int curIndex = currentIndex();
 
    m_bMoveFront = bFront;
    m_bAnimation = true;
    m_nWidgetCount = count();
 
    m_nNextIndex = index;
 
    //隐藏当前的widget
    widget(curIndex)->hide();
 
    //开始动画并设置间隔和开始、结束值
    QRect g = geometry();
 
    int width = g.width();
 
    bFront = index >= curIndex;
 
    moveAnimationStart(bFront);
}
 
void QAnimationStackedWidget::setCurrentWidget(QWidget* widget)
{
	int index = indexOf(widget);
    SwitchToIndex(index);
}
 
void QAnimationStackedWidget::Next()
{
    //如果正在动画,那么return
    if(m_bAnimation)
    {
        return;
    }
 
    m_bAnimation = true;
    m_nWidgetCount = count();
    int nIndex = currentIndex();
 
    //计算下一页的索引
    m_nNextIndex = (nIndex + 1) % m_nWidgetCount;
 
    //隐藏当前的widget
    widget(nIndex)->hide();
 
    //开始动画并设置间隔和开始、结束值
    QRect g = geometry();
    int x = g.x();
    int width = g.width();
    m_pAnimPrty->setStartValue(width);
    m_pAnimPrty->setEndValue(0);
    m_pAnimPrty->setDuration(m_nDuration);
    m_pAnimPrty->start();
 
    Q_UNUSED(x)
}