当前位置:   article > 正文

QStackedWidget动画 含源代码,可直接调用使用_qt的qstackedwidget页面切换动画效果

qt的qstackedwidget页面切换动画效果

QStackedWidget切换动画 含源代码,可直接调用使用

本文通过继承QStackedWidget类,实现动画功能(本文使用版本QT5.12.10)

可直接实例化QAnimationStackedWidget类,或在qtdesigner中将QStackedWidget提升为该类,或继承该类,均可直接调用动画效果

原理简述

原理非常简单,其实就是通过QPropertyAnimation设置QStackedWidget中每一页的’'pos"属性,即位置属性,将每一页的显示位置移动即可实现上述效果。不过需要留意切换前后的currentIndex等细节

动画效果展示

  • 动画效果1 从左向右滑动
    请添加图片描述
  • 动画效果2 从左侧进入(注意观察文字位置,自行体会和上一个动画的差别)
    请添加图片描述
  • 动画效果3 向左侧退出(注意观察文字位置,自行体会和上一个动画的差别)
    请添加图片描述

调用说明

调用时,可设置动画持续时间(默认1000ms),必须设置动画类型
所有动画类型在enum AnimationMode中,亦可自行修改
L代表左,R右,U上,D下
L2R为动画效果1
FromL为动画效果2
Quit2L为动画效果3

QAnimationStackedWidget* animationStackedWidget=new QAnimationStackedWidget(this);
animationStackedWidget->setAnimationDuration(1000);
animationStackedWidget->setAnimationMode(FromL);
//调用(亦可通过信号与槽调用)
animationStackedWidget->StartStackedWidgetAnimation(0,1); //当前页面index,以及切换的页面index
  • 1
  • 2
  • 3
  • 4
  • 5

组合动画效果

文章提供源代码亦提供动画效果4
请添加图片描述
本质是组合了进入与退出动画,设置了一组QSequentialAnimationGroup,文章封装好了从左向右进入,再从右向左退出的动画效果,修改动画的startValue和endValue也可实现别的方向效果。该动画主要是提供思路(其实是本人自己的项目需求)
调用时需设置动画模式为 AUTOScroll,并使用另一槽函数
(本人代码水平有限,如果直接拿来用,在设置为此动画模式后,请只使用该模式,不要在程序其它位置setAnimationMode为其它模式,否则会出问题(仅使用动画效果123的话是没有任何问题的))

animationStackedWidget->StartStackedWidgetMaskAnimation(2, 0, 1, 1000);
//第一个参数为遮罩层index,即实例中绿色3代表的index
//第二三个参数即为切换前的index及切换后的index
//第四个参数为遮罩层在完全出现后的停留时间
  • 1
  • 2
  • 3
  • 4

源代码 .h

#pragma once

#include <QStackedWidget>
#include <QPropertyAnimation>
#include <QPauseAnimation>
#include <QSequentialAnimationGroup>

enum AnimationMode{
	L2R,R2L,U2D,D2U,FromL,FromR,FromU,FromD,Quit2L, Quit2R, Quit2U, Quit2D,AUTOScroll
};

class QAnimationStackedWidget  : public QStackedWidget
{
	Q_OBJECT

public:
	QAnimationStackedWidget(QWidget *parent);
	~QAnimationStackedWidget();
	//设置动画时长
	void setAnimationDuration(int duration);
	//设置动画模式,模式在enum AnimationMode中枚举
	void setAnimationMode(int mode);
signals:
	//动画完成时发出信号
	void sStackedWidgetAnimationFinished(int indexbefore,int indexcurrent);
public slots:
	//支持除AUTOScroll外的动画
	void StartStackedWidgetAnimation(int indexbefore, int indexafter);
	//仅支持AUTOScroll动画,indexmask为遮罩层的index,septime为暂停时间
	void StartStackedWidgetMaskAnimation(int indexmask, int indexbefore, int indexafter, int septime);
private:
	QPropertyAnimation*					m_AnimationCurrent;
	QPropertyAnimation*					m_AnimationNext;
	QPauseAnimation*						m_PauseAnimation;
	QSequentialAnimationGroup*	m_AnimationGroup;
	int            m_AnimationDuration = 1000;
	double		m_AnimationCurrentValue = 0;
	int			m_AnimationMode = 0;
	int			m_lndexBeforeAnimation = 0;
	int			m_lndexAfterAnimation = 0;
	int			m_IndexMask = 0;
	bool			m_IsAnimation = false;
	bool			m_IsGroupAnimation = false;
	QPointF rectL;
	QPointF rectR;
	QPointF rectU;
	QPointF rectD;
	QPointF rect;
	void startAnimationEngine();
private slots:
	void OnAnimationFinished();
	void OnPauseAnimationFinished();
	void OnGroupAnimationFinished();
};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

源代码 .cpp

#include "QAnimationStackedWidget.h"

