尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Rust+Slint 实现侧滑菜单栏源码分享
RustSlint 实现侧滑菜单栏源码分享一、效果展示二、源码分享1、工程结构2、main.rs3、build.rs4、main.slint6、Drawer.slint7、Cargo.toml三、实现原理1、状态驱动 UI 更新2、 动画与过渡效果3、 手势交互实现3.1 、按钮点击打开3.2、 右边缘拖拽3.3、 遮罩点击关闭4、 位置计算与约束5、 数据绑定与列表渲染5.1、 数据结构定义5.2、 列表动态渲染6、组件化设计7、响应式布局8、视觉层次与交互反馈9、总结一、效果展示二、源码分享1、工程结构2、main.rsslint::include_modules!();fnmain()-Result(),slint::PlatformError{letmain_windowMainWindow::new()?;main_window.run()}3、build.rsfnmain(){slint_build::compile(ui/main.slint).unwrap()}4、main.slintimport{Drawer}fromDrawer.slint;export componentMainWindowinheritsWindow{preferred-width:700px;preferred-height:700px;title:SideBarView;// 主内容背景 Rectangle{x:0;y:0;width:root.width;height:root.height;background:#f5f6fa;Text{x:24px;y:70px;text:主页;font-size:28px;font-weight:700;color:#2c3e50;}Text{x:24px;y:110px;text:点击左上角按钮或从右边缘拖拽打开侧边栏;font-size:14px;color:#95a5a6;}Rectangle{x:16px;y:16px;width:100px;height:36px;background:btn-touch.pressed?#2980b9:#3498db;border-radius:8px;animate background{duration:150ms;}btn-touch:TouchArea{clicked{drawer.opentrue;}}Text{text:菜单;horizontal-alignment:center;vertical-alignment:center;color:white;font-size:14px;}}}// 抽屉组件 drawer:Drawer{x:0;y:0;width:root.width;height:root.height;drawer-width:320px;// 菜单数据扁平化分组标题 菜单项混合menu-data:[// 常用{is-header:true,title:常用,label:,icon-text:,is-active:false},{is-header:false,title:,label:个人中心,icon-text:,is-active:true},{is-header:false,title:,label:消息通知,icon-text:,is-active:false},{is-header:false,title:,label:收藏夹,icon-text:⭐,is-active:false},// 工具{is-header:true,title:工具,label:,icon-text:,is-active:false},{is-header:false,title:,label:文件管理,icon-text:,is-active:false},{is-header:false,title:,label:下载管理,icon-text:,is-active:false},{is-header:false,title:,label:云存储,icon-text:☁,is-active:false},// 系统{is-header:true,title:系统,label:,icon-text:,is-active:false},{is-header:false,title:,label:设置,icon-text:⚙,is-active:false},{is-header:false,title:,label:帮助与反馈,icon-text:,is-active:false},{is-header:false,title:,label:退出登录,icon-text:,is-active:false},];// ---- 用户卡片通过 children 注入到 Drawer 内容区顶部----Rectangle{x:16px;y:12px;width:parent.width-32px;height:80px;background:#34495e;border-radius:12px;Rectangle{x:16px;y:(parent.height-48px)/2;width:48px;height:48px;background:#3498db;border-radius:24px;Text{text:U;font-size:22px;font-weight:700;color:white;horizontal-alignment:center;vertical-alignment:center;}}Text{x:76px;y:18px;text:用户名;font-size:16px;font-weight:600;color:white;}Text{x:76px;y:42px;text:userexample.com;font-size:12px;color:#8899aa;}}}}6、Drawer.slint// 右侧滑出抽屉组件 — 使用 ListView 实现可滚动菜单import{ListView}fromstd-widgets.slint;exportstructMenuEntry{is-header:bool,title:string,label:string,icon-text:string,is-active:bool,}export componentDrawer{in-out propertyboolopen:false;in-out propertylengthdrawer-width:root.width/2;inproperty[MenuEntry]menu-data:[];propertybooldragging:false;propertylengthdrag-start-x:0px;propertylengthdrag-start-drawer-x:0px;propertylengthcurrent-pointer-x:0px;propertylengthpanel-x:dragging?clamp(drag-start-drawer-x(current-pointer-x-drag-start-x),root.width-drawer-width,root.width,):(open?root.width-drawer-width:root.width);out propertyfloatopen-fraction:clamp((root.width-panel-x)/drawer-width*1.0,0,1,);container:Rectangle{x:0;y:0;width:root.width;height:root.height;background:transparent;clip:true;// 遮罩层 Rectangle{x:0;y:0;width:open?max(0px,root.width-drawer-width):0px;height:root.height;background:black;opacity:open-fraction*0.5;animate opacity{duration:250ms;}overlay-touch:TouchArea{width:parent.width;height:parent.height;clicked{openfalse;}}}// 抽屉面板 Rectangle{y:0;width:drawer-width;height:root.height;x:panel-x;background:#2c3e50;border-top-left-radius:12px;border-bottom-left-radius:12px;visible:panel-xroot.width-1px;animate x{duration:dragging?0ms:280ms;easing:ease-in-out;}// 左侧阴影Rectangle{x:-16px;y:0;width:16px;height:parent.height;background:linear-gradient(90deg,rgba(0,0,0,0),rgba(0,0,0,0.6));}// 标题栏Rectangle{x:0;y:0;width:drawer-width;height:70px;background:#34495e;border-top-left-radius:12px;Text{x:24px;text:菜单;font-size:22px;font-weight:600;color:white;vertical-alignment:center;}Rectangle{x:0;y:parent.height-1px;width:drawer-width;height:1px;background:#ffffff15;}}// 内容区域Rectangle{x:0;y:70px;width:drawer-width;height:root.height-70px;background:#2c3e50;clip:true;// 用户卡片children 注入放在 ListView 上方children// 可滚动菜单列表ListView{x:0;y:92px;width:parent.width;height:parent.height-92px;forentry[index]inmenu-data:Rectangle{height:entry.is-header?32px:52px;background:entry.is-header?transparent:(item-touch.pressed?#ffffff30:(item-touch.has-hover?#ffffff20:transparent));border-radius:entry.is-header?0px:10px;animate background{duration:150ms;}item-touch:TouchArea{x:0;y:0;width:parent.width;height:parent.height;}// ---- 分组标题 ----ifentry.is-header:Rectangle{y:4px;x:20px;height:24px;background:transparent;Text{width:parent.width;text:entry.title;font-size:18px;font-weight:600;color:#f8f8f8;vertical-alignment:center;horizontal-alignment:center;}}// ---- 菜单项 ----if!entry.is-header:Rectangle{x:14px;width:32px;height:32px;y:(parent.height-32px)/2;background:entry.is-active?#3498db:#ffffff20;border-radius:8px;Text{text:entry.icon-text;font-size:16px;color:entry.is-active?white:#aaa;horizontal-alignment:center;vertical-alignment:center;}}if!entry.is-header:Text{x:58px;text:entry.label;font-size:15px;color:entry.is-active?white:#ccc;vertical-alignment:center;}if!entry.is-header:Text{x:parent.width-36px;text:›;font-size:20px;color:#666;vertical-alignment:center;horizontal-alignment:center;width:20px;}}}}}// 右边缘拖拽条 Rectangle{x:root.width-20px;y:0;width:20px;height:root.height;visible:!open;edge-touch:TouchArea{pointer-event(event){ifevent.kindPointerEventKind.down{if!dragging{draggingtrue;drag-start-xself.mouse-x(root.width-20px);drag-start-drawer-xroot.width;current-pointer-xself.mouse-x(root.width-20px);}}ifevent.kindPointerEventKind.move{ifdragging{current-pointer-xself.mouse-x(root.width-20px);}}ifevent.kindPointerEventKind.up{ifdragging{ifpanel-xroot.width-drawer-width/2{opentrue;}else{openfalse;}draggingfalse;}}}}}}}7、Cargo.toml[package]namechartversion0.1.0edition2024[dependencies]slint{version1.16.1,features[renderer-winit-femtovg]}[build-dependencies]slint-build1.16.1三、实现原理本项目的抽屉式侧边栏实现基于 Rust Slint 框架主要包含以下几个核心原理1、状态驱动 UI 更新Slint 采用声明式 UI 编程模型所有界面变化都由状态property驱动。在本项目中open属性控制抽屉的打开/关闭状态dragging属性跟踪用户是否正在拖拽panel-x属性计算抽屉面板的实时 X 坐标位置这些属性通过绑定表达式相互关联当任一属性变化时UI 会自动更新。2、 动画与过渡效果抽屉的平滑动画通过 Slint 的animate关键字实现animate x{duration:dragging?0ms:280ms;easing:ease-in-out;}拖拽时duration: 0ms实现实时跟随手指移动释放时duration: 280ms使用缓动函数实现平滑过渡遮罩透明度animate opacity { duration: 250ms; }实现淡入淡出效果3、 手势交互实现3.1 、按钮点击打开btn-touch:TouchArea{clicked{drawer.opentrue;}}点击左上角按钮时直接将open属性设为true。3.2、 右边缘拖拽edge-touch:TouchArea{pointer-event(event){ifevent.kindPointerEventKind.down{// 开始拖拽记录起始位置}ifevent.kindPointerEventKind.move{// 实时更新面板位置}ifevent.kindPointerEventKind.up{// 根据位置决定最终状态ifpanel-xroot.width-drawer-width/2{opentrue;}else{openfalse;}}}}3.3、 遮罩点击关闭overlay-touch:TouchArea{clicked{openfalse;}}4、 位置计算与约束抽屉面板的位置通过数学计算实现propertylengthpanel-x:dragging?clamp(drag-start-drawer-x(current-pointer-x-drag-start-x),root.width-drawer-width,root.width,):(open?root.width-drawer-width:root.width);clamp()函数确保面板位置在[root.width - drawer-width, root.width]范围内拖拽时基于起始位置和偏移量计算实时位置非拖拽时根据open状态决定最终位置5、 数据绑定与列表渲染5.1、 数据结构定义exportstructMenuEntry{is-header:bool,title:string,label:string,icon-text:string,is-active:bool,}5.2、 列表动态渲染ListView{forentry[index]inmenu-data:Rectangle{// 根据 entry.is-header 渲染不同样式ifentry.is-header:Rectangle{...}if!entry.is-header:Rectangle{...}}}6、组件化设计项目采用模块化设计将抽屉功能封装为独立组件Drawer.slint独立的抽屉组件可复用MainWindow主窗口通过import { Drawer }引入children插槽允许主窗口向抽屉注入自定义内容如用户卡片7、响应式布局相对定位使用root.width、root.height实现自适应百分比计算open-fraction属性计算打开比例动态宽度drawer-width属性可配置默认root.width / 28、视觉层次与交互反馈状态反馈按钮按下状态、菜单项悬停/激活状态阴影效果左侧渐变阴影增强层次感圆角设计面板圆角提升视觉友好度颜色系统使用 Material Design 风格的配色方案9、总结本实现的核心优势性能高效Rust 编译为原生代码无 GC 停顿声明式 UI状态变化自动驱动界面更新手势友好支持点击、拖拽多种交互方式组件化抽屉组件可独立复用动画流畅硬件加速的平滑过渡效果这种实现方式既保证了性能又提供了良好的用户体验适合需要高性能 GUI 的桌面应用场景。
RELATED

相关推荐

C++技能管理器:从面向对象设计到Windows平台实战

C++技能管理器:从面向对象设计到Windows平台实战

简介:本资源是一个面向C游戏开发初学者与中级程序员的技能系统基础框架,聚焦Windows平台下角色技能逻辑的模块化实现,适用于RPG、ACT等类型游戏的技能管理功能开发。压缩包共6个文件(3个头文件.h 3个实现文件.cpp)&am…

📅 2026/10/1 19:48:11
htmx 4.0 发布:跳过 3.0 背后的考量,核心变化与新功能亮点多

htmx 4.0 发布:跳过 3.0 背后的考量,核心变化与新功能亮点多

htmx 4.0 版本发布,因作者曾承诺无 3.0(无破坏性变更),此次跳过 3 直接到 4。该版本历经 8 个月开发,有多项核心变化与新功能。版本号的特殊由来作者 Carson Gross 曾承诺 2.0 后无 3.0,意味着无破坏性变更…

📅 2026/9/10 16:39:30
单视频动态三维实时重构技术白皮书——破解静态模型失真、重塑动态实景孪生

单视频动态三维实时重构技术白皮书——破解静态模型失真、重塑动态实景孪生

单视频动态三维实时重构技术白皮书——破解静态模型失真、重塑动态实景孪生 文档版本:V1.0 编制单位:镜像视界(浙江)科技有限公司 理论与技术支撑:国家十四五重点课题研究、镜像视界浙江普陀时空大数据应用技术联合…

📅 2026/9/20 12:26:50
MORE NEWS

更多资讯

📰

启动报Port 8088 was already in use?先查是谁占的

启动报Port 8088 was already in use?先查是谁占的 项目启动报 Port 8088 was already in use,意思很直白:这个端口已经有人占了。 先说原理:端口是"门牌号",一间房只住一个进程 端口就是一台机器上的门牌号…

📰

担心文档上云?本地运行的办公AI才敢放心用

单位上周开了个会,主题是"AI 提效",散会时领导补了一句:涉及客户资料的文档,不许往云端传。这话一出,会议室里本来跃跃欲试的同事全蔫了——大家平时用的那些在线 AI,文档一上传就不知道存哪儿去…

📰

先能用,再好用:从烂尾复盘到两周上线,全栈项目的‘原型—快速迭代‘方法论

先能用,再好用:从烂尾复盘到两周上线,全栈项目的“原型—快速迭代”方法论 全栈学习路径的文章已经很多了:怎么选技术栈、怎么搭环境、怎么记文档,几乎每个方向都有人写。但一个更扎心的问题很少有人正面讨论——为什…

📰

深度思考模式把 ARC-AGI-2 从 17.6% 拉到 45.1%:对照 Gemini 3 Pro 的三份能力评测,看‘会思考‘改写了哪些边界

深度思考模式把 ARC-AGI-2 从 17.6% 拉到 45.1%:对照 Gemini 3 Pro 的三份能力评测,看“会思考”改写了哪些边界 一、先说结论:变强的不是“知识”,而是“解法” 每次新模型发布,评测榜单都会涨几个点,大…

📰

1.c++入门篇

1.c中的关键字asmdoifreturntrycontinueautodoubleinlineshorttypedefforbooldynamic_castintsignedtypeidpublicbreakelselongsizeoftypenamethrowcaseenummutablestaticunionwchar_tcatchexplicitnamespacestatic_castunsigneddefaultcharexportnewstructusingfriendclassext…

📰

《江灯合声》:有可行的分框版,也仍可以选择连续鸣谢

武汉江岸区栎坡合唱团在免费节目册《江灯合声》中,以表格集中鸣谢资助者。各家共同要求改为独立小框,团里仍想保留表格。现有全名与支持事项清楚可见,双方此前未承诺具体排版。我支持保留表格。补充的试排材料让选择更具体:分框能…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