Qt關于平滑滾動的使用QScroller及QScrollerProperties類說明

一、觸控時代的滾動工具: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 * 摩擦系數 * t2

其中摩擦系數通過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渲染引擎的深度結合

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/72267.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/72267.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/72267.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JavaAPI(網絡編程)

網絡通信協議 通信協議 ?所謂通信協議&#xff0c;是指通信雙方在進行數據交換時必須遵守的規則和約定。?這些規則確保了雙方能夠有效地進行通信&#xff0c;實現信息的交換和資源共享。通信協議定義了傳輸時的數據格式、控制信息以及傳輸順序和速度等&#xff0c;確保雙方…

Java---入門基礎篇(下)---方法與數組

前言 本篇文章主要講解有關方法與數組的知識點 ,是基礎篇的一部分 , 而在下一篇文章我會講解類和對象的知識點 入門基礎篇上的鏈接給大家放在下面啦 ! Java---入門基礎篇(上)-CSDN博客 感謝大家點贊&#x1f44d;&#x1f3fb;收藏?評論?&#x1f3fb; 歡迎各位大佬指點…

Python 爬蟲 – BeautifulSoup

Python 爬蟲&#xff08;Web Scraping&#xff09;是指通過編寫 Python 程序從互聯網上自動提取信息的過程。 爬蟲的基本流程通常包括發送 HTTP 請求獲取網頁內容、解析網頁并提取數據&#xff0c;然后存儲數據。 Python 的豐富生態使其成為開發爬蟲的熱門語言&#xff0c;特…

圖像分類項目1:基于卷積神經網絡的動物圖像分類

一、選題背景及動機 在現代社會中&#xff0c;圖像分類是計算機視覺領域的一個重要任務。動物圖像分類具有廣泛的應用&#xff0c;例如生態學研究、動物保護、農業監測等。通過對動物圖像進行自動分類&#xff0c;可以幫助人們更好地了解動物種類、數量和分布情況&#xff0c;…

物聯網 智慧園區井蓋管理辦法和功能介紹

在園區內實現 智慧井蓋 的定位、內部氣體檢測和紅外監測等頂級功能&#xff0c;可以顯著提升園區的安全管理水平和運維效率。以下是智慧井蓋系統的詳細設計方案和功能實現&#xff1a; 一、系統架構 智慧井蓋系統可以分為以下層次&#xff1a; 1. 感知層 定位模塊&#xff1…

零基礎deep seek+剪映,如何制作高品質的視頻短片

以下是專為零基礎學習者設計的 剪映專業版詳細教程&#xff0b;Deep seek配合制 &#xff0c;包含從入門到精通的系統化教學&#xff0c;配合具體操作步驟與實用技巧&#xff1a; 基于DeepSeek與剪映協同制作高品質視頻短片的專業流程指南&#xff08;2025年最新實踐版&#x…

PHP:IDEA開發工具配置XDebug,斷點調試

文章目錄 一、php.ini配置二、IDEA配置 一、php.ini配置 [xdebug] zend_extension"F:\wamp64\bin\php\php7.4.0\ext\php_xdebug-2.8.0-7.4-vc15-x86_64.dll" xdebug.remote_enable on xdebug.remote_host 127.0.0.1 xdebug.remote_port 9001 xdebug.idekey"…

改進YOLOv8模型的空間注意力機制研究:RFAConv的貢獻與實現

文章目錄 1. 背景介紹2. 什么是RFAConv?3. YOLOv8中的RFAConv實現3.1 RFAConv模塊設計3.2 在YOLOv8中集成RFAConv4. 性能對比與實驗結果4.1 實驗設置4.2 實驗結果5. 模型優化與調優5.1 調整RFAConv模塊的超參數5.2 數據增強策略5.3 更深層的注意力機制5.4 混合卷積與優化計算圖…

【Java】使用jdk自帶的zip壓縮實現任意文件壓縮打包下載功能(復制即用)

前言 在實際項目中&#xff0c;我們可能會接到將文件或者資料打包壓縮導出的需求&#xff0c;例如將系統中某些生成的文件一起打包壓縮下載提供給客戶使用&#xff0c;今天提供一個jdk自帶的工具類快速實現打包壓縮的功能&#xff0c;方法我已經封裝好&#xff0c;大家如果在項…

騰訊云擴容記錄

