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

一、效果展示

二、设计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)  # 初始化滑块值为0
        self.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)  # 初始化音量值为30
        self.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, QMediaContent

class 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)  # 初始化滑块值为0
        self.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)  # 初始化音量值为30
        self.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  # 如果索引超出范围,重置为0
        else:
            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_())  # 进入应用程序主循环
相关推荐
不太会写19 分钟前
基于Python+django+mysql旅游数据爬虫采集可视化分析推荐系统
python·推荐算法
呱牛do it32 分钟前
Python Matplotlib图形美化指南
开发语言·python·matplotlib
pianmian136 分钟前
python制图之小提琴图
开发语言·python·信息可视化
橙子小哥的代码世界38 分钟前
【机器学习】【KMeans聚类分析实战】用户分群聚类详解——SSE、CH 指数、SC全解析,实战电信客户分群案例
人工智能·python·机器学习·kmeans·数据科学·聚类算法·肘部法
计算机徐师兄38 分钟前
Python基于Flask的豆瓣Top250电影数据可视化分析与评分预测系统(附源码,技术说明)
python·flask·豆瓣top250电影数据可视化·豆瓣top250电影评分预测·豆瓣电影数据可视化分析系统·豆瓣电影评分预测系统·豆瓣电影数据
k layc43 分钟前
【论文解读】《Training Large Language Models to Reason in a Continuous Latent Space》
人工智能·python·机器学习·语言模型·自然语言处理·大模型推理
阿正的梦工坊1 小时前
Sliding Window Attention(滑动窗口注意力)解析: Pytorch实现并结合全局注意力(Global Attention )
人工智能·pytorch·python
喜-喜1 小时前
Python pip 缓存清理:全面方法与操作指南
python·缓存·pip
rgb2gray1 小时前
GeoHD - 一种用于智慧城市热点探测的Python工具箱
人工智能·python·智慧城市
MZWeiei2 小时前
Matplotlib,Streamlit,Django大致介绍
python·django·matplotlib