QT--实现滑动切换界面(转载) QT--实现滑动切换界面

QT--实现滑动切换界面

一、前言

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

在这里提供了下载地址


二、效果展示

图一:初步开发的效果
在这里插入图片描述
图二:改进之后的效果
在这里插入图片描述


三、原理详解

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

滑动是用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);
}
                
                                
版权声明:本文为《贝勒里恩》博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明,。
本文原文链接:https://blog.csdn.net/Mr_robot_strange/article/details/106208966
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章