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

【Rust GUI开发入门】编写一个本地音乐播放器(5. 制作音乐列表组件) - Jordan

目的是要做一个这样的音乐列表组件:

songlist-view.png

包含:

  • 一个标题栏
  • 多个列表项

制作标题栏

需要在标题栏上显示排序图标,实现点击排序功能,因此额外需要定义一个枚举类型SortKey指示排序依据。这里的排序图标也手动绘制,不使用网络上的图标:

@rust-attr(derive(serde::Serialize, serde::Deserialize))
export enum SortKey {BySongName,BySinger,ByDuration,
}component SortIcon inherits Window {in-out property <bool> ascending:true;in-out property <bool> display:true;height: 15px;width: 15px;background: transparent;if !ascending && display: Path {MoveTo {x: 5;y: 1;}LineTo {x: 5;y: 9;}LineTo {x: 7;y: 7;}stroke: gray;stroke-width: 1px;}if ascending && display:Path {MoveTo {x: 5;y: 9;}LineTo {x: 5;y: 1;}LineTo {x: 3;y: 3;}stroke: gray;stroke-width: 1px;}
}component TitleBarItem inherits Window {in property <string> name:"name";in-out property <bool> display-sort-icon <=> arrow.display;in-out property <bool> ascending-sort <=> arrow.ascending;Rectangle {width: 100%;height: 100%;text := Text {text: name;color: dimgray;x: parent.width * 0.4;y: parent.height / 2 - self.height / 2;}arrow := SortIcon {ascending: true;width: 12px;height: 12px;x: text.x + text.width + 5px;y: parent.height / 2 - self.height / 2;}}
}export component TitleBar inherits Window {height: 30px;in-out property <SortKey> key;in-out property <bool> ascending;callback sort-items(SortKey, bool);VerticalLayout {HorizontalLayout {alignment: space-between;area1 := TouchArea {width: 33%;clicked => {sort-items(SortKey.BySongName, ascending);}TitleBarItem {width: 100%;height: 100%;name: @tr("Title");background: area1.has-hover ? Palette.control-background : transparent;display-sort-icon: key == SortKey.BySongName;ascending-sort: ascending;}}area2 := TouchArea {width: 33%;clicked => {sort-items(SortKey.BySinger, ascending);}TitleBarItem {name: @tr("Artist");height: 100%;width: 100%;background: area2.has-hover ? Palette.control-background : transparent;display-sort-icon: key == SortKey.BySinger;ascending-sort: ascending;}}area3 := TouchArea {width: 33%;clicked => {sort-items(SortKey.ByDuration, ascending);}TitleBarItem {name: @tr("Duration");height: 100%;width: 100%;background: area3.has-hover ? Palette.control-background : transparent;display-sort-icon: key == SortKey.ByDuration;ascending-sort: ascending;}}}Path {width: 100%;height: 5px;MoveTo {x: 0;y: 0;}LineTo {x: 100%;y: 0;}stroke: Palette.foreground;stroke-width: 0.3px;}}
}

制作列表项

每个列表项关联一首歌曲,显示其相关信息:

  • 歌名
  • 歌手
  • 时长

因此额外定义了一个SongInfo结构体。此外,双击该列表项会触发音乐播放,所以对外暴露一个double-clicked回调函数:

export struct SongInfo {id:int,song_name:string,singer:string,duration:string,song_path:string,
}export component SongItem inherits Window {height: 30px;in property <SongInfo> info:{ id:0, song_name:"xxx", singer:"xxx", duration:"xxx", song_path:"xxx" };callback double_clicked();background: area.has-hover ? Palette.control-background : transparent;VerticalLayout {area := TouchArea {double-clicked => {double_clicked();}HorizontalLayout {alignment: space-between;Rectangle {width: 33%;Text {width: 100%;x: parent.width * 0.4;text: info.song-name;overflow: elide;}}Rectangle {width: 33%;Text {width: 100%;x: parent.width * 0.4;text: info.singer;overflow: elide;}}Rectangle {width: 33%;Text {x: parent.width * 0.4;text: info.duration;}}}}Path {width: 100%;height: 1px;MoveTo {x: 0;y: 0;}LineTo {x: 100%;y: 0;}stroke: Palette.foreground;stroke-width: 0.15px;}}
}

