欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Qt重寫QStackedWidget模擬實現(xiàn)home界面滑動效果

 更新時間:2022年11月29日 17:06:06   作者:音視頻開發(fā)老舅  
這篇文章主要為大家詳細介紹了Qt如何通過重寫QStackedWidget模擬實現(xiàn)home界面滑動效果,文中的實現(xiàn)過程講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下

在上章我們學習了QScroller實現(xiàn)home界面滑動效果,但是該界面是實現(xiàn)的上下滑動效果,如果想模擬手機home滑動界面,則需要實現(xiàn)左右滑動效果.

本章,則重寫QStackedWidget類,來真正的模擬手機,來實現(xiàn)home界面左右滑動效果.

1.SmoothStackedWidget類實現(xiàn)

demo界面如下圖所示(創(chuàng)建了4個子界面):

 (支持快滑,慢滑):

如果是慢滑,則根據(jù)當前滑到的界面處于哪一頁占比更多,則就跳到哪里.

否則就是快滑,根據(jù)滑動的偏移值來決定跳轉(zhuǎn)

同樣也支持邊緣滑動檢測(已在最邊緣時,則滑動速率減慢,告訴用戶已到邊緣):

2.代碼實現(xiàn)

頭文件如下所示:

#ifndef SMOOTHSTACKEDWIDGET_H
#define SMOOTHSTACKEDWIDGET_H
 
#include <QObject>
#include <QWidget>
#include <QStackedWidget>
#include <QAbstractScrollArea>
#include <QPixmap>
#include <QPropertyAnimation>
 
class SmoothStackedWidget : public QStackedWidget
{
    Q_OBJECT
 
#define SMOOTH_MAX_MS   900                   //平滑滑動時的最大延遲時間
#define SMOOTH_EDGE_MOVE_RATIO   0.14         //邊緣移動系數(shù),范圍0~1,越低越慢
 
    typedef enum tagScrollMouseDragInfo {
          MOUSE_RELEASE = 0,                       //鼠標離開
          MOUSE_PRESS = 1,                         //按下
          MOUSE_PRESS_MOVE = 2,                    //按下移動
          MOUSE_RELEASE_MOVE = 3                   //鼠標離開并滑動
    }Scroll_Mouse_Drag_INFO_E;
 
    typedef enum tagSmoothAnimationSwitchInfo {
          SWITCH_PRE = -1,                      //切換上一頁
          SWITCH_NONE = 0,                      //不切換
          SWITCH_NEXT = 1,                      //切換下一頁
    }AnimationSwitch_Drag_INFO_E;
 
    Scroll_Mouse_Drag_INFO_E m_dragFlag = MOUSE_RELEASE;
    AnimationSwitch_Drag_INFO_E m_switchFlag = SWITCH_NONE;
  
    QWidget *m_parent;
 
    QWidget m_smoothWidget;
 
    int m_smoothCurrentIndex=-1;
 
    QPropertyAnimation *animation;
 
    float m_smoothMovePos;
 
    bool eventFilter(QObject *obj, QEvent *evt) override;
 
    void paintEvent(QPaintEvent *event) override;
 
    void resizeEvent(QResizeEvent *event) override;
 
    void SmoothLoadPixmap(bool isSmoothUpdate = false);
    void SmoothStartMove();
 
    void SmoothMove(int offset);
 
    void SmoothAnimationStart(int startPos, int endPos, int durationMs);
 
    void SmoothAnimationInit();
 
public:
    explicit SmoothStackedWidget(QWidget *parent = nullptr);
 
    int addWidget(QAbstractScrollArea *w);
 
    int addWidget(QWidget *w);
 
    void setCurrentIndex(int index);
 
    void removeWidget(QWidget *w);
 
    void IconUpdate();      //刷新頁數(shù)標簽
 
    void UpdateSmooth();
 
signals:
 
protected slots:
    void OnSmoothAnimationFinished();
 
};
 
#endif // SMOOTHSTACKEDWIDGET_H