QAnimationStackedWidget::QAnimationStackedWidget(QWidget *parent)
	: QStackedWidget(parent)
{
	m_AnimationCurrent = new QPropertyAnimation(this,"pos");
	m_AnimationNext = new QPropertyAnimation(this, "pos");
	m_PauseAnimation = new QPauseAnimation(this);
	m_AnimationGroup = new QSequentialAnimationGroup(this);
	connect(m_AnimationNext, &QPropertyAnimation::finished, this, &QAnimationStackedWidget::OnAnimationFinished);
	connect(m_AnimationCurrent, &QPropertyAnimation::finished, this, &QAnimationStackedWidget::OnAnimationFinished);
}

QAnimationStackedWidget::~QAnimationStackedWidget()
{
	if (m_AnimationCurrent) { m_AnimationCurrent->deleteLater(); m_AnimationCurrent = Q_NULLPTR; }
	if (m_AnimationNext) { m_AnimationNext->deleteLater(); m_AnimationNext = Q_NULLPTR; }
	if (m_AnimationGroup) { m_AnimationGroup->clear(); m_AnimationGroup->deleteLater(); m_AnimationGroup = Q_NULLPTR; }
	if (m_PauseAnimation) { m_PauseAnimation->deleteLater(); m_PauseAnimation = Q_NULLPTR; }
}

void QAnimationStackedWidget::OnAnimationFinished()
{
	m_IsAnimation = false;
	widget(m_lndexBeforeAnimation)->hide();
	widget(m_lndexAfterAnimation)->show();
	widget(m_lndexAfterAnimation)->raise();
	setCurrentIndex(m_lndexAfterAnimation);
	emit(sStackedWidgetAnimationFinished(m_lndexBeforeAnimation, m_lndexAfterAnimation));
}

void QAnimationStackedWidget::OnPauseAnimationFinished()
{
	widget(m_lndexBeforeAnimation)->hide();
	widget(m_lndexAfterAnimation)->show();
	widget(m_IndexMask)->show();
	widget(m_lndexAfterAnimation)->lower();
	widget(m_IndexMask)->raise();
}

void QAnimationStackedWidget::OnGroupAnimationFinished()
{
	widget(m_IndexMask)->hide();
	widget(m_lndexBeforeAnimation)->hide();
	widget(m_lndexAfterAnimation)->show();
	setCurrentIndex(m_lndexAfterAnimation);
	m_IsGroupAnimation = false;
	emit(sStackedWidgetAnimationFinished(m_lndexBeforeAnimation, m_lndexAfterAnimation));
}


void QAnimationStackedWidget::StartStackedWidgetAnimation(int indexbefore, int indexafter)
{
	if (m_IsAnimation||m_IsGroupAnimation) { return; }
	if (indexbefore >= count() || indexafter >= count() || indexbefore < 0 || indexafter < 0 || indexafter == indexbefore)
	{
		return;
	}
	m_lndexBeforeAnimation = indexbefore;
	m_lndexAfterAnimation = indexafter;
	m_AnimationCurrent->setDuration(m_AnimationDuration);
	m_AnimationNext->setDuration(m_AnimationDuration);
	m_IsAnimation = true;
	startAnimationEngine();
}

void QAnimationStackedWidget::StartStackedWidgetMaskAnimation(int indexmask,int indexbefore, int indexafter,int septime)
{
	if (m_IsAnimation || m_IsGroupAnimation) { return; }
	m_IsGroupAnimation = true;
	m_IndexMask = indexmask;
	m_lndexBeforeAnimation = indexbefore;
	m_lndexAfterAnimation = indexafter;
	m_AnimationCurrent->setTargetObject(widget(indexmask));
	m_AnimationNext->setTargetObject(widget(indexmask));
	m_AnimationCurrent->setStartValue(rectL);
	m_AnimationCurrent->setEndValue(rect);
	m_AnimationNext->setStartValue(rect);
	m_AnimationNext->setEndValue(rectL);
	m_AnimationCurrent->setDuration(m_AnimationDuration);
	m_AnimationNext->setDuration(m_AnimationDuration);
	m_PauseAnimation->setDuration(septime);
	m_AnimationGroup->addAnimation(m_AnimationCurrent);
	m_AnimationGroup->addAnimation(m_PauseAnimation);
	m_AnimationGroup->addAnimation(m_AnimationNext);
	m_AnimationGroup->start();
	widget(indexmask)->show();
	widget(indexmask)->raise();
	widget(indexbefore)->show();
}

