Python----PyQt开发(PyQt高级:手搓一个音乐播放器)

embedded/2025/2/25 7:44:39/

一、效果展示

二、设计PyQt界面

本次ui界面设置用到了水平和垂直布局

2.1、设置ui窗口显示大小与位置

python">        self.setWindowTitle('音乐播放器')  # 设置窗口标题self.setGeometry(800, 300, 800, 800)  # 设置窗口大小和位置

2.2、创建显示歌曲列表控件

python">        # 创建显示歌曲列表的控件        self.song_list = QListWidget(self)

2.3、创建歌曲名称和歌曲时间

python">        self.name_label = QLabel('歌曲名称', self)self.time_label = QLabel('00:00/00:00', self)

2.4、把歌曲名称和歌曲时间水平布局

python">        # 创建水平布局用于放置歌曲名称和时间标签self.label_layout = QHBoxLayout()self.label_layout.addWidget(self.name_label)self.label_layout.addWidget(self.time_label)

2.5、创建歌曲进度条

python">        # 创建播放进度滑块self.player_slider = QSlider()self.player_slider.setValue(0)  # 初始化滑块值为0self.player_slider.setOrientation(Qt.Horizontal)  # 设置为水平滑块

2.6、创建播放,选择文件,上一首,下一首组件

python">        # 创建控制按钮self.play_btn = QPushButton('播放', self)self.choose_btn = QPushButton('选择文件', self)self.pre_btn = QPushButton('上一首', self)self.next_btn = QPushButton('下一首', self)

2.7、创建音量进度条

python">        # 创建音量滑块self.volume_slider = QSlider()self.volume_slider.setRange(0, 100)  # 设置音量范围self.volume_slider.setValue(30)  # 初始化音量值为30self.volume_slider.setOrientation(Qt.Horizontal)  # 设置为水平滑块

2.8、将按钮组件和音量进度条放在同一水平布局

python">        # 创建按钮水平布局self.btn_layout = QHBoxLayout()self.btn_layout.addWidget(self.play_btn)self.btn_layout.addWidget(self.choose_btn)self.btn_layout.addWidget(self.pre_btn)self.btn_layout.addWidget(self.next_btn)self.btn_layout.addWidget(self.volume_slider)

2.9、创建垂直布局,将其组件放入

python">        # 创建主垂直布局self.vbox = QVBoxLayout()self.vbox.addWidget(self.song_list)  # 添加歌曲列表self.vbox.addLayout(self.label_layout)  # 添加标签布局self.vbox.addWidget(self.player_slider)  # 添加播放进度滑块self.vbox.addLayout(self.btn_layout)  # 添加按钮布局

2.10、设置主布局

python">        self.setLayout(self.vbox)  # 设置主布局

三、添加事件

3.1、设置按钮点击事件到对应的槽函数

python">        # 连接按钮点击事件到对应的槽函数self.play_btn.clicked.connect(self.play_slot)self.choose_btn.clicked.connect(self.choose_slot)self.pre_btn.clicked.connect(self.previous_slot)self.next_btn.clicked.connect(self.next_slot)

 播放暂停

python">    def play_slot(self):# 控制播放和暂停的逻辑if self.play_btn.text() == '播放':self.timer.start(1000)  # 启动定时器,每秒更新一次self.MP3_player.play()  # 播放音乐self.play_btn.setText('暂停')  # 更新按钮文本else:self.timer.stop()  # 停止定时器self.MP3_player.pause()  # 暂停音乐self.play_btn.setText('播放')  # 更新按钮文本

 选择文件

python">    def choose_slot(self):# 打开文件对话框选择音乐文件self.music_path, _ = QFileDialog.getOpenFileName(self, '选择歌曲', './', 'MP3(*.mp3)')if self.music_path:  # 确保选择了文件self.music_name = QFileInfo(self.music_path).fileName()  # 获取文件名self.song_list.addItem(QListWidgetItem(self.music_name))  # 将歌曲添加到列表self.song_list_data.append(self.music_path)  # 将路径存储到数据列表中self.name_label.setText(self.music_name)  # 更新当前歌曲名称self.MP3_player.setMedia(QMediaContent(QUrl(self.music_path)))  # 设置媒体内容self.timer.start(1000)  # 启动定时器

 上一首

python">    def previous_slot(self):# 播放上一首歌曲的逻辑if self.song_list.currentRow() > 0:  # 如果有上一首歌self.song_list.setCurrentRow(self.song_list.currentRow() - 1)  # 当前行减一self.play_selected_song()  # 播放选中的歌曲

 下一首

