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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章