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
  • 5
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
qt 滑屏翻页效果C++程序 #ifndef PICTUREFLOW_H #define PICTUREFLOW_H #include class PictureFlowPrivate; /*! Class PictureFlow implements an image show widget with animation effect like Apple's CoverFlow (in iTunes and iPod). Images are arranged in form of slides, one main slide is shown at the center with few slides on the left and right sides of the center slide. When the next or previous slide is brought to the front, the whole slides flow to the right or the right with smooth animation effect; until the new slide is finally placed at the center. */ class PictureFlow : public QWidget { Q_OBJECT Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) Q_PROPERTY(QSize slideSize READ slideSize WRITE setSlideSize) Q_PROPERTY(int slideCount READ slideCount) Q_PROPERTY(int centerIndex READ centerIndex WRITE setCenterIndex) public: enum ReflectionEffect { NoReflection, PlainReflection, BlurredReflection }; /*! Creates a new PictureFlow widget. */ PictureFlow(QWidget* parent = 0); /*! Destroys the widget. */ ~PictureFlow(); /*! Returns the background color. */ QColor backgroundColor() const; /*! Sets the background color. By default it is black. */ void setBackgroundColor(const QColor& c); /*! Returns the dimension of each slide (in pixels). */ QSize slideSize() const; /*! Sets the dimension of each slide (in pixels). */ void setSlideSize(QSize size); /*! Returns the total number of slides. */ int slideCount() const; /*! Returns QImage of specified slide. */ QImage slide(int index) const; /*! Returns the index of slide currently shown in the middle of the viewport. */ int centerIndex() const; /*! Returns the effect applied to the reflection. */ ReflectionEffect reflectionEffect() const; /*! Sets the effect applied to the reflection. The default is PlainReflection. */ void setReflectionEffect(ReflectionEffect effect); public slots: /*! Adds a new slide. */ void addSlide(const QImage& image); /*! Adds a new slide. */ void addSlide(const QPixmap& pixmap); /*! Sets an image for specified slide. If the slide already exists, it will be replaced. */ void setSlide(int index, const QImage& image); /*! Sets a pixmap for specified slide. If the slide already exists, it will be replaced. */ void setSlide(int index, const QPixmap& pixmap); /*! Sets slide to be shown in the middle of the viewport. No animation effect will be produced, unlike using showSlide. */ void setCenterIndex(int index); /*! Clears all slides. */ void clear(); /*! Shows previous slide using animation effect. */ void showPrevious(); /*! Shows next slide using animation effect. */ void showNext(); /*! Go to specified slide using animation effect. */ void showSlide(int index); /*! Rerender the widget. Normally this function will be automatically invoked whenever necessary, e.g. during the transition animation. */ void render(); /*! Schedules a rendering update. Unlike render(), this function does not cause immediate rendering. */ void triggerRender(); signals: void centerIndexChanged(int index); protected: void paintEvent(QPaintEvent *event); void keyPressEvent(QKeyEvent* event); void mousePressEvent(QMouseEvent* event); void resizeEvent(QResizeEvent* event); private slots: void updateAnimation(); private: PictureFlowPrivate* d; }; #endif // PICTUREFLOW_H

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值