python">    def next_slot(self):# 播放下一首歌曲的逻辑if self.song_list.currentRow() < self.song_list.count() - 1:  # 如果有下一首歌self.song_list.setCurrentRow(self.song_list.currentRow() + 1)  # 当前行加一self.play_selected_song()  # 播放选中的歌曲

3.2、为滑块添加事件

播放进度滑块

python">        # 连接播放器状态变化信号到对应的槽函数self.MP3_player.positionChanged.connect(self.update_playspider_value)# 连接滑块移动事件到对应的槽函数self.player_slider.sliderMoved.connect(self.update_player_position)
python">    def update_playspider_value(self, position):# 更新播放进度滑块的值self.player_slider.setValue(position)
python">    def update_player_position(self, position):# 设置播放器的播放位置self.MP3_player.setPosition(position)

音量滑块

python">        # 连接播放器状态变化信号到对应的槽函数self.MP3_player.durationChanged.connect(self.update_player_volume)# 连接滑块移动事件到对应的槽函数self.volume_slider.sliderMoved.connect(self.update_volume_slot)
python">    def update_player_volume(self, duration):# 更新音量滑块的范围,根据音频的时长设置滑块的范围self.player_slider.setRange(0, duration)
python">    def update_volume_slot(self, position):# 更新播放器音量self.MP3_player.setVolume(position)

四、用到的库函数

Qt Widgets 和布局:
        QWidget: 创建基本的窗口部件。
        QPushButton: 创建按钮。
        QListWidget: 创建一个列表控件,用于显示歌曲列表。
        QLabel: 创建标签,用于显示文本。
        QHBoxLayout: 创建水平布局管理器。
        QVBoxLayout: 创建垂直布局管理器。
        QSlider: 创建滑块控件,用于调节音量和播放进度。


Qt Multimedia:
        QMediaPlayer: 媒体播放器类,用于播放音频文件。
        QMediaContent: 媒体内容类,用于设置播放的音频文件。


Qt Core:
        QUrl: 用于处理 URL。
        QFileInfo: 用于获取文件的信息。
        QTimer: 用于定时器功能。
        QTime: 用于处理时间。
        Qt: 包含常量和枚举,例如 Qt.Horizontal。


事件和信号槽:
        clicked.connect(): 连接按钮点击事件到槽函数。
        positionChanged.connect(): 连接播放器位置变化信号到槽函数。
        durationChanged.connect(): 连接播放器时长变化信号到槽函数。
        sliderMoved.connect(): 连接滑块移动事件到槽函数。


文件对话框:
        QFileDialog.getOpenFileName(): 打开文件对话框以选择文件。


其他:
        setText(): 设置标签的文本。
        setCurrentRow(): 设置当前选中的行。
        addItem(): 向列表控件中添加项目。
        setMedia(): 设置媒体内容。
        play(): 播放音频。
        pause(): 暂停音频。
        stop(): 停止音频。
        setVolume(): 设置播放器音量。
        setPosition(): 设置播放器播放位置。
        setRange(): 设置滑块的范围。
        setValue(): 设置滑块的值。

五、完整代码

