文章目录
文件大小40M,欢迎下载体验!点击下载
一.前言
天涯的尽头是风沙,红尘的故事叫牵挂~
打磨了一段时间的fun音乐播放器和大家见面了!本次给大家带来一款我自己独立开发的简约美观的音乐播放器,整体UI风格比较简约不简单。
二.相关知识
1.PyQt5
PyQt5 是 Python 绑定 Qt 应用程序框架的一个库,它用于开发跨平台的桌面应用程序。PyQt5 由 Riverbank Computing 维护,基于 Qt 5 框架,提供了丰富的 GUI 组件和强大的功能,包括窗口控件、布局管理、信号槽机制、多线程支持、绘图、网络编程等。
PyQt5 的特点:
✅ 跨平台支持:可在 Windows、macOS 和 Linux 上运行。
✅ 强大的 GUI 组件:提供 Qt Designer 可视化设计 UI,支持拖拽控件布局。
✅ 信号槽机制:提供高效的事件处理系统,使 UI 响应更加流畅。
✅ QSS 样式表:类似 CSS,可以美化 UI 组件。
✅ 集成多媒体支持:基于 QtMultimedia,可实现音频、视频播放功能。
摘自chat GPT
2.苹果系统风格
苹果系统 UI 风格简洁、优雅,强调 扁平化设计、圆角矩形、半透明毛玻璃效果 和 流畅动效。它注重 一致性 和 直觉化交互,支持 深色模式、手势控制,并通过 生态整合(如 Handoff、AirDrop)提供无缝体验。整体风格现代、精致,专注于内容呈现和用户体验优化。
本次GUI风格模仿苹果系统风格,包括不限于窗口控制、音乐播放控制区域样式
不得不说,苹果这UI风格真漂亮!
3.高斯模糊
高斯模糊(Gaussian Blur) 是一种基于 高斯函数 的图像平滑处理技术,常用于 去噪、虚化背景、边缘检测 等。它通过 高斯卷积核 对图像进行平滑处理,使像素值按高斯分布加权平均,从而产生 柔和、自然的模糊效果。高斯模糊广泛应用于 图像处理、计算机视觉 以及 UI 设计中的毛玻璃效果。
三.展示
预览一张!
1.主界面
大家通过安装包安装好后,启动软件就能到软件的主界面,下图就是软件首页
2.推荐歌单
推荐歌单页面展示了多个推荐的歌单,推荐歌单是支持无限下拉加载数据的,另外推荐歌单的列数也会随着窗口缩放改变。
3.音乐小屋
音乐小屋其实是笔者的一个巧思,这个页面存放着用户的本地操作比如最近播放与收藏
4.播放页面
歌曲信息始终在窗体右侧展示,右侧包含了歌曲的封面和基本信息以及滚动歌词区域。
笔者真的很喜欢这个背景高斯模糊效果。
四.心得体会
1.重写表格
细心的读者可以观察到,本次的歌曲列表并不是用的原生的QTableWidget,本次笔者使用网格布局+滚动区域手搓了一个表格组件,高度自定义化:
- 表头和数据对齐
- 加入自定义横向分割线
- 加入自定义组件控制播放列表和歌曲
2.高斯模糊
如果您喜欢本软件,肯定是被界面的高斯模糊效果给吸引了,这里确实是真实的高斯模糊:首先将图片转换为可处理的格式,然后调整大小以适应窗口,并应用高斯模糊。处理完成后,将模糊后的图片存储并触发界面刷新。绘制时,会先渲染模糊背景,再叠加一个透明度较低的黑色遮罩,使整体视觉效果更柔和。
3.歌词同步
歌词区域会根据当前播放的歌词进行高亮展示,代码会自动匹配当前正在播放的那句歌词,具体的匹配逻辑我贴一下源代码:
def find_lyric_index(self, position) -> int:
# 歌词的时间列表
index = 0
try:
times = list(zip(*self.lyrics))[1]
# 获取序号
times = [*times, position]
index = sorted(times).index(position)
# 不重合则减一
if times.count(position) < 2:
index = index - 1
except:
pass
return index
4.项目代码结构
从前几篇开始,笔者开始加入项目结构这个模块,原因是有的读者私聊我,让我介绍一下项目结构,在此我截图贴一下我的代码结构。
整体代码行数2500行左右
5.无限下拉实现
下载了本软件的朋友会发现推荐歌单部分是支持无线下拉的,具体来说:
通过绑定滚动条的 valueChanged 事件到 load_more_playlist,当滚动条的值达到最大(即滚动到底部)时,load_more_playlist 递增 page 并调用 load_playlist 加载新数据,而 load_playlist 通过 subThread 线程异步获取数据,完成后触发 add_play_list 更新界面,同时将线程存入 thread_list 进行管理,从而保证界面流畅不卡顿,实现无限滚动加载的效果,具体的代码片段见下图:
6.缓存处理
有的读者可能会感觉到:软件运行好快呀尤其是图片,这是因为我们做了缓存处理,所有加载网络or本地图片都会经过下面的函数,此函数会根据图片的特征判断是去加载网络图片还是本地缓存图片。具体来说是:
首先创建一个空的 QPixmap,如果 url 为空则直接返回,否则检查 main_conf.cache_cover_dir 目录下是否已有对应缓存文件,若存在则直接加载,否则通过 self.e.do_request(url, **args) 下载图片数据并用 pix.loadFromData(pix_data) 加载,同时调用 do_cache_cover(file_name, pix_data) 将图片缓存,若下载失败则捕获异常并打印错误,最终通过 self.pixmap_finished.emit(pix) 发送信号返回图片。
7.播放控制区域透明化
播放控制区域整体是黑色半透明的,所有按钮颜色都是白色的,这样对比度的差异可以让我们适应不同颜色的高斯模糊背景图,具体来说:
PlayControlArea 继承自 QFrame,用于创建音乐播放器的播放控制区域。它包含四个主要部分:播放控制按钮(上一首、播放/暂停、下一首、播放模式)、进度条(显示当前播放时间和进度)、音量控制(音量按钮和滑动条)以及整体布局管理。通过 set_ui_ui() 设置按钮图标,并使用 setStyleSheet() 统一应用样式,使界面美观且功能完整。
我这里给朋友们贴出完整的代码片段
每一个组件都是自定义组件,都是能单独执行、调试的
8.点击下载分享
用户把鼠标放到具体某一行歌曲上的时候,会展示一些圆形操作按钮,具体包括:播放、下载、分享、添加到播放列表、收藏,这里和大家聊一下下载和分享
我们定义了SingleControlWidget这个组件,会判断用户鼠标是否在指定的区域内,继而来控制此组件的显隐,自定义了btn_clicked信号,发射str, dict的数据,分别是操作和歌曲信息。
然后我们在主界面连接这个信号,用于实现具体的操作功能
其中下载、分享之前都需要先获取歌曲链接,我们这里定义了一个线程,如果真的拿到了播放链接再进行后续操作,这里用下载举例子
在 PyQt5 中使用线程的主要好处是避免阻塞 GUI 主线程,从而保持界面流畅和响应用户交互。由于 PyQt5 的事件循环运行在主线程中,如果执行耗时操作(如网络请求、文件读取或复杂计算)而不使用线程,界面可能会卡顿甚至无响应。通过 QThread 或 QtConcurrent 将耗时任务放入后台线程处理,可以提升程序的并发性,同时确保 GUI 线程专注于界面更新和用户交互,提高应用的整体性能和用户体验。
五.代码运行方式
本项目是在Python3.8环境下开发的
Python3.8可以点击这里下载
使用项目根目录requirements.txt
pip install -r requirements.txt
这里要强调一下
Pillow==9.3.0
否则会遇到
requirements.txt的内容为:
Pillow==9.3.0
PyQt5==5.15.11
PyQt5_sip==12.15.0
QtAwesome==1.3.1
Requests==2.32.3
superqt==0.7.1
六.总结
本次和大家分享了我开发的fun音乐播放器,开发这款音乐播放器我很开心,因为我是真的喜欢,因为喜欢所以会很用心,希望各位读者多多评论、点赞!