当前位置: 首页 > news >正文

【QML实战】打造丝滑体验:自定义滚动条详解-“延时隐藏”效果

【QML实战】打造丝滑体验:自定义滚动条详解-“延时隐藏”效果

  • 一、自定义滚动条详解
    • 1、使用 `ScrollBar` 组件(Qt 5.8+)
    • 2、完全自定义滚动条逻辑
    • 3、关键属性说明
    • 4、样式定制技巧
    • 5、交互增强
  • 二、效果展示
    • 1、效果展示
    • 2、源码分享

一、自定义滚动条详解

在 QML 中自定义滚动条通常需要结合FlickableListView等可滚动控件,通过覆盖默认样式或完全重写逻辑实现。以下是两种常见方法:

1、使用ScrollBar组件(Qt 5.8+)

从 Qt 5.8 开始,官方提供了ScrollBar组件,可直接替换默认滚动条:

Flickable{id:flick width:200height:200contentWidth:400contentHeight:400ScrollBar.vertical:ScrollBar{id:vbar policy:ScrollBar.AlwaysOn width:10background:Rectangle{color:"lightgray"}contentItem:Rectangle{color:"darkgray"radius:5}}}

2、完全自定义滚动条逻辑

若需更深度定制,可手动计算位置和尺寸:

Flickable{id:flick width:200height:200contentWidth:400contentHeight:400Rectangle{id:track width:8anchors.right:parent.right height:parent.height color:"#e0e0e0"Rectangle{id:handle width:parent.width height:flick.visibleArea.heightRatio*track.height y:flick.visibleArea.yPosition*track.height color:"#707070"radius:4Behavior on y{SmoothedAnimation{duration:150}}}}}