python">import sys
from PyQt5.QtCore import QUrl, QFileInfo, QTimer, QTime
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QListWidget, QLabel, QHBoxLayout, QVBoxLayout, QSlider, \QFileDialog, QListWidgetItem
from PyQt5.QtCore import Qt
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContentclass AudioWidge(QWidget):def __init__(self):super().__init__()self.ui_init()self.songname_index = 0  # 用于歌曲名称显示的索引self.song_list_data = []  # 存储歌曲列表的数据self.slot_init()def ui_init(self):self.MP3_player = QMediaPlayer()  # 创建媒体播放器对象self.setWindowTitle('音乐播放器')  # 设置窗口标题self.setGeometry(800, 300, 800, 800)  # 设置窗口大小和位置# 创建显示歌曲列表的控件self.song_list = QListWidget(self)# 创建显示当前歌曲名称和播放时间的标签self.name_label = QLabel('歌曲名称', self)self.time_label = QLabel('00:00/00:00', self)# 创建水平布局用于放置歌曲名称和时间标签self.label_layout = QHBoxLayout()self.label_layout.addWidget(self.name_label)self.label_layout.addWidget(self.time_label)# 创建播放进度滑块self.player_slider = QSlider()self.player_slider.setValue(0)  # 初始化滑块值为0self.player_slider.setOrientation(Qt.Horizontal)  # 设置为水平滑块# 创建控制按钮self.play_btn = QPushButton('播放', self)self.choose_btn = QPushButton('选择文件', self)self.pre_btn = QPushButton('上一首', self)self.next_btn = QPushButton('下一首', self)# 创建音量滑块self.volume_slider = QSlider()self.volume_slider.setRange(0, 100)  # 设置音量范围self.volume_slider.setValue(30)  # 初始化音量值为30self.volume_slider.setOrientation(Qt.Horizontal)  # 设置为水平滑块# 创建按钮水平布局self.btn_layout = QHBoxLayout()self.btn_layout.addWidget(self.play_btn)self.btn_layout.addWidget(self.choose_btn)self.btn_layout.addWidget(self.pre_btn)self.btn_layout.addWidget(self.next_btn)self.btn_layout.addWidget(self.volume_slider)# 创建主垂直布局self.vbox = QVBoxLayout()self.vbox.addWidget(self.song_list)  # 添加歌曲列表self.vbox.addLayout(self.label_layout)  # 添加标签布局self.vbox.addWidget(self.player_slider)  # 添加播放进度滑块self.vbox.addLayout(self.btn_layout)  # 添加按钮布局self.setLayout(self.vbox)  # 设置主布局def slot_init(self):# 连接按钮点击事件到对应的槽函数self.play_btn.clicked.connect(self.play_slot)self.choose_btn.clicked.connect(self.choose_slot)self.pre_btn.clicked.connect(self.previous_slot)self.next_btn.clicked.connect(self.next_slot)# 连接播放器状态变化信号到对应的槽函数self.MP3_player.positionChanged.connect(self.update_playspider_value)self.MP3_player.durationChanged.connect(self.update_player_volume)# 连接滑块移动事件到对应的槽函数self.player_slider.sliderMoved.connect(self.update_player_position)self.volume_slider.sliderMoved.connect(self.update_volume_slot)# 初始化定时器,用于更新播放时间self.timer = QTimer(self)self.timer.timeout.connect(self.update_time_slot)def play_slot(self):# 控制播放和暂停的逻辑if self.play_btn.text() == '播放':self.timer.start(1000)  # 启动定时器,每秒更新一次self.MP3_player.play()  # 播放音乐self.play_btn.setText('暂停')  # 更新按钮文本else:self.timer.stop()  # 停止定时器self.MP3_player.pause()  # 暂停音乐self.play_btn.setText('播放')  # 更新按钮文本def choose_slot(self):# 打开文件对话框选择音乐文件self.music_path, _ = QFileDialog.getOpenFileName(self, '选择歌曲', './', 'MP3(*.mp3)')if self.music_path:  # 确保选择了文件self.music_name = QFileInfo(self.music_path).fileName()  # 获取文件名self.song_list.addItem(QListWidgetItem(self.music_name))  # 将歌曲添加到列表self.song_list_data.append(self.music_path)  # 将路径存储到数据列表中self.name_label.setText(self.music_name)  # 更新当前歌曲名称self.MP3_player.setMedia(QMediaContent(QUrl(self.music_path)))  # 设置媒体内容self.timer.start(1000)  # 启动定时器def previous_slot(self):# 播放上一首歌曲的逻辑if self.song_list.currentRow() > 0:  # 如果有上一首歌self.song_list.setCurrentRow(self.song_list.currentRow() - 1)  # 当前行减一self.play_selected_song()  # 播放选中的歌曲def next_slot(self):# 播放下一首歌曲的逻辑if self.song_list.currentRow() < self.song_list.count() - 1:  # 如果有下一首歌self.song_list.setCurrentRow(self.song_list.currentRow() + 1)  # 当前行加一self.play_selected_song()  # 播放选中的歌曲def play_selected_song(self):# 播放当前选中的歌曲current_row = self.song_list.currentRow()if current_row >= 0 and current_row < len(self.song_list_data):  # 确保索引在有效范围内self.music_path = self.song_list_data[current_row]  # 获取当前歌曲文件路径self.music_name = QFileInfo(self.music_path).fileName()  # 获取文件名self.name_label.setText(self.music_name)  # 更新当前歌曲名称self.MP3_player.setMedia(QMediaContent(QUrl(self.music_path)))  # 设置媒体内容self.MP3_player.play()  # 播放音乐def timerEvent(self, a0):# 处理定时器事件,用于更新歌曲名称显示if self.songname_index == len(self.music_name):self.songname_index = 0  # 如果索引超出范围,重置为0else:self.songname_index += 1  # 增加索引self.name_label.setText(self.music_name[self.songname_index:])  # 更新歌曲名称显示def update_time_slot(self):# 更新播放时间和总时长显示cur_playtime = self.MP3_player.position()  # 获取当前播放时长music_time = self.MP3_player.duration()  # 获取音乐总时长# 格式化当前播放时长和总时长为 mm:ss 格式cur_playtime_str = QTime(0, 0, 0, 0).addMSecs(cur_playtime).toString('mm:ss')music_time_str = QTime(0, 0, 0, 0).addMSecs(music_time).toString('mm:ss')# 更新时间标签显示self.time_label.setText(cur_playtime_str + '/' + music_time_str)def update_playspider_value(self, position):# 更新播放进度滑块的值self.player_slider.setValue(position)def update_player_volume(self, duration):# 更新音量滑块的范围,根据音频的时长设置滑块的范围self.player_slider.setRange(0, duration)def update_player_position(self, position):# 设置播放器的播放位置self.MP3_player.setPosition(position)def update_volume_slot(self, position):# 更新播放器音量self.MP3_player.setVolume(position)if __name__ == '__main__':app = QApplication(sys.argv)  # 创建应用程序windows = AudioWidge()  # 创建音乐播放器窗口windows.show()  # 显示窗口sys.exit(app.exec_())  # 进入应用程序主循环