void QAnimationStackedWidget::startAnimationEngine()
{
	m_AnimationCurrent->setTargetObject(widget(m_lndexBeforeAnimation));
	m_AnimationNext->setTargetObject(widget(m_lndexAfterAnimation));
	widget(m_lndexBeforeAnimation)->show();
	widget(m_lndexAfterAnimation)->show();
	switch (m_AnimationMode)
	{
	case R2L:
		m_AnimationCurrent->setStartValue(rect);
		m_AnimationCurrent->setEndValue(rectL);
		m_AnimationNext->setStartValue(rectR);
		m_AnimationNext->setEndValue(rect);
		m_AnimationCurrent->start();
		m_AnimationNext->start();
		break;
	case L2R:
		m_AnimationCurrent->setStartValue(rect);
		m_AnimationCurrent->setEndValue(rectR);
		m_AnimationNext->setStartValue(rectL);
		m_AnimationNext->setEndValue(rect);
		m_AnimationCurrent->start();
		m_AnimationNext->start();
		break;
	case U2D:
		m_AnimationCurrent->setStartValue(rect);
		m_AnimationCurrent->setEndValue(rectD);
		m_AnimationNext->setStartValue(rectU);
		m_AnimationNext->setEndValue(rect);
		m_AnimationCurrent->start();
		m_AnimationNext->start();
		break;
	case D2U:
		m_AnimationCurrent->setStartValue(rect);
		m_AnimationCurrent->setEndValue(rectU);
		m_AnimationNext->setStartValue(rectD);
		m_AnimationNext->setEndValue(rect);
		m_AnimationCurrent->start();
		m_AnimationNext->start();
		break;
	case FromD:
		m_AnimationNext->setStartValue(rectD);
		m_AnimationNext->setEndValue(rect);
		m_AnimationNext->start();
		widget(m_lndexAfterAnimation)->raise();
		break;
	case FromU:
		m_AnimationNext->setStartValue(rectU);
		m_AnimationNext->setEndValue(rect);
		m_AnimationNext->start();
		widget(m_lndexAfterAnimation)->raise();
		break;
	case FromL:
		m_AnimationNext->setStartValue(rectL);
		m_AnimationNext->setEndValue(rect);
		m_AnimationNext->start();
		widget(m_lndexAfterAnimation)->raise();
		break;
	case FromR:
		m_AnimationNext->setStartValue(rectR);
		m_AnimationNext->setEndValue(rect);
		m_AnimationNext->start();
		widget(m_lndexAfterAnimation)->raise();
		break;
	case Quit2D:
		m_AnimationCurrent->setStartValue(rect);
		m_AnimationCurrent->setEndValue(rectD);
		m_AnimationCurrent->start();
		m_AnimationNext->setStartValue(rect);
		m_AnimationNext->setEndValue(rect);
		m_AnimationNext->start();
		widget(m_lndexBeforeAnimation)->raise();
		break;
	case Quit2U:
		m_AnimationCurrent->setStartValue(rect);
		m_AnimationCurrent->setEndValue(rectU);
		m_AnimationCurrent->start();
		m_AnimationNext->setStartValue(rect);
		m_AnimationNext->setEndValue(rect);
		m_AnimationNext->start();
		widget(m_lndexBeforeAnimation)->raise();
		break;
	case Quit2L:
		m_AnimationCurrent->setStartValue(rect);
		m_AnimationCurrent->setEndValue(rectL);
		m_AnimationCurrent->start();
		m_AnimationNext->setStartValue(rect);
		m_AnimationNext->setEndValue(rect);
		m_AnimationNext->start();
		widget(m_lndexBeforeAnimation)->raise();
		break;
	case Quit2R:
		m_AnimationCurrent->setStartValue(rect);
		m_AnimationCurrent->setEndValue(rectR);
		m_AnimationCurrent->start();
		m_AnimationNext->setStartValue(rect);
		m_AnimationNext->setEndValue(rect);
		m_AnimationNext->start();
		widget(m_lndexBeforeAnimation)->raise();
		break;
	default:
		break;
	}

}

void QAnimationStackedWidget::setAnimationMode(int mode)
{
	m_AnimationMode = mode;
	rectL = QPointF(-width(), 0);
	rectR = QPointF(width(), 0);
	rectU = QPointF(0, -height());
	rectD = QPointF(0, height());
	rect = QPointF(0, 0);
	switch (mode)
	{
	case AUTOScroll:
		disconnect(m_AnimationNext, &QPropertyAnimation::finished, this, &QAnimationStackedWidget::OnAnimationFinished);
		disconnect(m_AnimationCurrent, &QPropertyAnimation::finished, this, &QAnimationStackedWidget::OnAnimationFinished);
		connect(m_PauseAnimation, &QPauseAnimation::finished, this, &QAnimationStackedWidget::OnPauseAnimationFinished);
		connect(m_AnimationGroup, &QSequentialAnimationGroup::finished, this, &QAnimationStackedWidget::OnGroupAnimationFinished);
		break;
	default:
		break;
	}
}

void QAnimationStackedWidget::setAnimationDuration(int duration)
{
	m_AnimationCurrent->setDuration(duration);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222

调用示例

#include "QAnimationStackedWidget.h"

QAnimationStackedWidget* animationStackedWidget; = new QAnimationStackedWidget(this);
animationStackedWidget->addWidget(....);
animationStackedWidget->setAnimationDuration(3000);
animationStackedWidget->setAnimationMode(L2R);
m_MainStackedWidget->StartStackedWidgetAnimation(0,1);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/81565
推荐阅读
相关标签
  

闽ICP备14008679号