python3GUI--new音乐播放器!By:PyQt5(附下载地址)


欢迎大家下载体验!

文件大小:72.03M
下载地址:https://wwt.lanzoul.com/iTWDU25p2oih

一.前言

大家好呀,之前预告过了,近期要发一款新的音乐播放器,保证亮眼!本次使用PyQt5开发一款主打听欧美风歌曲的音乐播放器,软件包含多个页面,支持歌词描边、帅气的播放页,让我们拭目以待!对了,有的读者说我的博客图太多了,最好是能多写一些开发思路,本篇全是干货,请大家放心阅读。

二.展示

1.启动

本次的音乐播放器主打简约风。经过一个splash之后进入我们的软件主页,首页包含多个模块,分别是专辑推荐、单曲推荐、MV推荐、歌手排行。
在这里插入图片描述

首页下方是歌手排行模块
在这里插入图片描述

2.MV推荐

MV推荐页面随机推荐MV内容,每个内容都是可以点击播放的~
在这里插入图片描述

3.专辑详情页

专辑详情页和歌手详情页头部背景均采用封面模糊化处理

在这里插入图片描述

4.歌手详情页

歌手详情页内部包含多个tab,均可点击,在此不再赘述。

在这里插入图片描述

5.搜索结果页

搜索结果页包含多个类别
在这里插入图片描述

6.歌曲播放页

本次的歌曲播放页经过精心设计,包括明暗两种配色。
在这里插入图片描述
再来一张 嘻嘻
请添加图片描述

7.我喜欢歌曲页

在这里插入图片描述

8.我喜欢专辑页

在这里插入图片描述

三.思路&启发

1.布局

本次开发仍然脱离了QT设计师,所有ui内容都是手搓出来的,拿主界面举个例子,我们把主界面分成多个区域:整体在一个widget上,然后防止堆叠组件,使用不同的“页”控制内容的展示,整体是垂直布局,上方为水平布局,内部为垂直布局,将我们的界面拆成不同的区域(类),方便管理与测试,最后把每个部分拼接起来,实现各自的功能,构成我们软件的主体。
在这里插入图片描述
老是有朋友问,左侧导航栏控制右侧展示不同内容的需求如何实现,在此介绍一下我的思路把:用按钮+堆栈布局(组件)即可,使用按钮控制堆栈组件(布局)的索引,展示不同的内容。
同理,播放页亦是如此。
在这里插入图片描述

2.细节

本次增加了许多细节,我来列举一下吧:
1.页面切换效果使用动画
2.无边框+阴影+可调整大小窗口
3.窗口全屏\恢复切换动画
4.歌名(歌手名)滚动效果
5.专辑(歌手详情)背景模糊效果
6.播放页歌词滚动效果
7.特色桌面歌词
8.特色对话框

3.组件复用

为了我们的软件整体风格统一,我这边定义了多个按钮类和标签类,它们具有相同的属性,将配置写入单独的配置文件里,统一管理图标与颜色及样式。

4.项目结构

PyQt5项目并没有一个规范的项目同一结构,下图是我们项目的项目结构 run.pyw是我们软件的入口,其他目录见名知意。
在这里插入图片描述

5.优化速度

本次从代码层面对软件的启动速度、响应速度进行优化:具体来说是:

1.Nuitka

Nuitka优点大致如下:

1.显著提高性能:

Nuitka 通过将 Python 代码编译成二进制格式,可以显著提高程序的执行速度。由于 C++ 代码的执行效率通常高于 Python 解释器,因此编译后的程序在执行时会更加快速,能够更有效地利用系统资源。

2.减小程序体积:

相比其他打包工具,Nuitka 生成的执行文件通常体积更小。这是因为 Nuitka 在编译过程中会优化代码,去除不必要的部分,并将多个模块合并成一个紧凑的可执行文件。

3.增强安全性:

将 Python 代码编译成二进制格式还可以增强程序的安全性。由于攻击者难以直接查看或修改编译后的代码,因此逆向工程或篡改程序的难度大大增加。

2.采用缓存机制

在软件根目录/data/cache/cover下缓存着界面加载的封面数据,因为我们耗时操作大多是由访问接口以及加载封面造成的,访问接口采用线程的方式,在子线程里进行耗时操作,加载图片时,先检测本地是否存在图片,有的话直接从本地读取,否则加载网路图片展示到界面上,之后把图片混存到本地,所以我们软件根目录是越来越大的,用户可以定期清理缓存数据优化存储空间。

3.页面索引记录

我们的主界面以及子界面是用堆栈组件构成的,比如我们首次点击排行榜页面,需要加载每个排行榜的数据,当我们在此切换到这个页面时,由于已经加载过了,就不会再产生网络请求重复加载了,同理:搜索结果页、歌手详情页…都用了这个思想。