http://www.ppmy.cn/embedded/164995.html

相关文章

Frontline Analytic Solver分析求解器—基于Excel数据分析、机器学习和运筹优化

Frontline Analytic Solver是一款求解性能优秀的基于Microsoft Excel用户界面的数学分析、机器学习,优化求解和模拟工具&#xff0c;主打产品有两种类型&#xff1a;分别是Analytic Solver for Excel和Analytic Solver for Cloud。Analytic Solver平台是针对任何规模问题的高级…

【计算机网络】传输层协议(UDP TCP)

目录 1. 端口号 端口号的划分 2. UDP UDP协议格式 在系统中的描述 缓冲区 使用注意事项 3. TCP 缓冲区 TCP协议格式 标记位 面向字节流 确认应答机制 流量控制 超时重传 连接管理 滑动窗口 延迟应答 捎带应答 快重传 拥塞控制 粘包问题 TIME_WAIT状态 总结 1. 端口…

Flutter 实现抖音风格底部导航栏

在移动应用开发中&#xff0c;良好的导航设计对用户体验至关重要。抖音作为一款现象级应用&#xff0c;其底部导航设计简洁直观&#xff0c;极具吸引力。本文将详细介绍如何使用 Flutter 开发一个类似抖音风格的底部导航栏&#xff0c;帮助开发者打造兼具美观与实用的导航界面。…

【YOLOv11改进[注意力]】引入DICAM机制(多尺度特征提取和通道注意力机制) | 水下图像增强

推荐一个涨点不错的方向,多尺度特征提取+注意力机制。比如,DICAM模块,结合多尺度特征提取和通道注意力机制,可有效涨点。其中,多尺度特征提取可以帮助模型更全面地理解图像的信息,从而提高复杂场景的目标检测能力;注意力机制可以让模型更关注输入数据中的重要部分,突出…

Docker 搭建 Redis 数据库

Docker 搭建 Redis 数据库 前言一、准备工作二、创建 Redis 容器的目录结构三、启动 Redis 容器1. 通过 redis.conf 配置文件设置密码2. 通过 Docker 命令中的 requirepass 参数设置密码 四、Host 网络模式与 Port 映射模式五、检查 Redis 容器状态六、访问 Redis 服务总结 前言…

DeepSeek-R1本地部署保姆级教程

一、DeepSeek-R1本地部署配置要求 &#xff08;一&#xff09;轻量级模型 ▌DeepSeek-R1-1.5B 内存容量&#xff1a;≥8GB 显卡需求&#xff1a;支持CPU推理&#xff08;无需独立GPU&#xff09; 适用场景&#xff1a;本地环境验证测试/Ollama集成调试 &#xff08;二&a…

【PDF预览】使用iframe实现pdf文件预览,加盖章

使用iframe实现pdf文件预览&#xff0c;以及在pdf上添加水印。另外还包括批注、打印、下载、缩放、分页等功能 <iframesrc"http://static.shanhuxueyuan.com/test.pdf"width"100%"height"100%"frameborder"0"></iframe>&l…

Linux基础指令2

查找指令&#xff08;which,find&#xff09; which命令 可查看所使用的一系列命令的程序文件存放在哪里 语法&#xff1a;which 要查找的命令 find命令&#xff1a;按文件名查找文件 分了按文件名查找与按文件大小查找 按文件名查找文件 语法&#xff1a;find 起始路径 -nam…