需求是多页显示每页可以添加很多项,涉及到了水平滑动是翻页,垂直滑动列表滚动。遇到的问题是水平滑动有延时,经过测试和查看源码发现,QScroller 属性 QScrollerPropertiesPrivate 有默认值
spp.mousePressEventDelay = qreal(0.25);//0.25s后响应鼠标按下事件
所以需要重新设置属性 MousePressEventDelay,另外还需要注意列表需要设置的滑动对象是 viewport.
QScroller支持鼠标和触摸屏拖拽滑动手势,很好的实现丝滑动画效果。用起来也非常简单,步骤如下:
- 第一步,创建一个QScroller对象,并关联要进行手势操作的组件,支持任何scrolling widget和graphics item
QScroller*scroller = QScroller::scroller(tableView->viewport()); - 第二步,设置要捕获的手势来源
scroller->grabGesture(tableView->viewport(),QScroller::LeftMouseButtonGesture);
其中,第一个参数是目标组件,第二个参数是动作来源,包括:
QScroller::TouchGesture 触摸屏或触控板,水平滑动没问题,垂直滑动就可以任意方向滑动,导致翻页和列表滑动同时进行
QScroller::LeftMouseButtonGesture 鼠标左键
QScroller::MiddleMouseButtonGesture 鼠标中键
QScroller::RightMouseButtonGesture 鼠标右键 - 第三步,定义一个QScrollerProperties用来配置QScroller的具体参数
QScrollerProperties properties = scroller->scrollerProperties(); - 第四步,配置具体参数,参数较多,常用的如下:
properties.setScrollMetric(QScrollerProperties::DragVelocitySmoothingFactor,0.1);//设置平滑滑动速度,当滑动后手离开屏幕后,进行平滑滑动的速度,此值应介于0和1之间。值越小,速度越慢。??实际没区别properties.setScrollMetric(QScrollerProperties::FrameRate,QScrollerProperties::Fps60);//设置滚动过程中画面的刷新率,60帧看着舒服,帧率越低画面越跳动properties.setScrollMetric(QScrollerProperties::DragStartDistance,0.002);//设置移动阀值(按下后需要移动最少多少米距离后,触发滑动),用来避免误操作properties.setScrollMetric(QScrollerProperties::DecelerationFactor,0.5);//设置减速因子,值越大,减速越快,进而会影响点击释放后滚动的距离。对于大多数类型,该值应在0.1到2.0的范围内properties.setScrollMetric(QScrollerProperties::AxisLockThreshold,0.5);//设置当运动方向与某一个轴的角度小于该设定值(0~1)时,则限定只有该轴方向的滚动properties.setScrollMetric(QScrollerProperties::ScrollingCurve,QEasingCurve::OutQuad);//设置当鼠标释放后自动滚动到停止时的运动曲线,参数为QEasingCurve类型,不能设置为QEasingCurve::Type类型,不会隐式转换properties.setScrollMetric(QScrollerProperties::MaximumClickThroughVelocity,0.5);//自动滚动过程中,鼠标点击操作会停止当前滚动,当速度大于该设定(m/s)时,鼠标事件不会传递给目标即不会停止滚动properties.setScrollMetric(QScrollerProperties::AcceleratingFlickMaximumTime ,2);//与AcceleratingFlickSpeedupFactor配合使用。设置一个时间和加速因子,开始自动滚动后,如果在该时间(s)内检测到轻滑加速手势,则滚动速度加速到:当前速度x加速因子,加速因子必须大于等于1.0。加速后的速度也不能超过QScrollerProperties::MaximumVelocity的设定值properties.setScrollMetric(QScrollerProperties::AcceleratingFlickSpeedupFactor,1);//与AcceleratingFlickMaximumTime配合使用,应>=1properties.setScrollMetric(QScrollerProperties::MinimumVelocity,0.1);//设置自动滑动的最小速度,m/s,如果手势的速度小于该速度,则不会触发自动滚动,所以可以设置得小一些properties.setScrollMetric(QScrollerProperties::MaximumVelocity,0.1);//设置自动滚动能达到得最大速度,m/sproperties.setScrollMetric(QScrollerProperties::SnapTime,0.1);//设置滚动曲线的时间因子。设置滚动的时长,值越小,滚动时间越长properties.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy,QScrollerProperties::OvershootWhenScrollable);//设置垂直向允许过量拖拽的策略,可以设置滚动条出现时开启、始终关闭、始终开启三种策略properties.setScrollMetric(QScrollerProperties::OvershootDragResistanceFactor,0.1);//设置过量拖拽的移动距离与鼠标移动距离的比例,0~1,值越小表现出的阻塞感越强properties.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor,0.1);//设置过量拖拽的距离占页面的比例,0~1,比如设置0.5,过量拖拽垂直最多移动高度的一半properties.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor,0.1);//设置自动滚动时允许的过量滚动距离比例,类似于OvershootDragDistanceFactorproperties.setScrollMetric(QScrollerProperties::OvershootScrollTime,0.1);//设置当拖拽过量时,释放后位置恢复所用时间(s)properties.setScrollMetric(QScrollerProperties::MousePressEventDelay,1);//设置鼠标事件延迟时间,单位s。当鼠标按下后,开始手势识别,如果在该时间内开始了拖拽手势,窗口不会收到鼠标事件,相当于取消了点击事件,和滑屏关系不大
默认值://Qt\5.15.2\Src\qtbase\src\widgets\util\qscrollerproperties.cpp
spp.mousePressEventDelay = qreal(0.25);spp.dragStartDistance = qreal(5.0 / 1000);spp.dragVelocitySmoothingFactor = qreal(0.8);spp.axisLockThreshold = qreal(0);spp.scrollingCurve.setType(QEasingCurve::OutQuad);spp.decelerationFactor = qreal(0.125);spp.minimumVelocity = qreal(50.0 / 1000);spp.maximumVelocity = qreal(500.0 / 1000);spp.maximumClickThroughVelocity = qreal(66.5 / 1000);spp.acceleratingFlickMaximumTime = qreal(1.25);spp.acceleratingFlickSpeedupFactor = qreal(3.0);spp.snapPositionRatio = qreal(0.5);spp.snapTime = qreal(0.3);spp.overshootDragResistanceFactor = qreal(0.5);spp.overshootDragDistanceFactor = qreal(1);spp.overshootScrollDistanceFactor = qreal(0.5);spp.overshootScrollTime = qreal(0.7);spp.hOvershootPolicy = QScrollerProperties::OvershootWhenScrollable;spp.vOvershootPolicy = QScrollerProperties::OvershootWhenScrollable;spp.frameRate = QScrollerProperties::Standard;
- 第五步,应用配置参数
scroller->setScrollerProperties(properties);