3、关键属性说明

  • visibleArea.heightRatio:滚动条手柄高度与内容高度的比例
  • visibleArea.yPosition:当前滚动位置的比例值(0.0-1.0)
  • policy:控制滚动条显示策略(AlwaysOn/AlwaysOff/AsNeeded

4、样式定制技巧

通过修改以下属性实现视觉定制:

contentItem:Rectangle{color:"customColor"radius:3border.width:1border.color:"darkColor"}background:Rectangle{color:"trackColor"opacity:0.5}

5、交互增强

添加鼠标区域实现拖动交互:

MouseArea{anchors.fill:handle drag.target:handle drag.axis:Drag.YAxis drag.minimumY:0drag.maximumY:track.height-handle.height onPositionChanged:{if(drag.active){flick.contentY=handle.y/(track.height-handle.height)*(flick.contentHeight-flick.height)}}}

二、效果展示

1、效果展示

2、源码分享

importQtQuickimportQtQuick.ControlsimportQtQuick.LayoutsimportQtQuick.Controls.BasicApplicationWindow{id:root visible:truewidth:400height:600title:"QML 自定义延时滚动条"// 定义滚动条的隐藏延时时间(毫秒)propertyintscrollBarHideDelay:2000ColumnLayout{anchors.fill:parent anchors.margins:20spacing:10Label{text:"向下滚动查看效果,停止操作后滚动条将在2秒后自动消失。"wrapMode:Text.WordWrap Layout.fillWidth:truefont.pixelSize:14color:"#333333"}// 核心容器:FlickableFlickable{id:flickableContent Layout.fillWidth:trueLayout.fillHeight:trueclip:truecontentHeight:columnContent.height// 内容区域Column{id:columnContent width:flickableContent.width spacing:15Repeater{model:50// 生成50个条目以产生滚动delegate:Rectangle{width:parent.width height:60color:index%2===0?"#f0f0f0":"#e0e0e0"radius:8Text{text:"列表项 #"+(index+1)anchors.centerIn:parent font.pixelSize:18font.bold:truecolor:"#555555"}}}}// --- 自定义垂直滚动条开始 ---ScrollBar.vertical:ScrollBar{id:customVScrollBar active:flickableContent.ScrollBar.active// 初始跟随系统激活状态// 视觉样式:圆角矩形滑块policy:ScrollBar.AlwaysOn// 我们手动控制可见性,所以设为AlwaysOn以便监听visible:opacity>0.01// 当透明度几乎为0时隐藏,避免阻挡鼠标事件background:Rectangle{implicitWidth:10color:"transparent"// 背景透明}contentItem:Rectangle{implicitWidth:10radius:width/2color:customVScrollBar.pressed?"#0078D7":"#cccccc"// 平滑过渡动画Behavior on color{ColorAnimation{duration:150}}}// 状态机:控制显示和隐藏states:[State{name:"visible"PropertyChanges{target:customVScrollBar opacity:1.0}},State{name:"hidden"PropertyChanges{target:customVScrollBar opacity:0.0}}]// 默认状态设为可见(初始化时)state:"visible"// 动画:透明度渐变transitions:Transition{NumberAnimation{properties:"opacity"duration:400easing.type:Easing.OutQuad}}// --- 核心逻辑:延时隐藏控制器 ---Timer{id:delayTimer interval:root.scrollBarHideDelay running:falserepeat:falseonTriggered:{// 定时器结束,切换到隐藏状态// 只有当鼠标不在滚动条上时,才真正隐藏if(!customVScrollBar.hovered){customVScrollBar.state="hidden"}}}// 事件监听onActiveChanged:{if(active){// 当用户开始滚动,立即显示并重置定时器customVScrollBar.state="visible"delayTimer.restart()}else{// 滚动停止,启动定时器delayTimer.start()}}onHoveredChanged:{if(hovered){// 鼠标移入:立即显示,停止定时器(防止鼠标指着时突然消失)customVScrollBar.state="visible"delayTimer.stop()}else{// 鼠标移出:如果当前正在滚动,则不处理(由onActiveChanged接管)// 如果没在滚动,则启动定时器准备隐藏if(!active){delayTimer.start()}}}}// --- 自定义垂直滚动条结束 ---}}}

http://www.jsqmd.com/news/478045/

相关文章:

  • Node版本切换不求人:手把手教你用nvm离线安装指定版本Node.js
  • Github 狂取12k star,堪称终端版Postman,也太炫酷了!
  • 从零实现KNN:构建手写数字识别引擎的实战指南
  • Wan2.1-umt5实时翻译效果实测:支持多语种互译与领域适配
  • 从零开始理解DO-254:航空电子硬件的安全性与可靠性设计
  • Qwen-Image-2512-Pixel-Art-LoRA 与MySQL集成:构建带管理后台的素材库系统
  • pyproj.Geod.inv方法全解析:从参数说明到椭球模型选择指南
  • 通义千问1.5-1.8B-Chat-GPTQ-Int4 WebUI 计算机组成原理教学应用:自动生成习题与解答
  • ACWing 3380. 质因数的个数
  • 大模型工具调用实战:为什么我放弃了System Message传参改用tools参数?
  • OFA视觉问答模型实战教程:Pillow+requests+ModelScope协同调用
  • 法奥程序Modbus标定
  • 优惠券系统避坑指南:从美团实践中学到的5个关键设计原则
  • 立创EDA开源项目:ALL IN ONE全统一超高速HUB硬件设计与实现全解析
  • 立创开源Type-C超声波切割刀DIY全解析:从STC8H驱动到GU-18脉冲变压器设计
  • HY-Motion 1.0应用实战:快速生成游戏角色动作,提升开发效率
  • Hugging Face国内镜像加速实战:5分钟搞定模型下载慢的问题
  • 移植numworks图形计算器:7.移植LCD驱动——添加到numworks中
  • IMYAI视频创作系统部署实战:海外服务器配置与8大AI模型接入避坑指南
  • ollama部署本地大模型|embeddinggemma-300m在金融研报相似度分析应用
  • 成为管理者后,必须持续塑造更强的自己
  • 基于 51 单片机的空气浓度检测系统仿真:打造身边的空气卫士
  • ESP8684-WROOM-04C射频特性深度解析与工程落地指南
  • Linux网络驱动开发:PHY状态机与链路检测机制详解(附实战代码分析)
  • 进程资源限制与性能优化实践
  • 【生产实践】基于Docker Compose的StarRocks高可用集群部署与调优指南
  • Spring Boot 3.5.x 实战:SpringDoc 2 与 Swagger3 的深度集成与配置优化
  • 次元画室教程:锁定“风格密码”,批量产出AE可用素材(附案例)
  • 微前端架构实战:从原理到框架选型
  • C语言快速入门10-结构体