当前位置:网站首页>Qt实现界面滑动切换效果
Qt实现界面滑动切换效果
2022-07-04 17:47:00 【三雷科技】
目录
一、Qt实现界面滑动切换效果
效果如下图,滑动效果移动上下屏幕。

二、 设计思路
利用QStackWidget将页面存储起来,因为页面比较少,因此我直接将所有的页面存储在QStachWidget中,如果页面相对较多,可以使用使用使渲染的方式。
然后使用show函数同时展示两个页面的内容,这个很重要,如果使用setCurrentIndex只会展示一个界面,这样不会出现两个界面同时存在的情况。
使用QPropertyAnimation以及QParallelAnimationGroup来设置界面切换动画。
当页面左移动时,将原始界面移除屏幕到左边,将当前界面从右边移动至现在界面位置。
当页面右移动时,将原始界面移除屏幕到右边,将当前界面从左边移动至屏幕展示位置
三、主要函数讲解
QPropertyAnimation:动画类,如果仅控制一个界面的动画可以直接设置动画效果后,start函数启动动画效果。
QParallelAnimationGroup:动画组类,控制一组动画同时运行,我们这里控制了两个界面因此需要使用QParallelAnimationGroup来控制两个界面的动画。
QStackedWidget:用于存储多个界面,当界面需要展示的时候可以通过setCurrentIndex展示当前页面。
四、源代码解析
4、1 初始化界面
在QStatchWidget中添加多个界面。因为这是游戏界面初始化,每一页有25题,一共有515道题目,翻页的总数等int(515/25).
#define MAX_NUM 515
LevelMainWidget::LevelMainWidget(QWidget* parent)
: QWidget(parent)
, m_ptrStackWidget(new QStackedWidget(this))
, m_ptrLayoutMain(new QHBoxLayout)
, m_ptrBtnPre(new QPushButton("上一个", this))
, m_ptrBtnNext(new QPushButton("下一个", this))
, m_bDonghua(false)
{
// 添加界面
for (int i = 0; i < 515; i += 25) {
int start = i + 1;
int end = i + 25;
if (end > 515) {
end = 515;
}
LevelWidget* lvlWidget = new LevelWidget(start, end);
m_listLevelWidget.append(lvlWidget);
m_ptrStackWidget->addWidget(lvlWidget);
connect(lvlWidget, &LevelWidget::sigBtnClick, this,
&LevelMainWidget::slotBtnLevel);
}
// 设置当前展示的界面索引。
m_ptrStackWidget->setCurrentIndex(0);
// 添加上一页按钮
m_ptrLayoutMain->addWidget(m_ptrBtnPre);
// 添加展示的界面
m_ptrLayoutMain->addWidget(m_ptrStackWidget);
// 添加下一页按钮
m_ptrLayoutMain->addWidget(m_ptrBtnNext);
setFixedSize(500, 500);
setLayout(m_ptrLayoutMain);
initConnect();
}
void LevelMainWidget::initConnect()
{
connect(m_ptrBtnPre, SIGNAL(clicked()), this, SLOT(slotBtnPre()));
connect(m_ptrBtnNext, SIGNAL(clicked()), this, SLOT(slotBtnNext()));
}
4、2 上一页滑动效果
获取展示界面的宽度以及高度,下移动界面的时候需要使用。
m_bDonghua:记录当前是否在动画效果中,如果在动画效果中不进行翻页(如果不设置,在快速切换的时候会出现重影)
m_ptrStackWidget->setCurrentIndex(PreIndex);
m_ptrStackWidget->widget(currentIndex)->show();animation1:设置当前页(未切换前)面页面的动画效果,你可以看到startValue和endValue,是从原始屏幕位置移除屏幕外。
animation2:设置即将切换到界面的动画效果,你可以看到startValue和endValue,是从屏幕外位置移除屏幕正中间。
当界面的动画同时执行的时候就出现滑动效果。
void LevelMainWidget::slotBtnPre()
{
if (m_bDonghua) {
return;
}
m_bDonghua = true;
int currentIndex = m_ptrStackWidget->currentIndex();
int windowWidth = m_ptrStackWidget->widget(currentIndex)->width();
int windowHieght = m_ptrStackWidget->widget(currentIndex)->height();
int PreIndex = currentIndex - 1;
if (currentIndex == 0) {
return;
}
m_ptrStackWidget->setCurrentIndex(PreIndex);
m_ptrStackWidget->widget(currentIndex)->show();
QPropertyAnimation* animation1;
QPropertyAnimation* animation2;
QParallelAnimationGroup* group = new QParallelAnimationGroup;
animation1 = new QPropertyAnimation(m_ptrStackWidget->widget(currentIndex),
"geometry");
animation1->setDuration(500);
animation1->setStartValue(QRect(0, 0, windowWidth, windowHieght));
animation1->setEndValue(QRect(windowWidth, 0, windowWidth, windowHieght));
animation2 =
new QPropertyAnimation(m_ptrStackWidget->widget(PreIndex), "geometry");
animation2->setDuration(500);
animation2->setStartValue(
QRect(-windowWidth, 0, windowWidth, windowHieght));
animation2->setEndValue(QRect(0, 0, windowWidth, windowHieght));
group->addAnimation(animation1);
group->addAnimation(animation2);
group->start();
group->setProperty(
"widget", QVariant::fromValue(m_ptrStackWidget->widget(currentIndex)));
connect(group, SIGNAL(finished()), this, SLOT(onAnimationFinished()));
}4、3 下一页滑动效果
获取展示界面的宽度以及高度,下移动界面的时候需要使用。
m_bDonghua:记录当前是否在动画效果中,如果在动画效果中不进行翻页(如果不设置,在快速切换的时候会出现重影)
m_ptrStackWidget->setCurrentIndex(NextIndex);
m_ptrStackWidget->widget(currentIndex)->show();animation1:设置当前页(未切换前)面页面的动画效果,你可以看到startValue和endValue,是从原始屏幕位置移除屏幕外。
animation2:设置即将切换到界面的动画效果,你可以看到startValue和endValue,是从屏幕外位置移除屏幕正中间。
当界面的动画同时执行的时候就出现滑动效果。
void LevelMainWidget::slotBtnNext()
{
if (m_bDonghua) {
return;
}
m_bDonghua = true;
int currentIndex = m_ptrStackWidget->currentIndex();
int windowWidth = m_ptrStackWidget->widget(currentIndex)->width();
int windowHieght = m_ptrStackWidget->widget(currentIndex)->height();
int NextIndex = currentIndex + 1;
if (currentIndex >= m_ptrStackWidget->count()) {
return;
}
m_ptrStackWidget->setCurrentIndex(NextIndex);
m_ptrStackWidget->widget(currentIndex)->show();
QPropertyAnimation* animation1;
QPropertyAnimation* animation2;
QParallelAnimationGroup* group = new QParallelAnimationGroup;
animation1 = new QPropertyAnimation(m_ptrStackWidget->widget(currentIndex),
"geometry");
animation1->setDuration(500);
animation1->setStartValue(QRect(0, 0, windowWidth, windowHieght));
animation1->setEndValue(QRect(-windowWidth, 0, windowWidth, windowHieght));
animation2 =
new QPropertyAnimation(m_ptrStackWidget->widget(NextIndex), "geometry");
animation2->setDuration(500);
animation2->setStartValue(QRect(windowWidth, 0, windowWidth, windowHieght));
animation2->setEndValue(QRect(0, 0, windowWidth, windowHieght));
group->addAnimation(animation1);
group->addAnimation(animation2);
group->start();
group->setProperty(
"widget", QVariant::fromValue(m_ptrStackWidget->widget(currentIndex)));
connect(group, SIGNAL(finished()), this, SLOT(onAnimationFinished()));
}4、4 动画结束处理
动画结束后需要将上一界面进行隐藏,在切换页面的时候已经将上一页面的指针保存发送过来了。
group->setProperty(
"widget", QVariant::fromValue(m_ptrStackWidget->widget(currentIndex)));因此在动画结束时,获取上一页面的指针,然后再修改其隐藏状态即可。
void LevelMainWidget::onAnimationFinished()
{
QParallelAnimationGroup* group = (QParallelAnimationGroup*)sender();
QWidget* widget = group->property("widget").value<QWidget*>();
if (nullptr != widget) {
widget->hide();
}
m_bDonghua = false;
}
五、源码地址
六、其他文章
1. QT开发环境安装以配置。
2. QT线段画板实战
4. QT入门开发一个时钟
10. svg转图片工具开发
13. Qt网络与通信(TCP聊天室)
边栏推荐
- Caché JSON 使用JSON适配器
- From automation to digital twins, what can Tupo do?
- 工厂从自动化到数字孪生,图扑能干什么?
- IBM WebSphere MQ检索邮件
- IBM WebSphere MQ retrieving messages
- 技术分享 | 接口测试价值与体系
- 大佬们,求助一下,我用mysql cdc 2.2.1(flink 1.14.5)写入kafka,设置
- The CDC of sqlserver can read the data for the first time, but it can't read the data after adding, deleting and modifying. What's the reason
- [opencv introduction to mastery 9] opencv video capture, image and video conversion
- 奥迪AUDI EDI INVOIC发票报文详解
猜你喜欢

