嵌入式由于需要支持手指滑动,所以先写个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);
界面如下图所示:
customscroll:自定义滑动,该类包含了一个显示滑动条.逻辑如下所示:
效果如下所示:
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
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()<
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滑动的资料请关注七九推其它相关文章!