四.食用方法

1.项目运行

这里认为读者已经拿到本项目的代码
安装依赖

mutagen==1.45.1
Pillow==9.3.0
Pillow==11.0.0
PyQt5==5.15.11
PyQt5_Frameless_Window==0.3.7
PyQt5_sip==12.15.0
PyQt_Fluent_Widgets==1.5.6
pyqtkeybind==0.0.9
pywin32==306
QtAwesome==1.1.0
Requests==2.32.3
Send2Trash==1.8.0

执行下面的命令安装项目依赖

pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

启动项目
先启动server.exe然后启动软件入口

python3 run.pyw

2.exe运行

安装时,请避免中文、带空格的目录!
本次开发软件依赖外部接口,具体来说是依赖node.js提供的接口服务,不过无需担心,笔者已经打包好了。
windows用户首先双击运行kill&start.bat,待黑框显示本地服务地址(一般是http://localhost:3000
然后双击exe启动软件即可。

五.总结

本次和大家分享了我使用PyQt5开发的新音乐播放器,清新的界面你一定会喜欢!欢迎大家下载尝试!
近期应该是不会再开发新的播放器了,项目重心放到别的上面了,有时间会和大家分享的!

在这里插入图片描述

<think>在PyQt5中设置ComboBox当前选中的值有多种方法,可以根据不同的需求选择: 1. 通过索引设置:使用setCurrentIndex(index) 2. 通过文本设置:使用setCurrentText(text) 3. 通过数据设置:如果ComboBox中存储了用户数据,可以使用setCurrentIndex根据数据查找索引,或者使用findData找到索引再设置 下面将详细说明并给出代码示例。</think># 在 PyQt5 中设置 ComboBox 当前选中值的方法详解 在 PyQt5 中设置 ComboBox 的当前选中值是 GUI 开发中的常见需求。下面我将详细介绍多种设置方法,包括通过索引、文本值、数据对象等方式,并提供完整的代码示例和最佳实践。 ## 核心方法汇总 PyQt5 提供了多种设置 ComboBox 选中值的方法: | 方法 | 描述 | 使用场景 | |------|------|----------| | `setCurrentIndex(index)` | 通过索引设置选中项 | 知道项目在列表中的位置 | | `setCurrentText(text)` | 通过文本值设置选中项 | 知道要选中的具体文本 | | `setCurrentData(data)` | 通过关联的用户数据设置选中项 | 需要基于数据对象选择 | | `setEditText(text)` | 设置可编辑 ComboBox 的文本 | 用户可编辑的下拉框 | ## 完整代码示例 ```python import sys from PyQt5.QtWidgets import ( QApplication, QMainWindow, QWidget, QVBoxLayout, QComboBox, QPushButton, QLabel, QLineEdit, QFormLayout, QGroupBox ) from PyQt5.QtCore import Qt class ComboBoxDemo(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("PyQt5 ComboBox 设置选中值示例") self.setGeometry(100, 100, 500, 400) # 创建主部件 central_widget = QWidget() self.setCentralWidget(central_widget) main_layout = QVBoxLayout(central_widget) # 创建下拉框并添加项目 self.combo = QComboBox() self.combo.setMinimumWidth(200) # 添加带有用户数据的项目 self.combo.addItem("苹果", userData="fruit_apple") self.combo.addItem("香蕉", userData="fruit_banana") self.combo.addItem("橙子", userData="fruit_orange") self.combo.addItem("葡萄", userData="fruit_grape") self.combo.addItem("西瓜", userData="fruit_watermelon") # 添加分组项目 self.combo.insertSeparator(5) self.combo.addItem("汽车", userData="vehicle_car") self.combo.addItem("飞机", userData="vehicle_airplane") self.combo.addItem("火车", userData="vehicle_train") main_layout.addWidget(self.combo) # 显示当前选中信息 self.info_label = QLabel("当前选中: 无") main_layout.addWidget(self.info_label) # 创建设置面板 settings_group = QGroupBox("设置选中值") settings_layout = QFormLayout() # 通过索引设置 self.index_input = QLineEdit() self.index_input.setPlaceholderText("输入索引 (0-7)") self.set_index_btn = QPushButton("通过索引设置") self.set_index_btn.clicked.connect(self.set_by_index) # 通过文本设置 self.text_input = QLineEdit() self.text_input.setPlaceholderText("输入文本 (: 香蕉)") self.set_text_btn = QPushButton("通过文本设置") self.set_text_btn.clicked.connect(self.set_by_text) # 通过数据设置 self.data_input = QLineEdit() self.data_input.setPlaceholderText("输入数据 (: fruit_banana)") self.set_data_btn = QPushButton("通过数据设置") self.set_data_btn.clicked.connect(self.set_by_data) # 添加到布局 settings_layout.addRow("索引设置:", self.index_input) settings_layout.addRow(self.set_index_btn) settings_layout.addRow(QLabel("")) # 空行分隔 settings_layout.addRow("文本设置:", self.text_input) settings_layout.addRow(self.set_text_btn) settings_layout.addRow(QLabel("")) # 空行分隔 settings_layout.addRow("数据设置:", self.data_input) settings_layout.addRow(self.set_data_btn) settings_group.setLayout(settings_layout) main_layout.addWidget(settings_group) # 创建可编辑 ComboBox self.editable_combo = QComboBox() self.editable_combo.setEditable(True) self.editable_combo.addItems(["红色", "绿色", "蓝色", "黄色"]) self.editable_combo.setCurrentText("绿色") # 设置初始值 self.set_editable_btn = QPushButton("设置为: 紫色") self.set_editable_btn.clicked.connect(lambda: self.editable_combo.setEditText("紫色")) main_layout.addWidget(QLabel("可编辑 ComboBox:")) main_layout.addWidget(self.editable_combo) main_layout.addWidget(self.set_editable_btn) # 初始更新显示 self.update_selection_info() # 绑定选择变化事件 self.combo.currentIndexChanged.connect(self.update_selection_info) self.editable_combo.currentIndexChanged.connect( lambda: self.update_selection_info(source=self.editable_combo) ) def update_selection_info(self, index=None, source=None): """更新显示当前选中信息""" combo = source or self.combo # 获取当前选中信息 current_text = combo.currentText() current_index = combo.currentIndex() try: current_data = combo.currentData() # 获取用户数据 data_str = f", 数据: {current_data}" if current_data else "" except AttributeError: data_str = "" info_text = f"当前选中: 索引={current_index}, 文本=&#39;{current_text}&#39;{data_str}" if combo == self.combo: self.info_label.setText(info_text) else: print(f"可编辑ComboBox: {info_text}") def set_by_index(self): """通过索引设置选中项""" index_text = self.index_input.text() if not index_text: return try: index = int(index_text) if 0 <= index < self.combo.count(): self.combo.setCurrentIndex(index) else: print(f"索引超出范围 (0-{self.combo.count()-1})") except ValueError: print("请输入有效的整数索引") def set_by_text(self): """通过文本设置选中项""" text = self.text_input.text().strip() if not text: return # 方法1: 使用setCurrentText self.combo.setCurrentText(text) # 方法2: 使用findText + setCurrentIndex # index = self.combo.findText(text, Qt.MatchExactly) # if index >= 0: # self.combo.setCurrentIndex(index) # else: # print(f"未找到文本: &#39;{text}&#39;") def set_by_data(self): """通过用户数据设置选中项""" data = self.data_input.text().strip() if not data: return # 查找匹配的数据项 index = -1 for i in range(self.combo.count()): item_data = self.combo.itemData(i) if item_data == data: index = i break if index >= 0: self.combo.setCurrentIndex(index) else: print(f"未找到数据: &#39;{data}&#39;") if __name__ == "__main__": app = QApplication(sys.argv) window = ComboBoxDemo() window.show() sys.exit(app.exec()) ``` ## 方法详解与最佳实践 ### 1. 通过索引设置选中项 (`setCurrentIndex`) ```python # 设置第二个项目为选中项(索引从0开始) self.combo.setCurrentIndex(1) # 设置最后一个项目 self.combo.setCurrentIndex(self.combo.count() - 1) ``` **使用场景**: - 知道项目在列表中的确切位置 - 需要选中第一个或最后一个项目时 - 基于位置的计算选择(如循环切换) **注意事项**: - 索引从0开始 - 如果索引超出范围,不会改变当前选择 - 使用 `combo.count()` 获取项目总数 ### 2. 通过文本值设置选中项 (`setCurrentText`) ```python # 精确匹配文本设置选中项 self.combo.setCurrentText("香蕉") # 设置不存在的文本(不会改变选择) self.combo.setCurrentText("芒果") ``` **使用场景**: - 知道要选中的具体文本内容 - 从配置文件或数据库加载保存的选择 - 用户输入或选择恢复 **注意事项**: - 文本匹配是区分大小写的 - 如果没有完全匹配的项目,不会改变当前选择 - 对于可编辑 ComboBox,会设置编辑框的文本 ### 3. 通过用户数据设置选中项 (`itemData` + `setCurrentIndex`) ```python # 查找匹配用户数据的项目并选中 target_data = "fruit_orange" for i in range(self.combo.count()): if self.combo.itemData(i) == target_data: self.combo.setCurrentIndex(i) break ``` **使用场景**: - 项目关联了ID、代码或其他标识数据 - 需要根据数据对象而非显示文本来选择 - 从数据库加载记录并恢复选择状态 **最佳实践**: ```python # 创建数据模型类 class Fruit: def __init__(self, id, name, color): self.id = id self.name = name self.color = color # 添加项目时关联数据对象 fruits = [ Fruit(1, "苹果", "红色"), Fruit(2, "香蕉", "黄色"), Fruit(3, "葡萄", "紫色") ] for fruit in fruits: self.combo.addItem(fruit.name, userData=fruit) # 通过ID查找并选中 def select_by_id(fruit_id): for i in range(self.combo.count()): fruit = self.combo.itemData(i) if fruit and fruit.id == fruit_id: self.combo.setCurrentIndex(i) return True return False # 使用示例 select_by_id(2) # 选中香蕉 ``` ### 4. 设置可编辑 ComboBox (`setEditable` + `setEditText`) ```python # 创建可编辑 ComboBox self.editable_combo = QComboBox() self.editable_combo.setEditable(True) self.editable_combo.addItems(["红色", "绿色", "蓝色"]) # 设置编辑框文本 self.editable_combo.setEditText("自定义颜色") ``` **使用场景**: - 允许用户输入自定义值 - 需要提供建议选项但允许自由输入 - 实现自动完成功能 **高级用法**: ```python # 设置自动完成 self.editable_combo.completer().setCompletionMode(QCompleter.PopupCompletion) # 限制输入内容 self.editable_combo.lineEdit().setValidator(QRegExpValidator(r"[a-zA-Z]+")) # 添加自定义项目 self.editable_combo.addItem("自定义...") self.editable_combo.setCurrentIndex(self.editable_combo.count() - 1) ``` ## 特殊场景处理 ### 1. 处理分组项目(带分隔符) ```python # 添加分隔符 self.combo.insertSeparator(3) # 设置选中项时跳过分隔符 def set_valid_index(index): while index < self.combo.count(): # 检查是否是分隔符 if self.combo.itemText(index) != "": self.combo.setCurrentIndex(index) return index += 1 # 没有找到有效项目 self.combo.setCurrentIndex(-1) # 清除选择 ``` ### 2. 动态更新选项后保持选择 ```python # 保存当前选择 current_data = self.combo.currentData() # 清除并重新添加项目 self.combo.clear() self.combo.addItems(new_items) # 恢复选择 if current_data: for i in range(self.combo.count()): if self.combo.itemData(i) == current_data: self.combo.setCurrentIndex(i) break ``` ### 3. 处理多列数据展示 ```python # 使用自定义委托显示多列数据 from PyQt5.QtGui import QStandardItemModel, QStandardItem # 创建模型 model = QStandardItemModel() for fruit in fruits: item = QStandardItem(fruit.name) item.setData(fruit, Qt.UserRole) # 存储完整对象 item.setToolTip(f"颜色: {fruit.color}") model.appendRow(item) # 设置模型 self.combo.setModel(model) # 设置自定义委托显示更多信息 class FruitDelegate(QStyledItemDelegate): def paint(self, painter, option, index): # 自定义绘制逻辑 fruit = index.data(Qt.UserRole) if fruit: painter.save() # 绘制背景 if option.state & QStyle.State_Selected: painter.fillRect(option.rect, option.palette.highlight()) # 绘制文本 text_rect = option.rect.adjusted(5, 0, 0, 0) painter.drawText(text_rect, Qt.AlignVCenter, f"{fruit.name} ({fruit.color})") painter.restore() self.combo.setItemDelegate(FruitDelegate()) ``` ## 常见问题解决方案 ### 1. 设置选中项后未更新显示 - 确保在 UI 线程中更新 - 检查是否有事件阻塞 - 使用 `QApplication.processEvents()` 强制刷新 ### 2. 无法匹配文本值 - 检查大小写是否一致 - 使用 `Qt.MatchFixedString` 进行大小写不敏感匹配: ```python index = self.combo.findText(text, Qt.MatchFixedString) ``` ### 3. 处理空选择 ```python # 设置无选中状态 self.combo.setCurrentIndex(-1) # 添加空选项 self.combo.addItem("--请选择--", None) self.combo.setCurrentIndex(0) # 检查有效选择 if self.combo.currentData() is None: print("请选择一个有效选项") ``` ### 4. 性能优化(大量项目) ```python # 批量添加项目时禁用更新 self.combo.setUpdatesEnabled(False) try: self.combo.addItems(large_list) finally: self.combo.setUpdatesEnabled(True) self.combo.update() # 强制刷新 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

懷淰メ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值