騰訊云擴容&#xff1a; sudo yum install -y cloud-utils-growpart 安裝擴容工具 sudo file -s /dev/vda1 有數據 sudo LC_ALLen_US.UTF-8 growpart /dev/vda 1 sudo resize2fs /dev/vda1 df -Th 完畢 以下是對執行的命令的詳細解釋以及背后的原理&#xff1a; 1. 安裝 cloud…

服務流程設計和服務或端口重定向及其websocket等應用示例

服務流程設計和服務或端口重定向及其websocket等應用示例 目錄 服務或端口重定向的服務設計和websocket等應用示例 一、通用請求控制流程 1.1、入口 1.2、所有GET請求首先預檢控制單元 1.3、http請求會分別自動307重定向 1.4、所有請求首先執行跨源控制單元 1.5、然后…

PHP面試題--后端部分

本文章持續更新內容 之前沒來得及整理時間問題導致每次都得找和重新背 這次整理下也方便各位小伙伴一起更輕松的一起踏入編程之路 歡迎各位關注博主不定期更新各種高質量內容適合小白及其初級水平同學一起學習 一起成為大佬 數組函數有那些 ps&#xff1a;本題挑難的背因為…

深入了解 MySQL 中的 JSON_CONTAINS

深入了解 MySQL 中的 JSON_CONTAINS MySQL 5.7 及更高版本引入了對 JSON 數據類型的支持&#xff0c;使得在數據庫中存儲和查詢 JSON 數據成為可能。在這些新功能中&#xff0c;JSON_CONTAINS 函數是一個非常有用的工具&#xff0c;允許我們檢查一個 JSON 文檔是否包含特定的值…

git命令學習記錄

1. git reset 參數說明 git reset 是用來回退版本的&#xff0c;它可以添加三個參數&#xff0c;常用的使用格式是這樣的&#xff1a;git reset [--hard | --soft | --mixed] 版本號 一般使用git修改文件并提交需要三步&#xff0c;第一步在文本編輯器中編輯文件&#xff0c;也…

使用DeepSeek+KIMI生成高質量PPT

一、使用DeepSeek DeepSeek官網&#xff1a;DeepSeek 點擊“開始對話”&#xff0c;進入交互頁面。 在上圖中&#xff0c;輸入問題&#xff0c;即可獲取AI生成的結果。 基礎模型&#xff08;V3&#xff09;&#xff1a;通用模型&#xff08;2024.12&#xff09;&#xff0c;高…

深度學習工程師的技術圖譜和學習路徑

在構建一個深度學習工程師的技術圖譜時,按照“技能樹與能力模型”的結構可以幫助清晰地展示出技術體系的層次化關系,幫助學習者更好地理解每個技術點的依賴與順序。 深度學習工程師的技術圖譜和學習路徑 以下是深度學習工程師的技能樹,包括從基礎到進階的學習路徑,以及對…

RabbitMQ系列(五)基本概念之Queue

在 RabbitMQ 中&#xff0c;Queue&#xff08;隊列&#xff09; 是存儲消息的容器&#xff0c;也是消息傳遞的核心載體。以下是其核心特性與作用的全方位解析&#xff1a; 一、Queue 的定義與核心作用 消息存儲容器 Queue 是 RabbitMQ 中實際存儲消息的實體&#xff0c;生產者…

MySQL—使用binlog日志恢復數據

一、binlog日志恢復數據簡介 在 MySQL 中&#xff0c;使用二進制日志&#xff08;binlog&#xff09;恢復數據是一種常見的用于故障恢復或數據找回的方法。以下是詳細的使用步驟&#xff1a; 確認 binlog 已啟用&#xff1a;首先需要確認 MySQL 服務器已經啟用了二進制日志功…

VADv2: 基于矢量表征和概率規劃的E2E架構

1. 寫在前面 今天分享一篇自動駕駛領域的論文VADv2(End-to-End Vectorized Autonomous Driving via Probabilistic Planning), 基于矢量表征和概率規劃的E2E架構,2024年2月份華中科技大和地平線合作的一篇文章, 在經典的端到端模型架構上作出了基于概率規劃去輸出規劃軌跡的…

NLP11-命名實體識別(NER)概述

目錄 一、序列標注任務 常見子任務 二、 命名實體識別&#xff08;NER&#xff09; &#xff08;一&#xff09;簡介 &#xff08;二&#xff09;目標 &#xff08;三&#xff09;應用場景 &#xff08;四&#xff09;基本方法 &#xff08;五&#xff09;工具與資源 一…