Touch Gesture
一 .QScroller 自带的滑动效果
QScroller是qt自带的能够处理触摸手势的库 包括多指手势和惯性滑动。同时还提供了很多接口属性来设置滑动。效果用于触摸屏的一个滑动器,实现用户用手指来滑动视图,有大量的参数设置可以通过QScrollerProperties设置,它的默认值基于平台优化值。
1.1 QScroller类
头文件 #include <QScroller>
1.2 QScrollerProperties滑动器参数类
关于属性的设置还有很多,具体可以从Qt官网进行查询:
https://doc.qt.io/qt-5/qscroller.html
QScrollerProperties::MousePressEventDelay
//设置鼠标按下的延迟时间,比如设置按下多少ms后开始真正触发滑动器.
QScrollerProperties::DragStartDistance
//设置移动阀值(按下后需要移动最少多少距离后,触发滑动),用来避免误操作.
QScrollerProperties::DragVelocitySmoothingFactor
//平滑滑动速度,当滑动后手离开屏幕后,进行平滑滑动的速度,此值应介于0和1之间。值越小,速度越慢。
QScrollerProperties::DecelerationFactor
//减速速度因子,减速到0速度所需的时间。对于大多数类型,该值应在0.1到2.0的范围内
QScrollerProperties::MinimumVelocity
//平滑滑动的最小速度
QScrollerProperties::VerticalOvershootPolicy
//垂直越区策略
使用方法:
QScrollerProperties scrPrt = sc->scrollerProperties();
scrPrt.setScrollMetric(QScrollerProperties::DecelerationFactor, 5);
scrPrt.setScrollMetric(QScrollerProperties::MaximumVelocity, 0.635);
scrPrt.setScrollMetric(QScrollerProperties::DragStartDistance, 0.001);
1.3 抓取手势
QScroller::TouchGesture
value:0
Description:手势识别器仅在触摸事件时触发。具体来说,当使用触摸屏时,
它会对单触点做出反应,而当使用触摸板时,它会对双触点做出反应。
QScroller::LeftMouseButtonGesture
value:1
Description:手势识别器仅在鼠标左键事件上触发。
QScroller::MiddleMouseButtonGesture
value:3
Description:手势识别器仅在鼠标中键事件时触发。
QScroller::RightMouseButtonGesture
value:2
Description:手势识别器仅在鼠标右键事件时触发。
1.4 具体实例
#include <QScroller>
//增加手指滑动
#if 1
QScroller *sc = QScroller::scroller(m_listView->viewport());
QScrollerProperties scrPrt = sc->scrollerProperties();
//设置过冲值,避免过冲导致的BUG
#if 1
scrPrt.setScrollMetric(QScrollerProperties::OvershootDragResistanceFactor,0.000002);
scrPrt.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor,0.4);
#endif
//像素点滚动 也可以进行设置以Item为单位进行滚动
m_listView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
sc->setScrollerProperties(scrPrt);
sc->grabGesture(m_listView->viewport(),QScroller::LeftMouseButtonGesture);
二 .TouchEvent 滑动事件处理
TouchEvent主要是对触摸的 起始,中间过程,结束 等事件来进行数据处理达到自己想要的手势效果
2.1触摸事件
QEvent::TouchBegin:刚触摸的时候的触摸信息判断
QEvent::TouchUpdate:触摸过程中的信息
QEvent::TouchEnd:触摸结束的信息
QEvent::TouchCancel:触摸取消的信息
2.2触摸事件捕获
安装事件过滤器。通过事件过滤器对触摸事件进行捕捉再进行判断
#if 1
this->installEventFilter(this);
//触摸事件
this->setAttribute(Qt::WA_AcceptTouchEvents);
#endif
3.3实例
#if 1
//触摸事件
bool FullListView::eventFilter(QObject *object, QEvent *event)
{
switch (event->type())
{
case QEvent::TouchBegin:
return touchBeginEventProcess(event);
case QEvent::TouchUpdate:
return touchUpdateEventProcess(event);
case QEvent::TouchEnd:
return touchEndEventProcess(event);
case QEvent::TouchCancel:
return touchCancelEventProcess(event);
default:
break;
}
return false;
}
bool FullListView::touchBeginEventProcess(QEvent *event)
{
QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
QList<QTouchEvent::TouchPoint> touchStartPoints = touchEvent->touchPoints();
// touch开始触控的点坐标
startPoint1 = touchStartPoints.at(0).screenPos().toPoint();
// qDebug()<<"touch开始触控的点坐标"<<startPoint1;
touchBegin_time = QTime::currentTime();//touch开始时间
touchEvent->accept();
return true;
}
bool FullListView::touchUpdateEventProcess(QEvent *event)
{
QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
QList<QTouchEvent::TouchPoint> touchUpdatePoints = touchEvent->touchPoints();
if ( touchUpdatePoints.count() > 0) //多指
{
// 假设此时场景,手指滑动了
// screenPos 当前坐标的位置
nowPoint = touchUpdatePoints.at(0).screenPos().toPoint();
// 上一次坐标的位置
QPoint lastPoint = touchUpdatePoints.at(0).lastScreenPos().toPoint();
endPoint1 = nowPoint; // 手指滑动后,记录一下最后松开的 坐标位置
}
return true;
}
bool FullListView::touchEndEventProcess(QEvent *event)
{
//qDebug()<<"FullCommonUseWidget::touchEndEventProcess";
QTouchEvent *touchEvent11 = static_cast<QTouchEvent *>(event);
//touch 转换成坐标点
QList<QTouchEvent::TouchPoint> touchUpdatePoints1 = touchEvent11->touchPoints();
touchEnd_time = QTime::currentTime();//touch_end时间
//传入坐标值
QPoint p = mapFromGlobal(touchUpdatePoints1.at(0).lastScreenPos().toPoint());
int allTouch_Time = touchBegin_time.msecsTo(touchEnd_time);
qDebug()<<"touch间距时间:"<<allTouch_Time;
//如果触摸的时间小于500 模拟鼠标点击事件打开应用
if( (finalDistance_y < 10) &&(finalDistance_x < 10)&& (allTouch_Time <= 700) )
{
}
//如果上下左右移动的距离为2,且触摸时间大于700 弹出右键菜单
if( (finalDistance_y < 10) &&(finalDistance_x <10)&& (allTouch_Time > 700) )
{
}
touchEvent11->accept();
return true;
}
bool FullListView::touchCancelEventProcess(QEvent *event)
{
qDebug()<<"touchCancelEventProcess";
return true;
}
#endif
总结
1.应用QScroller类接口可以较好的实现应用的触摸滑动效果,活动过程中的属性可以通过相关接口进行设置。QScroller滑动的效果实际上就是用过滑动滚轮来实现的。并且已经能够实现了惯性滑动效果。滑动相对来说比较理想。
2.通过通过TouchEvent滑动触摸事件来实现滑动效果可以增加相应的手势识别。比如我想三指实现界面切换,四指实现滑动上下翻页等等。TouchEvent来处理的话需要自己来实现惯性滑动的效果。TouchEvent的滑动也是通过在滑动过程中不断的设置滚轮的位置来实现滑动的效果。个人觉着在不考虑惯性滑动的情况下使用TouchEvent来处理滑动效果更加理性。