您的位置:首页 > 娱乐 > 明星 > 武汉网站seo服务_龙岩app定制开发_免费行情软件网站下载大全_企业seo顾问服务阿亮

武汉网站seo服务_龙岩app定制开发_免费行情软件网站下载大全_企业seo顾问服务阿亮

2025/3/14 9:44:10 来源:https://blog.csdn.net/qianniulaoren/article/details/145902218  浏览:    关键词:武汉网站seo服务_龙岩app定制开发_免费行情软件网站下载大全_企业seo顾问服务阿亮
武汉网站seo服务_龙岩app定制开发_免费行情软件网站下载大全_企业seo顾问服务阿亮

一、触控时代的滚动工具:QScroller类设计介绍

1.1 从机械滚轮到数字惯性

在触控设备普及前,滚动操作如同老式打字机的滚轴,只能通过鼠标滚轮或滚动条进行离散式控制。QScroller的出现如同给数字界面装上了"惯性飞轮",通过模拟物理上的动量守恒定律,让滚动操作具备以下特性:

  • 速度传递:滑动速度决定滚动距离;
  • 动态衰减:摩擦系数影响停止时间;
  • 边界弹性:类似橡皮筋的越界回弹效果;

1.2 类关系拓扑图

QScroller ────┬── QScrollerProperties ├── QScrollEvent └── QScrollPrepareEvent 

QScroller作为控制器,通过QScrollerProperties配置物理参数,生成QScrollEvent事件以驱动界面的刷新。

二、核心类深度解析

2.1 QScroller类:滚动引擎

关键方法说明:

// 启用控件手势支持(核心入口)
static QScroller *QScroller::grabGesture(QObject *target, QScroller::GestureType gestureType = TouchGesture 
);//检查指定的目标对象是否已经关联了 QScroller 实例
static bool hasScroller(QObject *target) ;//使指定的目标对象停止捕获指定类型的滚动手势
static void ungrabGesture(QObject *target, 
QScroller::ScrollerGestureType gestureType);// 获取当前滚动状态 
QScroller::State state() const; // 滚动到指定区域(带动画)
void scrollTo(const QVector2D &pos, qreal scrollTime = 0);// 确保子控件可见(自动计算滚动路径)
void ensureVisible(const QRectF &rect, qreal xmargin = 0.1, qreal ymargin = 0.1);//设置滚动器的属性,如滚动速度、摩擦力、弹性等
void setScrollerProperties(const QScrollerProperties &properties);//启动滚动器,开始滚动操作
void start();//停止滚动器,终止滚动操作
void stop();//设置水平方向的捕捉位置。当滚动到这些位置时,滚动器会自动对齐到这些位置。
void setSnapPositionsX(const QList<qreal> &positions);//设置垂直方向的捕捉位置。当滚动到这些位置时,滚动器会自动对齐到这些位置。
void setSnapPositionsY(const QList<qreal> &positions);

手势类型枚举:

enum GestureType {TouchGesture,        // 触摸手势 LeftMouseButtonGesture, // 左键拖拽RightMouseButtonGesture // 右键拖拽(特殊场景)
};

2.2 QScrollerProperties:设置和调整配置参数

这个类就像汽车的"悬挂调校系统"调节汽车引擎一样,专门调整设置QScroller类的配置参数,包含几十个可配置参数,主要有:

QScrollerProperties properties;//设置滚轮滚动过程中画面的帧率,帧率越高看着越舒服,帧率越低画面越跳动
properties.setScrollMetric(QScrollerProperties::FrameRate,QScrollerProperties::Fps30);
//设置平滑速度,当滑动完手离开屏幕后,进行平滑滑动的速度,此值应介于0和1之间。值越小,速度越慢。但我试过实际没太明显的区别
properties.setScrollMetric(QScrollerProperties::DragVelocitySmoothingFactor,0.3);
//设置鼠标释放后滚动到停止时的运动曲线,参数为QEasingCurve类型,不能设置为QEasingCurve::Type类型,不会隐式转换
properties.setScrollMetric(QScrollerProperties::ScrollingCurve,QEasingCurve::OutQuad);
//设置移动阀值(按下后需要移动最少距离后,触发滑动),用来避免误操作
properties.setScrollMetric(QScrollerProperties::DragStartDistance,0.003);
//设置减速因子,值越大,减速越快,进而会影响点击释放后滚动的距离。对于大多数类型,该值应在0.1到2.0的范围内
properties.setScrollMetric(QScrollerProperties::DecelerationFactor,0.4);
//设置当运动方向与某一个轴的角度小于该设定值(0~1)时,则限定只有该轴方向的滚动,一般就用0.5,两个轴都是,不然要么区域重叠,要么区域漏掉
properties.setScrollMetric(QScrollerProperties::AxisLockThreshold,0.5);
//自动滚动过程中,鼠标点击操作会停止当前滚动,当速度大于该设定(m/s)时,鼠标事件不会传递给目标即不会停止滚动
properties.setScrollMetric(QScrollerProperties::MaximumClickThroughVelocity,0.5);
//与AcceleratingFlickSpeedupFactor配合使用。设置时间及加速因子
properties.setScrollMetric(QScrollerProperties::AcceleratingFlickMaximumTime ,3);
//与AcceleratingFlickMaximumTime配合使用,应>=1
properties.setScrollMetric(QScrollerProperties::AcceleratingFlickSpeedupFactor,2);
//设置自动滑动的最小速度,m/s,如果手势的速度小于该速度,则不会触发自动滚动,所以可以设置得小一些,防止手指轻微移动引起屏幕滚动
properties.setScrollMetric(QScrollerProperties::MinimumVelocity,0.2);
//设置自动滚动能达到得最大速度,m/s
properties.setScrollMetric(QScrollerProperties::MaximumVelocity,0.2);
//设置当拖拽过量时,释放后位置恢复所用时间(s)
properties.setScrollMetric(QScrollerProperties::OvershootScrollTime,0.2);
//设置滚动曲线的时间因子。设置滚动的时长,值越小,滚动时间越长
properties.setScrollMetric(QScrollerProperties::SnapTime,0.2);
//设置过量拖拽的距离占页面的比例,0~1,比如设置0.2,过量拖拽垂直最多移动高度的1/5
properties.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor,0.2);
//设置垂直向允许过量拖拽的策略,可以设置滚动条出现时开启、始终关闭、始终开启三种策略
properties.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy,QScrollerProperties::OvershootWhenScrollable);
//设置过量拖拽的移动距离与鼠标移动距离的比例,0~1,值越小表现出的阻塞感越强
properties.setScrollMetric(QScrollerProperties::OvershootDragResistanceFactor,0.2);
//设置自动滚动时允许的过量滚动距离比例
properties.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor,0.2);
//设置鼠标事件延迟时间,单位s。
properties.setScrollMetric(QScrollerProperties::MousePressEventDelay,1);QScroller::scroller(ui->scrollArea)->setScrollerProperties(properties);

三、实现原理揭秘

3.1 事件处理流水线

sequenceDiagram participant User participant QScroller participant Widget User->>QScroller: 触摸/鼠标按下 QScroller->>Widget: 发送ScrollPrepare事件 Widget->>QScroller: 返回内容尺寸等信息 loop 每帧更新 QScroller->>QScroller: 计算物理运动参数 QScroller->>Widget: 发送ScrollEvent Widget->>Widget: 更新显示位置 end User->>QScroller: 释放操作 QScroller->>Widget: 触发惯性滚动 

3.2 物理模型公式

滚动位置计算采用改进型牛顿运动方程:

当前位置 = 初始位置 + 初速度 * t - 0.5 * 摩擦系数 * t²

其中摩擦系数通过QScrollerProperties::DecelerationFactor动态调整


四、实用代码示例

4.1 基础滑动实现

// 为QListWidget启用触控滑动 
QListWidget *list = new QListWidget(this);
QScroller *scroller = QScroller::scroller(list->viewport());
QScroller::grabGesture(list->viewport(), QScroller::TouchGesture);// 配置滑动参数(类似手机APP的流畅感)
QScrollerProperties prop = scroller->scrollerProperties();
prop.setScrollMetric(QScrollerProperties::DragVelocitySmoothingFactor,  0.6);
prop.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor,  0.3);
scroller->setScrollerProperties(prop);

4.2 高级分页滚动

// 相册浏览分页效果 
QScrollArea *gallery = new QScrollArea(this);
QScroller::grabGesture(gallery, QScroller::LeftMouseButtonGesture);QScrollerProperties prop;
prop.setScrollMetric(QScrollerProperties::SnapPositionRatio,  1.0); // 整页吸附 
prop.setScrollMetric(QScrollerProperties::SnapTime,  0.5);         // 过渡动画时长 
QScroller::scroller(gallery)->setScrollerProperties(prop);

五、性能优化指南

  1. 渲染优化
// 启用像素级滚动(避免跳跃感)
listWidget->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
  1. 内存管理
// 及时释放不再使用的滚动器
QScroller::ungrabGesture(scrollArea); // 类似断开刹车系统
  1. 动态调参技巧
// 根据设备类型切换参数 
#ifdef Q_OS_ANDROID prop.setScrollMetric(...);  // 移动端优化参数 
#else prop.setScrollMetric(...);  // 桌面端参数 
#endif 

结语:滚动交互的未来

随着Qt6对QScroller的持续优化,已经未来产品更趋向于实际流畅感的需求,作为开发使用人员,这几个方面的优化值得我们关注使用:

  1. 多指操作与3D滚动集成
  2. 基于AI的动态参数调优
  3. 与Vulkan渲染引擎的深度结合

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com