把二者组合起来

使用Slint UI的内置ListView组件来渲染多个音乐项,然后竖直堆叠标题栏和这个ListView

export component SongListView inherits Window {in-out property <bool> ascending;in-out property <SortKey> sort-key;in-out property <SortKey> last-sort-key;in-out property <[SongInfo]> song-list;callback sort-songs(SortKey, bool);callback play-song(SongInfo, TriggerSource);VerticalLayout {width: 100%;height: 100%;TitleBar {ascending: root.ascending;key: root.sort-key;sort-items(key, ascending) => {if (root.last-sort-key == key) {root.sort-songs(key, !ascending);} else {root.sort-songs(key, true)}}}ListView {for item in root.song-list: SongItem {info: item;double_clicked => {root.play-song(item, TriggerSource.ClickItem);}}}}
}
http://www.hskmm.com/?act=detail&tid=21574

相关文章:

  • 【Nordic】nRF9151的SLM例程常用AT指令说明
  • sql server经典语句「转」
  • Codeforces 2149G Buratsuta 3 题解 [ 蓝 ] [ 摩尔投票 ] [ 线段树 ] [ 随机化 ] [ 主席树 ] [ 根号分治 ]
  • 2025 年最新推荐软件开发机构榜:聚焦微服务架构与 724 小时服务的优质厂商精选指南人力资源管理系统/资产管理系统/数据中台管理系统/流程管理系统软件开发公司推荐
  • 【半导体物理 | 学习笔记】第一章 半导体中的电子状态
  • 计数(5):多项式相关
  • 最新WTAPI开发微信机器人教程说明
  • 线性DP - 学习笔记
  • 2025 年最新制氮机厂家权威推荐排行榜:聚焦行业优质厂商综合实力,助力企业精准选购优质设备制氮机产生氮气/氮气纯化/设备改造/维修/保养/半导体用制氮机厂家推荐
  • 2025 年氨分解设备厂家最新推荐榜单:含半导体 / 冶金 / 稀土行业专用设备及品牌综合实力排名
  • 2025 阳台装修公司推荐榜:最新优质厂商资质 / 技术 / 服务测评,杭州浙江地区优选指南杭州阳台装修/浙江阳台装修公司推荐
  • bitset
  • 网易雷火胡志鹏:AI驱动未来,游戏科技重塑虚拟创造力与现实生产力
  • idea打包推送maven仓库及同时推送到不同的maven仓库,本地和云上的腾讯云
  • 2025 阳台柜厂家最新推荐榜:企业资质 / 材质 / 服务全景解析,选对品牌少走弯路杭州阳台柜/浙江阳台柜厂家推荐
  • 2025 年除湿机厂家最新权威推荐排行榜:实力厂家技术口碑评测及场景适配选购指南吊顶/泳池/车库/防爆/调温/新风除湿机厂家推荐
  • 2025 年液氨蒸发器厂家联系方式,众众电热:多领域加热设备供应与定制化解决方案提供商
  • 【Batch】批量修改文件后缀
  • 【solace】基于docker部署solace环境
  • 2025 年阿里巴巴开通实力商家店铺开通代运营 / 阿里巴巴新手开店全托管代运营公司推荐:南鑫粤网络 —— 全域运营解决方案与实战服务优势解析
  • Vue-element-admin开发指南 - 教程
  • 2025 年国内工作服厂家最新推荐排行榜:聚焦工艺设计与服务,精选权威榜单助企业采购冬季/春季/工人/车间/防静电/餐饮/劳保工作服厂家推荐
  • ClickHouse 窗口函数使用详解(一) - 若
  • ClickHouse 窗口函数详解:告别 GROUP BY 的局限性,实现灵活数据分析 - 若
  • 简单WEB网站
  • AtCoder AGC044 总结
  • UOJ#32【UR #2】跳蚤公路 题解
  • 2025 年窗帘杆源头厂家最新推荐榜单:包含支架 / 环 / 全自动 / 可伸缩等多类产品及配件,帮助选到品质与交期双优的优质厂家
  • 2025 年电动窗帘厂家推荐榜单:聚焦国内优质企业定制实力与口碑,为采购者提供最新选择参考电动窗帘系统/电机/轨道/配件/智能电动窗帘厂家推荐
  • Vue3 使用注意事项