热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

1.介绍嵌入式由于需要支持手指滑动,所以先写个demo,来试验.每次按下的时候,获取一次按下的pos以及按下的时间,然后释放的时候获取一次释放pos,从而计算出,每秒移动的像素点,

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 {
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
#include
#include
#include
#include
#include
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
#include
#include
#include
#include
#include
#include
#include


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(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()<pos()< 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 {
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滑动的资料请关注七九推其它相关文章!





推荐阅读
  • 浅解XXE与Portswigger Web Sec
    XXE与PortswiggerWebSec​相关链接:​博客园​安全脉搏​FreeBuf​XML的全称为XML外部实体注入,在学习的过程中发现有回显的XXE并不多,而 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
  • 判断编码是否可立即解码的程序及电话号码一致性判断程序
    本文介绍了两个编程题目,一个是判断编码是否可立即解码的程序,另一个是判断电话号码一致性的程序。对于第一个题目,给出一组二进制编码,判断是否存在一个编码是另一个编码的前缀,如果不存在则称为可立即解码的编码。对于第二个题目,给出一些电话号码,判断是否存在一个号码是另一个号码的前缀,如果不存在则说明这些号码是一致的。两个题目的解法类似,都使用了树的数据结构来实现。 ... [详细]
  • 在本教程中,我们将看到如何使用FLASK制作第一个用于机器学习模型的RESTAPI。我们将从创建机器学习模型开始。然后,我们将看到使用Flask创建AP ... [详细]
  • 获取时间的函数js代码,js获取时区代码
    本文目录一览:1、js获取服务器时间(动态)2 ... [详细]
  • html结构 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 本文介绍了C++中的引用运算符及其应用。引用运算符是一种将变量定义为另一个变量的引用变量的方式,在改变其中一个变量时,两者均会同步变化。引用变量来源于数学,在计算机语言中用于储存计算结果或表示值抽象概念。变量可以通过变量名访问,在指令式语言中引用变量通常是可变的,但在纯函数式语言中可能是不可变的。本文还介绍了引用变量的示例及验证,以及引用变量在函数形参中的应用。当定义的函数使用引用型形参时,函数调用时形参的改变会同时带来实参的改变。 ... [详细]
  • 本文介绍了深入浅出Linux设备驱动编程的重要性,以及两种加载和删除Linux内核模块的方法。通过一个内核模块的例子,展示了模块的编译和加载过程,并讨论了模块对内核大小的控制。深入理解Linux设备驱动编程对于开发者来说非常重要。 ... [详细]
  • 涉及的知识点-ViewGroup的测量与布局-View的测量与布局-滑动冲突的处理-VelocityTracker滑动速率跟踪-Scroller实现弹性滑动-屏幕宽高的获取等实现步 ... [详细]
author-avatar
那是黑夜过后的黎明_182
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有