其中eventFilter()函數(shù)如下所示:

當鼠標(手指)按下移動時,則調(diào)用SmoothMove(offset),通過offset來動態(tài)顯示滑動的界面.

當鼠標(手指)松開后,則調(diào)用SmoothAnimationStart()來實現(xiàn)界面移動(到底是切換上一頁、還是切換下一頁、還是當前頁).

bool SmoothStackedWidget::eventFilter(QObject *obj, QEvent *evt)
{
    QMouseEvent *mouse =  dynamic_cast<QMouseEvent *>(evt);
    QWidget *w =  dynamic_cast<QWidget *>(obj);
 
    static int pressPoint_x   = 0;          //按下的坐標
    static int dragPoint_x    = -1;         //拖動時的坐標
    static qint64 pressMSec ;
 
    if(mouse && w && animation->state() == QAbstractAnimation::Stopped)
    {
         if( mouse->type() ==QEvent::MouseButtonPress)    //首次按下
        {
           pressMSec = QDateTime::currentDateTime().toMSecsSinceEpoch();     //記錄按下的時間
           dragPoint_x  = mouse->pos().x();               //當前坐標
           pressPoint_x = dragPoint_x;                    //按下的位置
           m_dragFlag = MOUSE_PRESS;
        }
         else if(mouse->type() == QEvent::MouseButtonRelease &&
                 m_dragFlag == MOUSE_PRESS)               //未移動
        {
           m_dragFlag = MOUSE_RELEASE;
        }
         else if(mouse->type() == QEvent::MouseMove &&
                 m_dragFlag == MOUSE_PRESS)               //初次滑動,判斷移動閥值,避免誤操作
        {
            if(qAbs(dragPoint_x - mouse->pos().x()) > 3)     //判斷移動閥值,避免誤操作
            {
               dragPoint_x = mouse->pos().x();
               SmoothStartMove();
               m_dragFlag = MOUSE_PRESS_MOVE;
            }
        }
         else if(mouse->type() == QEvent::MouseMove &&
                 m_dragFlag== MOUSE_PRESS_MOVE )             //正在滑動
        {
            int offset = ( mouse->pos().x() - dragPoint_x);
            SmoothMove(offset);
            dragPoint_x = mouse->pos().x();
        }
        else if(mouse->type() == QEvent::MouseButtonRelease &&
                m_dragFlag == MOUSE_PRESS_MOVE)               //滑動結(jié)束,啟動平滑滑動
        {
             int durationMs= QDateTime::currentDateTime().toMSecsSinceEpoch()-pressMSec;
             SmoothAnimationStart(pressPoint_x,mouse->pos().x(),durationMs);
             m_dragFlag = MOUSE_RELEASE;
        }
    }
 
    return QWidget::eventFilter(obj,evt);
}

SmoothAnimationStart()函數(shù)如下所示:

void  SmoothStackedWidget::SmoothAnimationStart(int startPos, int endPos, int durationMs)
{
    int pixelPerSecond=qAbs(endPos - startPos)*1000/durationMs;       //計算每秒像素點
    m_switchFlag = SWITCH_NONE;
    int moveX = qAbs(m_smoothWidget.x());
    float temp = width()*0.5;
    int animationEndX;
 
    //慢速滑動(速度過慢||時間過長),則根據(jù)當前滑到哪里,就跳到哪里
    if(pixelPerSecond<300 || durationMs > 1000) {
        if(moveX < (temp)) {        //[0,width/2] = 上一頁
            if(currentIndex()==0) {
                animationEndX = -width();
            } else {
                animationEndX = 0;
                m_switchFlag = SWITCH_PRE;
            }
        } else if(moveX < (temp*3)) {    //[width/2,width*3/2] = 當前一頁
            animationEndX = -width();
        } else {
            if(currentIndex()==(count()-1)) {   //[width*3/2,width*2] = 下一頁
                animationEndX = -width();
            } else {
                animationEndX = -width()*2;
                m_switchFlag = SWITCH_NEXT;
            }
        }
 
    } else {    // 否則就是快速滑動
        if(startPos < endPos) { //向右滑動
            if(currentIndex()==0) {
                animationEndX = -width();
            } else {
                animationEndX = 0;
                m_switchFlag = SWITCH_PRE;
            }
        } else {         //向左滑動
            if(currentIndex()==(count()-1)) {
                animationEndX = -width();
            } else {
                animationEndX = -width()*2;
                m_switchFlag = SWITCH_NEXT;
            }
        }
    }
 
    //根據(jù)每秒滑動像素點,來計算滑動時長.
    int animationDuration = durationMs;
    float xOffsetRatio = qAbs(animationEndX - m_smoothWidget.x()) / (static_cast<float>(width())); //計算滑動占整屏比例
 
    if(animationDuration > (SMOOTH_MAX_MS * xOffsetRatio)) //滑動時間過大,則重置
        animationDuration = SMOOTH_MAX_MS * xOffsetRatio;
 
 
    animation->setDuration(animationDuration);
    animation->setStartValue(m_smoothWidget.geometry());
    animation->setEndValue(QRect(animationEndX, m_smoothWidget.y(), m_smoothWidget.width(), m_smoothWidget.height()));
    animation->start();
}

到此這篇關于Qt重寫QStackedWidget模擬實現(xiàn)home界面滑動效果的文章就介紹到這了,更多相關Qt QStackedWidget界面滑動內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • DLL加載設置相對路徑的方法

    DLL加載設置相對路徑的方法

    這篇文章給大家介紹了DLL加載設置相對路徑的方法,非常不錯,具有一定的參考借鑒加載,需要的朋友參考下吧
    2018-08-08
  • C++?Date類的具體使用(構(gòu)建,重載等)

    C++?Date類的具體使用(構(gòu)建,重載等)

    本文主要介紹了C++?Date類的具體使用(構(gòu)建,重載等),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • C語言庫函數(shù)qsort及bsearch快速排序算法使用解析

    C語言庫函數(shù)qsort及bsearch快速排序算法使用解析

    這篇文章主要為大家介紹了C語言庫函數(shù)qsort及bsearch快速排序算法的使用示例解析
    2022-02-02
  • FFmpeg實現(xiàn)音頻漸響效果參數(shù)值詳解

    FFmpeg實現(xiàn)音頻漸響效果參數(shù)值詳解

    這篇文章主要為大家介紹了FFmpeg實現(xiàn)音頻漸響效果參數(shù)值詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • C++超詳細分析單鏈表的實現(xiàn)與常見接口

    C++超詳細分析單鏈表的實現(xiàn)與常見接口

    鏈表是一種物理存儲結(jié)構(gòu)上非連續(xù)、非順序的存儲結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過鏈表中的指針鏈接次序?qū)崿F(xiàn)的,本章帶你分析單鏈表的實現(xiàn)與常見接口
    2022-03-03
  • C++模板類的用法

    C++模板類的用法

    這篇文章主要介紹了C++模板類的用法,實例講述了模板類的概念及相關用法,需要的朋友可以參考下
    2014-10-10
  • C語言實現(xiàn)單鏈表的快速排序算法

    C語言實現(xiàn)單鏈表的快速排序算法

    大家好,本篇文章主要講的是C語言實現(xiàn)單鏈表的快速排序算法,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • C++實現(xiàn)消消樂游戲

    C++實現(xiàn)消消樂游戲

    這篇文章主要為大家詳細介紹了C++實現(xiàn)消消樂游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C語言算法打卡回文串驗證算法題解

    C語言算法打卡回文串驗證算法題解

    這篇文章主要為大家介紹了C語言算法打卡萬人千提的leetcode回文串的驗證算法題解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-02-02
  • 代碼講解C++繼承和派生

    代碼講解C++繼承和派生

    在本文中我們通過實例代碼給大家講解下C++繼承和派生相關知識點,需要的朋友們學習下。
    2019-02-02

最新評論