• 58.tablewidget模拟手指实现滑动


    1.介绍

    嵌入式由于需要支持手指滑动,所以先写个demo,来试验.

    每次按下的时候,获取一次按下的pos以及按下的时间,然后释放的时候获取一次释放pos,从而计算出,每秒移动的像素点,其中计算代码如下所示:

    int ms= QDateTime::currentDateTime().toMSecsSinceEpoch()-pressMSec;
    int Pixel_per_second=qAbs(releasePoint_y - pressPoint_y)*1000/ms;       //计算每秒移动像素点

    获取到每秒移动像素点后,再结合ms(持续时间),进行判断,从而实现手指离开后,是否需要再滑动一下.具体代码如下所示:

     if(ms > 1000)      //滑动的时间太长
    {
         m_dragFlag = MOUSE_RELEASE;
         if(!m_scrollTimer.isActive())
             m_scrollTimer.start(1000);  //1S后取消滑动条显示
         return true;
    }
    
    if(releasePoint_y - pressPoint_y > 0)     //向下滑动
    {
        moveValue = m_scrollBar->value() - Pixel_per_second*0.2*(300/ms);//滑动时间越长,moveValue值越小,因为不是快速滑动
        if(moveValue < scrollV_min)
        {
            moveValue = scrollV_min;
        }
    }
    else
    {
        moveValue = m_scrollBar->value() + Pixel_per_second*0.2*(300/ms);
        if(moveValue > scrollV_max)
        {
            moveValue = scrollV_max;
        }
    }

    最后再调用QPropertyAnimation类来实现动画滑动:

    animation->setDuration(2000-ms);
    animation->setEndValue(moveValue);
    animation->setEasingCurve(QEasingCurve::OutQuart);

    界面如下图所示:

    2.CustomScroll类

    CustomScroll:自定义滑动,该类包含了一个显示滑动条.逻辑如下所示:

    • 当用户只是单击item时,则不显示.
    • 如果用户点击item进行滑动时,则显示.
    • 如果用户滑动后释放鼠标(离开手指),则1s后取消显示

    效果如下所示:

    CustomScroll.h如下所示:

    #ifndef CustomScroll_H
    #define CustomScroll_H
    
    #include <QObject>
    #include <QWidget>
    #include <QTimer>
    #include <QTableView>
    #include <QPropertyAnimation>
    #include <QDateTime>
    class CustomScroll : public QWidget
    {
        Q_OBJECT
    
        typedef enum tagLuiScrollMouseDragInfo {
            MOUSE_RELEASE = 0,                       //鼠标离开
            MOUSE_PRESS = 1,                         //按下
            MOUSE_PRESS_MOVE = 2,                   //按下移动
            MOUSE_RELEASE_MOVE = 3                   //鼠标离开并滑动
        }LUI_Scroll_Mouse_Drag_INFO_E;
    
    
        LUI_Scroll_Mouse_Drag_INFO_E m_dragFlag = MOUSE_RELEASE;
    
        QTimer m_scrollTimer;
        QTimer m_selectTimer;
        QTableView *m_table;
        QScrollBar *m_scrollBar;
    
        QPropertyAnimation *animation;
        int  m_selectRow;
        int  m_srcollH;
    
    
        void paintEvent(QPaintEvent *);
    
        bool eventFilter(QObject *obj, QEvent *evt);
    
    public:
        explicit CustomScroll(QTableView* table,QWidget *parent = nullptr);
    
    
    signals:
    
    
    public slots:
        void scrollTimeOut();
        void selectTimeOut();
    };
    
    #endif // CustomScroll_H

    CustomScroll.cpp如下所示:

    #include "customscroll.h"
    #include <QMouseEvent>
    #include <QDebug>
    #include <QApplication>
    #include <QPainter>
    #include <QTableWidget>
    #include <QHeaderView>
    #include <QScrollBar>
    #include <QAbstractAnimation>
    
    
    CustomScroll::CustomScroll(QTableView* table,QWidget *parent) : QWidget(parent)
    {
    #define  SRCOLL_HEIGHT  22
    
        setAttribute(Qt::WA_TranslucentBackground);
    
        m_table = table;
    
        m_scrollBar = table->verticalScrollBar();
    
        m_table->viewport()->installEventFilter(this);
    
        m_table->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
    
        animation =  new QPropertyAnimation(m_scrollBar,"value",this);
    
        connect(&m_scrollTimer,SIGNAL(timeout()),this,SLOT(scrollTimeOut()));
    
        connect(&m_selectTimer,SIGNAL(timeout()),this,SLOT(selectTimeOut()));
    
    
    
    
        this->setMinimumSize(10, table->height());
        this->setMaximumSize(10, table->height());
        this->move(table->width()-10,0);            //将滑动条移至最右侧
        this->raise();
    
        m_srcollH  = table->height()* SRCOLL_HEIGHT/100.0;
    
    }
    
    
    void CustomScroll::selectTimeOut()
    {
        m_table->selectRow(m_selectRow);
        m_selectTimer.stop();
        this->update();
    }
    
    void CustomScroll::scrollTimeOut()
    {
    
    
        if(m_dragFlag == MOUSE_RELEASE_MOVE && animation->state()==QAbstractAnimation::Stopped) //停下来了
        {
            this->update();
            m_dragFlag = MOUSE_RELEASE;
            m_scrollTimer.setInterval(1000);
        }
        else
        {
            this->update();
            if(m_scrollTimer.interval()==1000)
                m_scrollTimer.stop();
        }
    
    }
    
    
    bool CustomScroll::eventFilter(QObject *obj, QEvent *evt)
    {
        static int pressPoint_y   = 0;
        static int dragPoint_y    = -1;
        static qint64 pressMSec ;
        QMouseEvent *mouse =  dynamic_cast<QMouseEvent *>(evt);
    
        int scrollV_max = m_scrollBar->maximum ();
        int scrollV_min = m_scrollBar->minimum ();
    
         //根据鼠标的动作——按下、放开、拖动,执行相应的操作
        if(mouse)
        {
            if( mouse->type() ==QEvent::MouseButtonPress)    //首次按下
            {
                pressMSec = QDateTime::currentDateTime().toMSecsSinceEpoch();     //记录按下的时间
                dragPoint_y  = mouse->pos().y();               //当前坐标
                pressPoint_y = dragPoint_y;                      //按下的位置
    
                animation->stop();
                m_selectRow =  m_table->indexAt(mouse->pos() ).row();    //选择当前行
                qDebug()<<mouse->pos()<<m_selectRow;
                m_selectTimer.start(100);
                m_dragFlag = MOUSE_PRESS;
                return true;
            }
            else if(mouse->type() == QEvent::MouseButtonRelease && m_dragFlag == MOUSE_PRESS)   //未移动
            {
                m_dragFlag = MOUSE_RELEASE;
                if(!m_scrollTimer.isActive())
                    m_scrollTimer.start(1000);  //1S后取消滑动条显示
                return true;
            }
            else if(mouse->type() == QEvent::MouseButtonRelease && m_dragFlag == MOUSE_PRESS_MOVE)
            {
                dragPoint_y = -1;
                int releasePoint_y = mouse->pos().y();
    
                int ms= QDateTime::currentDateTime().toMSecsSinceEpoch()-pressMSec;
                int Pixel_per_second=qAbs(releasePoint_y - pressPoint_y)*1000/ms;       //计算每秒像素点
    
                if(Pixel_per_second<300 || qAbs(releasePoint_y - pressPoint_y) < 45)
                {
                    m_dragFlag = MOUSE_RELEASE;
                    if(!m_scrollTimer.isActive())
                        m_scrollTimer.start(1000);  //1S后取消滑动条显示
                    return true;
                }
                else
                {
    
                    int moveValue ;
    
                     if(ms > 1000)      //滑动的时间太长
                    {
                         m_dragFlag = MOUSE_RELEASE;
                         if(!m_scrollTimer.isActive())
                             m_scrollTimer.start(1000);  //1S后取消滑动条显示
                         return true;
                    }
    
                    if(releasePoint_y - pressPoint_y > 0)     //向下滑动
                    {
                        moveValue = m_scrollBar->value() - Pixel_per_second*0.2*(300/ms);//滑动时间越长,moveValue值越小,因为不是快速滑动
                        if(moveValue < scrollV_min)
                        {
                            moveValue = scrollV_min;
                        }
                    }
                    else
                    {
    
                        moveValue = m_scrollBar->value() + Pixel_per_second*0.2*(300/ms);
                        if(moveValue > scrollV_max)
                        {
                            moveValue = scrollV_max;
                        }
                    }
    
                    animation->setDuration(2000-ms);
                    animation->setEndValue(moveValue);
                    animation->setEasingCurve(QEasingCurve::OutQuart);
    
                    if(!m_scrollTimer.isActive())
                        m_scrollTimer.start(50);  //定时刷新滑动条显示
    
                    animation->start();
                    m_dragFlag = MOUSE_RELEASE_MOVE;
    
                }
                 return true;
            }
            else if(mouse->type() == QEvent::MouseMove && (m_dragFlag!= MOUSE_RELEASE) )
            {
                if(  m_dragFlag == MOUSE_PRESS)     //开始移动
                {
                    if(qAbs(dragPoint_y - mouse->pos().y()) < 4)      //判断移动阀值,避免误操作
                        return true;
                    else
                    {
                       m_dragFlag = MOUSE_PRESS_MOVE;
                       if(m_selectTimer.isActive())                         //已经移动了,所以取消选择
                           m_selectTimer.stop();
                       m_table->clearSelection();
                       dragPoint_y = mouse->pos().y();                      //获取当前坐标
                       update();
                       return true;
                    }
                }
    
                int moveValue = ( dragPoint_y-mouse->pos().y())+m_scrollBar->value();    //差距
    
                dragPoint_y = mouse->pos().y();                        //获取当前坐标
    
                if(scrollV_min > moveValue)
                {
                    moveValue = scrollV_min;
                }
                if(moveValue > scrollV_max)
                {
                    moveValue = scrollV_max;
                }
                m_scrollBar->setValue(moveValue);
                update();
    
                return true;
            }
        }
            return QWidget::eventFilter(obj,evt);
    }
    
    void CustomScroll::paintEvent(QPaintEvent *)
    {
    #define  WIDTH 6
    #define  MIN_HEIGHT 6
    
        if(m_dragFlag== MOUSE_RELEASE||m_dragFlag== MOUSE_PRESS)
        {
            return;
        }
    
        int scrollV_max = m_scrollBar->maximum ();
    
    
        QPainter painter(this);
    
        int y = (m_table->verticalScrollBar()->value()*(m_table->height()-m_srcollH))/(float)(scrollV_max);
    
        painter.setPen(Qt::NoPen);
       // painter.setBrush(QColor(180,180,180,200));
       // painter.drawRoundedRect(0,0,this->width(),this->height(),3,3);
    
        painter.setBrush(QColor(80,80,80,140));
        painter.drawRoundedRect(0,y,WIDTH,m_srcollH,3,3);
    }

     资源下载地址: https://download.csdn.net/download/qq_37997682/13614035

     未完,下章学习61.QT-QScroller实现home界面滑动效果

  • 相关阅读:
    轮播无缝
    项目开发的注意
    再聊移动端页面的适配
    如何在Vue项目中使用vw实现移动端适配
    移动端适配文章
    vue-cli 配置flexible px2rem-loader安装配置
    vuex复习笔记
    vue-router复习笔记
    vue-cli 笔记
    内置组件 -slot讲解
  • 原文地址:https://www.cnblogs.com/lifexy/p/14111572.html
Copyright © 2020-2023  润新知