pyqt5实现一个简易音乐播放器(升级到v2版本)
前言
假期最后一天,看到一篇文章使用pyqt实现了一个音乐播放器,刚好前段时间学完pyqt,来撸一个玩一玩,最终的效果如下:
后来又萌生想法,升级了一下UI:
本代码开源仓库:https://github.com/Mculover666/MP3Player。
文章目录
- 前言
- 一、安装pyqt5
- 二、类设计
- 三、界面设计
- 四、实现功能
- 1. 打开文件夹添加音乐功能
- 2. 播放音乐功能
- 3. 歌曲切换功能
- 4. 进度条
- 5. 配置文件读写的实现
- 5.1. 写配置文件的实现
- 5.2. 加载配置文件的实现
- 6. 退出确认功能的实现
- 五、升级UI界面
- 1. 按钮显示背景图片
- 2. 播放模式设置按钮
一、安装pyqt5
新建虚拟环境:
python -m venv venv
激活虚拟环境,安装pyqt5:
pip install pyqt5
二、类设计
MP3音乐播放器的所有内容都设计为MP3Player类,所以main.c文件中的内容变的简单:
#!/usr/bin/python3
# -*- coding: utf-8 -*-"""
MP3 playerauthor: Mculover666
version: v1.0.0
"""import sys
from MP3Player import MP3Player
from PyQt5.QtWidgets import (QApplication)if __name__ == '__main__':app = QApplication(sys.argv)ex = MP3Player()sys.exit(app.exec_())
MP3Player类的文件为:MP3Player.py
。
from PyQt5.QtWidgets import (QWidget, QDesktopWidget,QMessageBox, QHBoxLayout, QVBoxLayout, QSlider, QListWidget,QPushButton, QLabel, QComboBox)
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qtclass MP3Player(QWidget):def __init__(self):super().__init__()#add your code hereself.initUI()def initUI(self):self.resize(600, 400)self.center()self.setWindowTitle('MP3 player') self.setWindowIcon(QIcon('resource/music.png'))self.show()# bring the window to the center of the screen def center(self):qr = self.frameGeometry()cp = QDesktopWidget().availableGeometry().center()qr.moveCenter(cp)self.move(qr.topLeft())
图标文件从iconfont下载,放在resource文件夹下,文件名为music.png:
此时运行main.py,可以看到窗口和图标:
三、界面设计
def __init__(self):super().__init__()self.startTimeLabel = QLabel('00:00')self.endTimeLabel = QLabel('00:00')self.slider = QSlider(Qt.Horizontal, self)self.playBtn = QPushButton('播放', self)self.prevBtn = QPushButton('上一曲', self)self.nextBtn = QPushButton('下一曲', self)self.openBtn = QPushButton('打开文件夹', self)self.musicList = QListWidget()self.modeCom = QComboBox()self.modeCom.addItem('顺序播放')self.modeCom.addItem('单曲循环')self.modeCom.addItem('随机播放')self.authorLabel = QLabel('Mculover666')self.textLable = QLabel('星光不问赶路人,时光不负有心人')self.versionLabel = QLabel('v1.0.0')self.hBoxSlider = QHBoxLayout()self.hBoxSlider.addWidget(self.startTimeLabel)self.hBoxSlider.addWidget(self.slider)self.hBoxSlider.addWidget(self.endTimeLabel)self.hBoxButton = QHBoxLayout()self.hBoxButton.addWidget(self.playBtn)self.hBoxButton.addWidget(self.nextBtn)self.hBoxButton.addWidget(self.prevBtn)self.hBoxButton.addWidget(self.modeCom)self.hBoxButton.addWidget(self.openBtn)self.vBoxControl = QVBoxLayout()self.vBoxControl.addLayout(self.hBoxSlider)self.vBoxControl.addLayout(self.hBoxButton)self.hBoxAbout = QHBoxLayout()self.hBoxAbout.addWidget(self.authorLabel)self.hBoxAbout.addStretch(1)self.hBoxAbout.addWidget(self.textLable)self.hBoxAbout.addStretch(1)self.hBoxAbout.addWidget(self.versionLabel)self.vboxMain = QVBoxLayout()self.vboxMain.addWidget(self.musicList)self.vboxMain.addLayout(self.vBoxControl)self.vboxMain.addLayout(self.hBoxAbout)self.setLayout(self.vboxMain)self.initUI()
设计的界面如下图:
四、实现功能
1. 打开文件夹添加音乐功能
引入 QFileDialog 类:
from PyQt5.QtWidgets import (QWidget, QDesktopWidget,QMessageBox, QHBoxLayout, QVBoxLayout, QSlider, QListWidget,QPushButton, QLabel, QComboBox, QFileDialog)
添加支持音乐格式和音乐列表成员(在__init__
函数中):
self.song_formats = ['mp3', 'm4a', 'flac', 'wav', 'ogg']
self.songs_list = []
self.cur_playing_song = ''
self.is_pause = True
编写读取文件夹和添加音乐列表功能的函数:
# open floderdef openMusicFloder(self):self.cur_path = QFileDialog.getExistingDirectory(self, "选取音乐文件夹", './')if self.cur_path:self.showMusicList()self.cur_playing_song = ''self.startTimeLabel.setText('00:00')self.endTimeLabel.setText('00:00')self.slider.setSliderPosition(0)self.is_pause = Trueself.playBtn.setText('播放')#show music listdef showMusicList(self):self.musicList.clear()for song in os.listdir(self.cur_path):if song.split('.')[-1] in self.song_formats:self.songs_list.append([song, os.path.join(self.cur_path, song).replace('\\', '/')])self.musicList.addItem(song)self.musicList.setCurrentRow(0)if self.songs_list:self.cur_playing_song = self.songs_list[self.musicList.currentRow()][-1]
设置打开按钮的回调函数:
self.openBtn.clicked.connect(self.openMusicFloder)
提前下载放到文件夹中:
运行程序,选择该文件夹,可以看到播放列表添加成功:
2. 播放音乐功能
引入 QMediaPlayer类,QMediaContent类,QUrl类:
from PyQt5.QtCore import Qt, QUrl
from PyQt5.QtMultimedia import QMediaPlayer, QMediaContent
添加用于实现播放/暂停功能的新成员:
self.player = QMediaPlayer()
self.is_switching = False
编写一个基于MessageBox的提示函数:
# 提示
def Tips(self, message):QMessageBox.about(self, "提示", message)
编写播放当前设置的音乐函数:
# 设置当前播放的音乐
def setCurPlaying(self):self.cur_playing_song = self.songs_list[self.musicList.currentRow()][-1]self.player.setMedia(QMediaContent(QUrl(self.cur_playing_song)))
编写播放/暂停函数:
# 播放音乐def playMusic(self):if self.musicList.count() == 0:self.Tips('当前路径内无可播放的音乐文件')returnif not self.player.isAudioAvailable():self.setCurPlaying()if self.is_pause or self.is_switching:self.player.play()self.is_pause = Falseself.playBtn.setText('暂停')elif (not self.is_pause) and (not self.is_switching):self.player.pause()self.is_pause = Trueself.playBtn.setText('播放')
最后设置播放按钮的回调函数:
self.playBtn.clicked.connect(self.playMusic)
此时已经可以正常的播放、暂停。
3. 歌曲切换功能
歌曲切换功能包括三个:
- 上一曲
- 下一曲
- 双击音乐播放
编写上一曲和下一曲函数:
# 上一曲
def prevMusic(self):self.slider.setValue(0)if self.musicList.count() == 0:self.Tips('当前路径内无可播放的音乐文件')returnpre_row = self.musicList.currentRow()-1 if self.musicList.currentRow() != 0 else self.musicList.count() - 1self.musicList.setCurrentRow(pre_row)self.is_switching = Trueself.setCurPlaying()self.playMusic()self.is_switching = False# 下一曲
def nextMusic(self):self.slider.setValue(0)if self.musicList.count() == 0:self.Tips('当前路径内无可播放的音乐文件')returnnext_row = self.musicList.currentRow()+1 if self.musicList.currentRow() != self.musicList.count()-1 else 0self.musicList.setCurrentRow(next_row)self.is_switching = Trueself.setCurPlaying()self.playMusic()self.is_switching = False
设置上一曲按钮和下一曲按钮的回调函数:
self.prevBtn.clicked.connect(self.prevMusic)
self.nextBtn.clicked.connect(self.nextMusic)
编写双击歌曲播放的函数:
# 双击歌曲名称播放音乐
def doubleClicked(self):self.slider.setValue(0)self.is_switching = Trueself.setCurPlaying()self.playMusic()self.is_switching = False
设置双击事件回调函数:
self.musicList.itemDoubleClicked.connect(self.doubleClicked)
4. 进度条
进度条需要每1s刷新一次,所以肯定需要用定时器来实现。
导入QTimer类:
from PyQt5.QtCore import Qt, QUrl, QTimer
引入 Time 类:
import os, time
首先编写设置进度条的函数:
# 根据播放模式自动播放,并刷新进度条def playByMode(self):# 刷新进度条if (not self.is_pause) and (not self.is_switching):self.slider.setMinimum(0)self.slider.setMaximum(self.player.duration())self.slider.setValue(self.slider.value() + 1000)self.startTimeLabel.setText(time.strftime('%M:%S', time.localtime(self.player.position()/1000)))self.endTimeLabel.setText(time.strftime('%M:%S', time.localtime(self.player.duration()/1000)))# 顺序播放if (self.modeCom.currentIndex() == 0) and (not self.is_pause) and (not self.is_switching):if self.musicList.count() == 0:returnif self.player.position() == self.player.duration():self.nextMusic()# 单曲循环elif (self.modeCom.currentIndex() == 1) and (not self.is_pause) and (not self.is_switching):if self.musicList.count() == 0:returnif self.player.position() == self.player.duration():self.is_switching = Trueself.setCurPlaying()self.slider.setValue(0)self.playMusic()self.is_switching = False# 随机播放elif (self.modeCom.currentIndex() == 2) and (not self.is_pause) and (not self.is_switching):if self.musicList.count() == 0:returnif self.player.position() == self.player.duration():self.is_switching = Trueself.musicList.setCurrentRow(random.randint(0, self.musicList.count()-1))self.setCurPlaying()self.slider.setValue(0)self.playMusic()self.is_switching = False
在初始化时设置定时器:
self.timer = QTimer(self)
self.timer.start(1000)
self.timer.timeout.connect(self.playByMode)
运行,可以看到进度条实时刷新。
接着还要实现反向功能,由进度条拖动控制播放进度,添加下面这行代码添加回调函数实现:
self.slider.sliderMoved[int].connect(lambda: self.player.setPosition(self.slider.value()))
5. 配置文件读写的实现
每次运行软件时,都要手动设置音乐文件夹的目录,非常麻烦,使用配置文件来实现记录配置的功能。
配置文件读写使用 configparser 模块实现。
导入该模块:
import configparser
添加配置文件名的成员:
self.settingfilename = 'config.ini'
5.1. 写配置文件的实现
编写记录配置的函数:
# 更新配置文件
def updateSetting(self):config = configparser.ConfigParser()config.read(self.settingfilename)if not os.path.isfile(self.settingfilename):config.add_section('MP3Player')config.set('MP3Player', 'PATH', self.cur_path)config.write(open(self.settingfilename, 'w'))
在用户选择完音乐文件夹之后调用:
# 打开文件夹
def openMusicFloder(self):self.cur_path = QFileDialog.getExistingDirectory(self, "选取音乐文件夹", './')if self.cur_path:self.showMusicList()self.cur_playing_song = ''self.startTimeLabel.setText('00:00')self.endTimeLabel.setText('00:00')self.slider.setSliderPosition(0)self.updateSetting()self.is_pause = Trueself.playBtn.setText('播放')
运行,选择音乐文件夹,软件创建的配置文件内容为:
5.2. 加载配置文件的实现
编写加载配置文件的函数:
# 加载配置文件def loadingSetting(self):config = configparser.ConfigParser()config.read(self.settingfilename)if not os.path.isfile(self.settingfilename):returnself.cur_path = config.get('MP3Player', 'PATH')self.showMusicList()
在软件初始化阶段自动加载配置文件:
self.loadingSetting()
运行软件,可以看到自动加载出上次用户设置的目录。
6. 退出确认功能的实现
目前用户点击关闭按钮后,软件直接退出,接下来我们添加一个弹窗,确认用户是否要真的退出:
# 确认用户是否要真正退出
def closeEvent(self, event):reply = QMessageBox.question(self, 'Message',"确定要退出吗?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)if reply == QMessageBox.Yes:event.accept()else:event.ignore()
添加该函数实现后,当我们再次点击退出按钮时,即可看到提示信息:
至此,音乐播放器实现完成。
五、升级UI界面
v1版本用的都是普通按钮,太丑了,v2版本升级都用背景图片显示:
1. 按钮显示背景图片
self.playBtn.setStyleSheet("QPushButton{border-image: url(resource/image/play.png)}")
self.playBtn.setFixedSize(48, 48)
self.nextBtn.setStyleSheet("QPushButton{border-image: url(resource/image/next.png)}")
self.nextBtn.setFixedSize(48, 48)
self.prevBtn.setStyleSheet("QPushButton{border-image: url(resource/image/prev.png)}")
self.prevBtn.setFixedSize(48, 48)
self.openBtn.setStyleSheet("QPushButton{border-image: url(resource/image/open.png)}")
self.openBtn.setFixedSize(24, 24)
2. 播放模式设置按钮
v1版本使用comboBox选择播放模式,v2版本使用按钮点击,轮流选择。
先在初始化代码中创建按钮:
self.PlayModeBtn = QPushButton(self)
设置默认背景图片:
self.PlayModeBtn.setStyleSheet("QPushButton{border-image: url(resource/image/sequential.png)}")
self.PlayModeBtn.setFixedSize(24, 24)
编写回调函数设置播放模式:
# 播放模式设置
def playModeSet(self):# 设置为单曲循环模式if self.playMode == 0:self.playMode = 1self.PlayModeBtn.setStyleSheet("QPushButton{border-image: url(resource/image/circulation.png)}")# 设置为随机播放模式elif self.playMode == 1:self.playMode = 2self.PlayModeBtn.setStyleSheet("QPushButton{border-image: url(resource/image/random.png)}")# 设置为顺序播放模式elif self.playMode == 2:self.playMode = 0self.PlayModeBtn.setStyleSheet("QPushButton{border-image: url(resource/image/sequential.png)}")
修改之前的定时器回调函数:
# 根据播放模式自动播放,并刷新进度条
def playByMode(self):# 刷新进度条if (not self.is_pause) and (not self.is_switching):self.slider.setMinimum(0)self.slider.setMaximum(self.player.duration())self.slider.setValue(self.slider.value() + 1000)self.startTimeLabel.setText(time.strftime('%M:%S', time.localtime(self.player.position()/1000)))self.endTimeLabel.setText(time.strftime('%M:%S', time.localtime(self.player.duration()/1000)))# 顺序播放if (self.playMode == 0) and (not self.is_pause) and (not self.is_switching):if self.musicList.count() == 0:returnif self.player.position() == self.player.duration():self.nextMusic()# 单曲循环elif (self.playMode == 1) and (not self.is_pause) and (not self.is_switching):if self.musicList.count() == 0:returnif self.player.position() == self.player.duration():self.is_switching = Trueself.setCurPlaying()self.slider.setValue(0)self.playMusic()self.is_switching = False# 随机播放elif (self.playMode == 2) and (not self.is_pause) and (not self.is_switching):if self.musicList.count() == 0:returnif self.player.position() == self.player.duration():self.is_switching = Trueself.musicList.setCurrentRow(random.randint(0, self.musicList.count()-1))self.setCurPlaying()self.slider.setValue(0)self.playMusic()self.is_switching = False
最后将回调函数与按钮绑定:
self.PlayModeBtn.clicked.connect(self.playModeSet)
v2版本效果图如下:
pyqt5实现一个简易音乐播放器(升级到v2版本)相关推荐
- matlab中GUI的属性检查器中的XLimMode是什么_如何在Matlab中使用GUI做一个简易音乐播放器? ---- (二)GUIDE...
咕咕怪由于昨天有重要的事情所以咕了一天的文章 (感觉写得挺基础的,对各个部分有一定了解的童鞋可以直接跳过了解的部分 用Matlab做一个app有几种办法呢? 同样的,帮助文档告诉了我们答案:三种. 英 ...
- matlab figure函数_如何在Matlab中使用GUI做一个简易音乐播放器? ---- (六)控件间的数据传递...
我纠结了两个星期是否要写这一章-最后决定还是要写一章收尾,来解释其中的控件间的数据传递问题. 在前五篇中,如果有童鞋跟上了我的思路或者做完了这样一个gui,会发现还有一个一直避开的遗留问题,就是将歌曲 ...
- PyQt5实现简易音乐播放器
PyQt5实现简易音乐播放器 环境 vscode python 3.10.0 PyQt5 5.15.4 功能目标 能够读取本地的音乐文件,并实现播放的开关.曲目的切换和音量的加减 具体实现 新建一个文 ...
- JavaScript + Audio API自制简易音乐播放器(详细完整版、小白都能看懂)
JavaScript + Audio API自制简易音乐播放器(详细完整版) ** 音乐播放器的功能清单如下: ** 1.点击暂停按钮,歌曲暂停 2.点击播放按钮,歌曲播放 3.单曲循环与取消单曲循环 ...
- html实现简易音乐播放器
目标: 使用vue.js导包的形式做一个简单的音乐播放器,新手也很容易看懂. 内容: 1. 使用了flex实现响应式布局: 2. 使用min-width防止字体被压缩: 3. 使用computed计算 ...
- Android开发之简易音乐播放器(一)
这里介绍一个简易的音乐播放器, 效果图如下: 但是,由于这是一个简易版的音乐播放器,所播放的音乐只有一首,且被写死, 但,操作却十分简单,方便理解! 这是代码的主要设计: 音乐主要存放在这一个文件中: ...
- 单片机音乐播放器课程设计C语言,单片机课程设计简易音乐播放器
单片机课程设计简易音乐播放器 论文题目:简易音乐播放器所属系部:电子工程系 指导教师: 学生姓名: 学 号: 专 业: 电子信息工程技术 题目: 简易音乐播放器任务与要求:本设计以 MCS-51 系列 ...
- android开发音乐播放器,Android开发简易音乐播放器
这里介绍一个简易的音乐播放器,供大家参考,具体内容如下 效果图如下: 但是,由于这是一个简易版的音乐播放器,所播放的音乐只有一首,且被写死,但,操作却十分简单,方便理解! 这是代码的主要设计: 音乐主 ...
- 【微信小程序】简易音乐播放器,进度条拖拉、音乐的播放与暂停
小程序简易音乐播放器实现 粗糙的页面设计: wxml部分: <view class="test"><view class="img">& ...
最新文章
- docker安装mysql5.7_超详细Docker安装Mysql5.7并进行挂载
- webpack搭建vue项目开发环境【文档向学习】
- shell脚本[] [[]] -n -z 的含义解析
- linux的write是线程安全的吗,socket的write/send还是是否是线程安全?
- python服务端对应多个客户端_Python-网络编程:TCP2 循环为多个客户端服务
- 【PKUWC2018】随机算法【状压dp】【组合计数】
- C ++ 指针 | 指针的操作_2
- 【LeetCode】Remove Nth Node From End of List
- Interbase浴火重生:开源数据库Firebird更新到2.12
- HDU4841 圆桌问题【约瑟夫环+模拟+STL】
- windows下mysql忘记密码重置
- ASCII表,二进制、十进制对照表
- 喵喵玩 v3.8.5
- php爬虫亚马逊,亚马逊爬虫(亚马逊 api)
- Axure元件-内联框架设计网页
- ISO8601时间格式转换为Date
- RK3326 Android 8.1 吉字节问题解决
- 一款酷炫的开源 macOS 屏幕保护程序
- 光滑噪声数据常用的方法_几种常见的数据变换方法
- Cobbler 自动装机系统
热门文章
- 搞定机械工程专业毕业设计选题推荐
- 三菱机械臂demo程序
- (step4.2.3)hdu 1242(Rescue——BFS)
- 计算机机房新风机的作用,机房为什么要装新风系统,附解决方案
- Windows进不去系统(蓝屏、黑屏、BIOS更新等无法开机的情况),试试这几种解决办法
- ARM最强CPU/GPU来了!A75、G72首发:性能爆炸
- 终于找到了一款好用的录屏软件了
- 100+个数据分析常用指标和术语
- android启动微信应用程序,android 从微信分享的网页中启动APP
- stormzhang