Qt利用tablewidget模拟手指实现滑动

目录
  • 1.介绍
  • 2.CustomScroll类

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);
}

以上就是Qt利用tablewidget模拟手指实现滑动的详细内容,更多关于Qt tablewidget滑动的资料请关注我们其它相关文章!

(0)

相关推荐

  • Qt GUI图形图像开发之QT表格控件QTableView,QTableWidget复杂表头(多行表头) 及冻结、固定特定的行的详细方法与实例

    我们在开发过程中对于表格使用频率还是挺高的,使用QT框架开发时候我们使用QTableView或者QTableWidget创建表格. 其中表格分为 表格头与表格体: 对于简单地表格,我们可以设置表头来满足我们的要求(当然也可以隐藏表头),不过对于定制化的表头,我们能做的不是特别多.特别是对于复杂的表头,使用自带的表头,无论怎么设置都不太可能达到需求.例如我最近接到的一个项目,需求是: 我们分析一下这个表格有什么特点: 1.表头不是简单的一行,而是两行. 2.表头有单元格的合并. 3.部分表头中间有

  • C/C++表格组件Qt TableWidget应用详解

    TableWidget 表格结构组件,该组件可以看作是TreeWidget树形组件的高级版,表格组件相比于树结构组件灵活性更高,不仅提供了输出展示二维表格功能,还可以直接对表格元素直接进行编辑与修改操作,表格结构分为表头,表中数据两部分,表格结构可看作一个二维数组,通过数组行列即可锁定特定元素,如下代码是针对表格结构的基本使用方法,分别实现了表头数据的初始化,元素的插入等基本操作. 在研究Widget组件之前先来熟悉一下View组件,View组件相对Widget组件来说只是不具备编辑功能,其他功

  • Qt GUI图形图像开发之Qt表格控件QTableView简单使用方法及QTableView与QTableWidget区别

    QTableView是Qt中用来把数据集以表格形式提供给用户的一个控件 QTableView类实现表格视图,QTableView的数据由继承QAbstractItemModel的子类models来提供 #include<QStandardItemModel> QStandardItemModel *model = new QStandardItemModel(); ui->tableView->setModel(model); 一.添加表头: model->setColumn

  • Qt QTableWidget基本操作及使用

    目录 界面设计与初始化 QTableWidget 基本操作 设置表头 初始化表格数据 获得当前单元格数据 插入.添加.删除行 其他属性控制 遍历表格读取数据 QTableWidget 是 Qt 中的表格组件类.在窗体上放置一个 QTableWidget 组件后,可以在 Property Editor 里对其进行属性设置,双击这个组件,可以打开一个编辑器,对其 Colum.Row 和 Item 进行编辑. 一个 QTableWidget 组件的界面基本结构如图 1 所示,这个表格设置为 6 行 5

  • Qt实现导出QTableWidget/QTableView数据

    目录 一.前言 二.功能特点 三.体验地址 四.效果图 五.相关代码 一.前言 本组件的初衷就是造一个轮子,让数据导入导出用法极致简单,几个行数几行代码搞定它,适用大部分的应用场景,这也是本组件和qtxls最大的区别,qtxls的目标是大而全,提供各种xls的接口,至于如何组织导出的数据,那需要程序员自己去处理,这就避免不了需要调用很多函数代码,而我们往往入门的程序员用起来没那么方便,比如很多人其实就想将现在QTableWidget或者QTableView中的数据导出,也不想去研究如何组织数据,

  • Qt利用tablewidget模拟手指实现滑动

    目录 1.介绍 2.CustomScroll类 1.介绍 嵌入式由于需要支持手指滑动,所以先写个demo,来试验. 每次按下的时候,获取一次按下的pos以及按下的时间,然后释放的时候获取一次释放pos,从而计算出,每秒移动的像素点,其中计算代码如下所示: int ms= QDateTime::currentDateTime().toMSecsSinceEpoch()-pressMSec; int Pixel_per_second=qAbs(releasePoint_y - pressPoint_

  • Qt利用QScroller实现home界面滑动效果

    目录 1.QScroller类 2.QScrollerProperties滑动器参数类 3.表格类的使用示例 4.自定义home界面Demo示例 在学习本章之前需要知道滑动的关键词: 鼠标按下,鼠标滑动 : 指的是用户按下屏幕,然后进行移动的操作,此时用户滑动多少距离,那么视图就偏移多少距离. 平滑滑动 : 指的是手指离开屏幕了,然后会读取滑动的速率(距离/时间),从而让视图自己平滑的再滑动一段距离. 1.QScroller类 用于触摸屏的一个滑动器,实现用户用手指来滑动视图,有大量的参数设置可

  • 利用Java+Selenium+OpenCV模拟实现网页滑动验证

    目录 一.需求分析 二.模拟步骤 1.使用selenium打开某音网页 2.找到小滑块以及小滑块所在的背景图 3.计算小滑块需要滑动的距离 4.按住小滑块并滑动 三.学习过程中比较棘手的问题 1.截图问题 2.返回结果与实际滑动距离相差太多,甚至无规律可循 3.openCV的下载安装 四.总结 目前很多网页都有滑动验证,目的就是防止不良爬虫扒他们网站的数据,我这次本着学习的目的使用Java和selenium学习解决滑动验证的问题,前前后后花了一周时间(抄代码),终于成功了某音的滑动验证! 效果展

  • 利用swift实现卡片横向滑动动画效果的方法示例

    本文主要给大家介绍了关于利用swift实现卡片横向滑动动画效果的相关资料,分享出来供大家参考学习,下面来一起看看详细的介绍吧. 根据惯例,首先上效果图: 那天去面试,面试官突然拿出手机点开了一个app,自个在那点了一会,然后问我 这个效果怎么实现,当时一看可以滑动,肯定用scrollView 或者 collectionView实现,就大概的说了下.今天刚好闲下来,就敲一敲这个效果. 先来分析下这个效果: 卡片是横向滚动,并且每个卡片的位置都是保持在屏幕中间的,而且 左右相邻的卡片都露出来一点边

  • 如何利用原生JS实现触摸滑动监听事件

    前言 今天写一个小Demo,有个地方涉及到了左滑右滑的逻辑,本来想着用插件来着,但是想到自己好久没用原生JS写滑动的监听了,所以试着用原生JS来实现了一下,毕竟温故而知新嘛,同时做个记录.先把实现的效果贴出来: 构思 想要写出丝滑的触摸滑动事件的监听,要考虑以下3个方面的逻辑: 距离: 滑动距离要大于40 时间: 滑动时间小于在0.5秒,即500毫秒内完成手指按下,拖动,离开(避免只是手指在屏幕就触发) 滑动方向: 左右滑动的条件是:X轴移动的距离大于Y轴移动的距离,为正则向左,为负则向右 上下

  • 利用PyQt5模拟实现网页鼠标移动特效

    核心代码: from random import random from time import time from PyQt5.QtCore import QPropertyAnimation, QObject, pyqtProperty, QEasingCurve,\ Qt, QRectF, pyqtSignal from PyQt5.QtGui import QColor, QPainterPath, QPainter from PyQt5.QtWidgets import QWidget

  • android中使用Activity实现监听手指上下左右滑动

    用Activity的onTouchEvent方法实现监听手指上下左右滑动 应用了Activity的ontouchEvent方法监听手指点击事件,手指滑动的时候会先按下,滑倒另一个地方再抬起,我们就可以根据按下的坐标和抬起的坐标算出用户是往哪一个方向滑动了. package com.example.testtt; import android.app.Activity; import android.os.Bundle; import android.view.MotionEvent; impor

  • 利用python模拟实现POST请求提交图片的方法

    本文主要给大家介绍的是关于利用python模拟实现POST请求提交图片的方法,分享出来供大家参考学习,下面来一看看详细的介绍: 使用requests来模拟HTTP请求本来是一件非常轻松的事情,比如上传图片来说,简单的几行代码即可: import requests files = {'attachment_file': ('1.png', open('1.png', 'rb'), 'image/png', {})} values = {'next':"http://www.xxxx.com/xxx

  • Android视频播放器屏幕左侧边随手指上下滑动亮度调节功能的原理实现

    本文给大家分享Android视频播放器屏幕左侧边随手指上下滑动亮度调节功能的原理实现,具体代码如下所示: import android.app.Activity; import android.os.Bundle; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import andro

  • vue 路由页面之间实现用手指进行滑动的方法

    问题描述:vue 路由页面之间如何用手指进行滑动 解决方法: 1.下载依赖:npm intall  vue-touch --save -D 2.在需要滑动的页面添加标签;<v-touch>  注意要宽高,当页面有东西要写入时,可用v-touch 包裹着其他标签: 如:<v-touch class="controller" v-on:swipeleft="onSwipeLeft" v-on:swiperight="onSwipeRight&

随机推荐