0
点赞
收藏
分享

微信扫一扫

QT--实现滑动切换界面


文章目录

  • ​​一、前言​​
  • ​​二、效果展示​​
  • ​​三、原理详解​​
  • ​​四、具体实现​​

一、前言

之前用QT写的多界面,基本上都是触发按钮来实现,存在一些问题。一来界面切换生硬,毫无美感;二来随着触摸屏的大众化,用户在潜移默化中已经习惯了类似于滑动这样的手势操作。于是我就突发奇想,想实现这样的效果,这种滑动切换效果在工业开发板上是很实用的,因为工业开发板屏幕尺寸往往偏小,直接点击按钮不太方便。

在这里提供了​​下载地址​​。

二、效果展示

图一:初步开发的效果

QT--实现滑动切换界面_开发板


图二:改进之后的效果

QT--实现滑动切换界面_鼠标事件_02

三、原理详解

滑动切换,我们把它理解为两个动作,分别是:滑动和切换。
首先,讲解滑动的实现原理:

滑动是用Qt的鼠标事件来实现的。可以直接采用​​mousePressEvent​​​配合​​mouseReleaseMove​​​来实现,也可以采用事件监听器来实现(我抱着学习的心态采用的这个,因为之前没接触过)。事件监听怎么用,可以参考我的博文:​​Qt事件​​​。
当鼠标点下的时候,记录一下鼠标的起始位置;当鼠标松开的时候,记录一下鼠标的当前位置;然后根据两个坐标去判断,鼠标是否发生了移动,如果移动了,那就执行滑动之后要发生的事件。滑动又分为左滑和右滑,而且移动了多少算是滑动,这需要定一个标准,当移动距离超过了设定的标准,则判定为产生了滑动。

其次,讲解切换的原理:

widget的切换,其实就直接用show()和hide就可以实现,或者是QStackWidget的setCurrentIndex()。但是这样切换界面是瞬间的,没有一个过渡动画,显然这不是我想要的效果(模拟手机界面滑动)。为了实现这样的效果,我们可以截图当前界面,然后画到Label上,然后先切换完界面,再把Label平移出去,这样就实现了图一的效果。
但是这还是没有完全模拟到滑动界面切换(手机的界面切换是一个界面滑出去,一个界面滑进来),所以继续进行改进。要实现一个界面滑出去,接着一个界面滑出来,这就有两个动作了,所以我们需要把两个动画(QPropertyAnimation)放在一个动画容器(QParallelAnimationGroup)里,然后一起播放。画面1是滑出去,画面2是滑进来,连贯起来就实现了图二的效果。

四、具体实现

bool Widget::eventFilter(QObject *watch, QEvent *evn)
{
static int press_x; //鼠标按下时的位置
static int press_y;
static int relea_x; //鼠标释放时的位置
static int relea_y;

QMouseEvent *event = static_cast<QMouseEvent *>(evn); //将之转换为鼠标事件

if(event->type()==QEvent::MouseButtonPress) //如果鼠标按下
{
press_x = event->globalX();
press_y = event->globalY();
}

if(event->type()==QEvent::MouseButtonRelease) //如果鼠标释放
{
relea_x = event->globalX();
relea_y = event->globalY();
}

//判断滑动方向(右滑)
if((relea_x - press_x)>20 && event->type()==QEvent::MouseButtonRelease && qAbs(relea_y-press_y)<50)
{
int current_page = ui->stackedWidget->currentIndex();
if(current_page<=2)
{
ui->label->setPixmap(ui->stackedWidget->currentWidget()->grab()); //捕获当前界面并绘制到label上

QPropertyAnimation *animation1 = new QPropertyAnimation(ui->label,"geometry");
animation1->setDuration(1000); //设置动画时间为1秒
animation1->setStartValue(QRect(0,0,this->width(),this->height()));
animation1->setEndValue(QRect(this->width()*2,0,this->width(),this->height()));

ui->stackedWidget->setCurrentIndex(current_page+1); //切换界面

QPropertyAnimation *animation2 = new QPropertyAnimation(ui->stackedWidget->currentWidget(),"geometry");
animation2->setDuration(1000);
animation2->setStartValue(QRect(-this->width()*2,0,this->width(),this->height()));
animation2->setEndValue(QRect(0,0,this->width(),this->height()));

QParallelAnimationGroup *group = new QParallelAnimationGroup; //动画容器
group->addAnimation(animation1);
group->addAnimation(animation2);
group->start();
}
}

//判断滑动方向(左滑)
if((press_x - relea_x)>20 && event->type()==QEvent::MouseButtonRelease && qAbs(relea_y-press_y)<50)
{
int current_page = ui->stackedWidget->currentIndex();
if(current_page>=0)
{
ui->label->setPixmap(ui->stackedWidget->currentWidget()->grab());

QPropertyAnimation *animation1 = new QPropertyAnimation(ui->label,"geometry");
animation1->setDuration(1000);
animation1->setStartValue(QRect(0,0,this->width(),this->height()));
animation1->setEndValue(QRect(-this->width(),0,this->width(),this->height()));

ui->stackedWidget->setCurrentIndex(current_page-1);

QPropertyAnimation *animation2 = new QPropertyAnimation(ui->stackedWidget->currentWidget(),"geometry");
animation2->setDuration(1000);
animation2->setStartValue(QRect(this->width()*2,0,this->width(),this->height()));
animation2->setEndValue(QRect(0,0,this->width(),this->height()));

QParallelAnimationGroup *group = new QParallelAnimationGroup;
group->addAnimation(animation1);
group->addAnimation(animation2);
group->start();
}
}

return QWidget::eventFilter(watch,evn);
}


举报

相关推荐

0 条评论