Scala basic tutorial -- 15 -- recursion

How to modify icons in VBS or VBE

Scala basic tutorial -- 17 -- Collection

ByteDance dev better technology salon was successfully held, and we joined hands with Huatai to share our experience in improving the efficiency of web research and development

神经网络物联网应用技术学什么

ThreadLocal原理与使用

MXNet对GoogLeNet的实现(并行连结网络)

Mxnet implementation of googlenet (parallel connection network)

How is the entered query SQL statement executed?

正则替换【JS,正则表达式】
随机推荐
876. Intermediate node of linked list
Scala基础教程--17--集合
prometheus安装
资料下载 丨首届腾讯技术开放日课程精华!
Scala基础教程--15--递归
Nebula Importer 数据导入实践
Deleting nodes in binary search tree
Basic tutorial of scala -- 16 -- generics
英特尔集成光电研究最新进展推动共封装光学和光互连技术进步
Scala basic tutorial -- 15 -- recursion
2022CoCa: Contrastive Captioners are Image-Text Fountion Models
使用FTP
Rookie post station management system based on C language
ftp、sftp文件传输
Perfect JS event delegation
Is Guoyuan futures a regular platform? Is it safe to open an account in Guoyuan futures?
[发布] 一个测试 WebService 和数据库连接的工具 - DBTest v1.0
SSL证书续费相关问题详解
建立自己的网站(15)
删除字符串中出现次数最少的字符【JS,Map排序,正则】