当前位置:网站首页>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聊天室)
边栏推荐
- Rookie post station management system based on C language
- [opencv introduction to mastery 9] opencv video capture, image and video conversion
- Go microservice (II) - detailed introduction to protobuf
- Scala basic tutorial -- 13 -- advanced function
- IBM WebSphere MQ retrieving messages
- Scala basic tutorial -- 14 -- implicit conversion
- 升级智能开关,“零火版”、“单火”接线方式差异有多大?
- Mxnet implementation of googlenet (parallel connection network)
- Scala basic tutorial -- 20 -- akka
- IBM WebSphere MQ检索邮件
猜你喜欢
One question per day (2022-07-02) - Minimum refueling times
Scala basic tutorial -- 13 -- advanced function
基于unity的愤怒的小鸟设计
神经网络物联网应用技术就业前景【欢迎补充】
Scala basic tutorial -- 15 -- recursion
Principle and application of ThreadLocal
Nature microbiology | viral genomes in six deep-sea sediments that can infect Archaea asgardii
[uniapp] uniapp development app online Preview PDF file
TorchDrug教程
Nebula Importer 数据导入实践
随机推荐
2022-07-04: what is the output of the following go language code? A:true; B:false; C: Compilation error. package main import 'fmt' func
Scala基础教程--19--Actor
MXNet对GoogLeNet的实现(并行连结网络)
《看完就懂系列》字符串截取方法substr() 、 slice() 和 substring()之间的区别和用法
Leetcode ransom letter C # answer
Scala基础教程--17--集合
Guys, for help, I use MySQL CDC 2.2.1 (Flink 1.14.5) to write Kafka and set
Scala basic tutorial -- 13 -- advanced function
26. 删除有序数组中的重复项 C#解答
Learning path PHP -- phpstudy "hosts file does not exist or is blocked from opening" when creating the project
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
From automation to digital twins, what can Tupo do?
用实际例子详细探究OpenCV的轮廓绘制函数drawContours()
更安全、更智能、更精致,长安Lumin完虐宏光MINI EV?
李迟2022年6月工作生活总结
Unity adds a function case similar to editor extension to its script, the use of ContextMenu
Caché JSON 使用JSON适配器
DeFi生态NFT流动性挖矿系统开发搭建
Scala basic tutorial -- 12 -- Reading and writing data
ftp、sftp文件传输