更新日志:
20221031:添加独立播放列表
20221107:添加“上一首”、“下一首”功能
展示图片:
202211071308更新:添加上一首、下一首功能
20221031更新:添加独立播放列表
主要功能:
1、进度条拖动
2、音量拖动
3、独立播放列表
4、窗体渐变色(UI美化方面)
概述:
之前刚学python的时候,就照着网上的代码实现一个简单的播放器功能:
使用python加PyQt5,利用QMediaPlayer写一个简易的音乐播放器(进度条拖动,音量改变,播放停止切换,歌曲列表))
不过,这个博文里的程序功能比较简单,然后界面也没有设置:
初版界面:
20221031更新界面:
对比一下,外观上差别还是挺明显的。UI的配色可以根据自己的喜好来设置(QSS文件里设置)
本文主要说一下两个方面的实现:
1、独立播放列表
2、界面样式设置
其他功能设置就不多介绍,可以去看我之前写的那篇博文,我在底下也会把完整代码重新贴一遍。
独立播放列表的实现,主要在于多窗口之间的函数调用和参数传递实现,这个我也单独写过一个介绍:
<Python>PyQt5,多窗口之间参数传递和函数调用
有兴趣的可以看看。
播放列表窗口代码:
class music_list_win(QWidget):
"""歌曲列表窗口"""
def __init__(self,m_l):
super().__init__()
self.music_list1=m_l
#print(self.music_list1)
self.initUI()
def initUI(self):
self.qss_style_file='music_play_pro2022\qss_music_list_win.qss'
self.qss1=QssRead.readQSS(self.qss_style_file)
self.song_lists=[]
self.list_music_list=QListWidget(self)
self.list_music_list.doubleClicked.connect(self.music_list_doubleplay_func)
#self.qlist.setStyle(QStyleFactory.create('Fusion'))
self.list_music_list.setGeometry(10, 10, 230, 500)
self.music_list_add()
self.setGeometry(920, 100, 250, 600)
self.setWindowTitle('播放列表')
self.setStyleSheet(self.qss1)
#self.setWindowFlag(Qt.FramelessWindowHint)
self.setWindowIcon(QIcon("music_play_pro2022\musicicon2.jpeg"))
#self.show()
列表填充函数:
def music_list_add(self):
for i,l in enumerate( self.music_list1):
#print(l[0])
self.list_music_list.addItem("[ "+str(i)+" ]"+"--"+l[0])
调用主窗体函数的函数:
这里mp1是主窗体的实例化,doubleplay_subwin()是主窗体的一个函数。
def music_list_doubleplay_func(self):
""""""
#music_list_index=self.list_music_list.currentRow()
mp1.doubleplay_subwin()
主窗体传递参数给播放列表窗体:
主窗体获取歌曲列表,并且同时将列表传递给子窗体(播放列表窗体),并且显示窗体。
def load_music_file_func(self):
#获取歌曲所在文件夹路径
self.qlist.clear()
self.cur_path=QFileDialog.getExistingDirectory(self, "选取文件夹", 'E:/')
#判断歌曲文件路径是否存在
if os.path.exists(self.cur_path):
#将文件夹中的所有歌曲添加到List中
for song in os.listdir(self.cur_path):
#print(song)
self.songs_list.append([song, os.path.join(self.cur_path, song).replace('\\', '/')])
music_list.append([song, os.path.join(self.cur_path, song).replace('\\', '/')])
self.qlist.addItem(song)
self.music_list_win1=music_list_win(music_list)
self.music_list_win1.show()
可以看到优化过的界面,背景色为渐变,看起来也好看一些,这里在qss文件里设置:
QWidget
{
background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #81F5D8,stop:0.2 #43ABE7,stop:0.5 #57E7EC stop:1 #8EF068);
}
qlineargradient是设置渐变色的,可以调整渐变方向、渐变点、渐变颜色等,以调出自己喜欢的配色。
完整代码:
20221031更新:添加独立播放列表
20221107更新:添加上一首、下一首功能
#-*-coding:utf-8-*
"""名称:风尘音乐播放器
版本:V0.1
作者:菌尘
"""
import os
import string
import sys
import time
import random
import configparser
import ffmpeg
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtMultimedia import *
from qss_read import QssRead
music_name=''
music_list=[]
music_list_index=0
class music_list_win(QWidget):
"""歌曲列表窗口"""
def __init__(self,m_l:list):
super().__init__()
self.music_list1=m_l
#print(self.music_list1)
self.initUI()
def initUI(self):
self.qss_style_file='music_play_pro2022\qss_music_list_win.qss'
self.qss1=QssRead.readQSS(self.qss_style_file)
self.song_lists=[]
self.list_music_list=QListWidget(self)
self.list_music_list.doubleClicked.connect(self.music_list_doubleplay_func)
#self.qlist.setStyle(QStyleFactory.create('Fusion'))
self.list_music_list.setGeometry(10, 10, 230, 500)
self.music_list_add()
self.setGeometry(920, 100, 250, 600)
self.setWindowTitle('播放列表')
self.setStyleSheet(self.qss1)
#self.setWindowFlag(Qt.FramelessWindowHint)
self.setWindowIcon(QIcon("music_play_pro2022\musicicon2.jpeg"))
#self.show()
def music_list_add(self):
for i,l in enumerate( self.music_list1):
#print(l[0])
self.list_music_list.addItem("[ "+str(i)+" ]"+"--"+l[0])
def music_list_doubleplay_func(self):
""""""
#music_list_index=self.list_music_list.currentRow()
mp1.doubleplay_subwin()
class Music_Play_win(QMainWindow):
"""Main窗口"""
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
#导入UI样式文件
self.qss_style_file='music_play_pro2022\qss_music_main_win_style.qss'
self.qss1=QssRead.readQSS(self.qss_style_file)
self.songs_list=[]
self.music_list_win1=music_list_win(music_list)
self.is_playing=False
self.is_pause=True
self.layout=QVBoxLayout()
#添加菜单项
self.menu1=self.menuBar()
self.menu1.setGeometry(QRect(0,0,100,40))
self.menu1.setObjectName("menubar")
self.file=self.menu1.addMenu('文件')
self.file_close_win=QAction('退出',self)
self.file.addAction(self.file_close_win)
self.tool=self.menu1.addMenu('工具')
self.tool_change_bg=QAction('更改背景色',self)
self.tool.addAction(self.tool_change_bg)
self.about=self.menu1.addMenu('关于')
#为菜单添加响应
self.file_close_win.triggered.connect(self.close)
self.tool_change_bg.triggered.connect(self.tool_change_bg_func)
#UI布局
self.gb1=QGroupBox('正在播放', self)
self.gb1.setGeometry(220, 50, 420, 60)
self.gb2=QGroupBox('个人中心', self)
self.gb2.setGeometry(20, 40, 80, 300)
self.gb3=QGroupBox('歌曲列表', self)
self.gb3.setGeometry(220, 180, 300, 130)
self.h1_layout=QHBoxLayout()
self.h2_layout=QHBoxLayout()
self.myfont = QFont('Microsoft YaHei', 20)
self.my_btn=QPushButton('我的主页', self)
self.my_btn.setStyle(QStyleFactory.create('Fusion'))
self.my_btn.setGeometry(30,90,60,20)
self.fav_btn=QPushButton('收藏页',self)
self.fav_btn.setStyle(QStyleFactory.create('Fusion'))
self.fav_btn.setGeometry(30, 120, 60, 20)
self.btn_music_list=QPushButton('播放列表',self)
self.btn_music_list.setGeometry(30,150,60,20)
self.btn_music_list.setStyle(QStyleFactory.create('Fusion'))
self.btn_music_list.clicked.connect(self.music_list_show_func)
self.lbl_musicname=QLabel('', self)
self.lbl_musicname.setGeometry(230, 65, 20, 20)
self.lbl_musicname.adjustSize()
self.label_song_duration_runtime = QLabel('00:00', self)
self.label_song_duration_runtime.setStyle(QStyleFactory.create('Fusion'))
self.label_song_duration_runtime.setGeometry(170, 60, 60, 20)
#self.label1.adjustSize()
self.label_song_duration_all = QLabel('00:00', self)
self.label_song_duration_all.setStyle(QStyleFactory.create('Fusion'))
self.label_song_duration_all.setGeometry(645, 60, 60, 20)
#self.label2.adjustSize()
self.lbl_vol_name=QLabel('音量',self)
self.lbl_vol_name.setStyle(QStyleFactory.create('Fusion'))
self.lbl_vol_name.setGeometry(220,120,20,20)
self.lbl_vol_name.adjustSize()
self.lbl_volunm=QLabel('0',self)
self.lbl_volunm.setGeometry(355,125,20,20)
self.lbl_volunm.adjustSize()
self.player=QMediaPlayer()
self.player.setVolume(3)
self.player.stateChanged.connect(self.do_mediaplayer_statechanged)
self.posi_fwd_btn=QPushButton('快进', self)
self.posi_fwd_btn.setStyle(QStyleFactory.create('Fusion'))
self.posi_fwd_btn.setGeometry(500,120,60,20)
self.posi_fwd_btn.setIcon(QIcon("C:/Users/rongjv/Desktop/快进.jfif"))
self.posi_fwd_btn.clicked.connect(self.setsongposi_fwd)
self.posi_bkd_btn=QPushButton('后退',self)
self.posi_bkd_btn.setStyle(QStyleFactory.create('Fusion'))
self.posi_bkd_btn.setGeometry(580,120,60,20)
self.posi_bkd_btn.setIcon(QIcon("C:/Users/rongjv/Desktop/快退.jfif"))
self.posi_bkd_btn.clicked.connect(self.setsongposi_bkd)
self.slider=QSlider(Qt.Horizontal, self)
self.setStyle(QStyleFactory.create('Fusion'))
self.slider.setMinimum(0)
self.slider.setMaximum(1000)
#self.slider.valueChanged.connect(self.songposition)
self.slider.sliderMoved.connect(self.songposition)
self.slider.sliderPressed.connect(self.sl_pr)
self.slider.sliderReleased.connect(self.sl_re)
self.slider.valueChanged.connect(self.sl_vc)
self.volunm_slider=QSlider(Qt.Horizontal, self)
self.volunm_slider.setGeometry(250,120,100,20)
self.volunm_slider.setMinimum(0)
self.volunm_slider.setMaximum(100)
self.volunm_slider.valueChanged.connect(self.songvolunm)
self.open_btn=QPushButton('导入歌曲', self)
self.open_btn.setStyle(QStyleFactory.create('Fusion'))
self.open_btn.setGeometry(30, 180, 60, 20)
self.open_btn.clicked.connect(self.load_music_file_func)
self.btn_next=QPushButton('',self)
self.btn_next.setGeometry(420,90,20,20)
self.btn_next.setIcon(QIcon('music_play_pro2022\\next1.png'))
self.btn_next.clicked.connect(self.next_play_func)
self.btn_last=QPushButton('',self)
self.btn_last.setGeometry(390,90,20,20)
self.btn_last.setIcon(QIcon('music_play_pro2022\last1.png'))
self.btn_last.clicked.connect(self.last_play_func)
self.play_btn = QPushButton('', self)
self.play_btn.setStyle(QStyleFactory.create('Fusion'))
self.play_btn.setGeometry(520, 85, 20, 25)
self.play_btn.setIcon(QIcon(QPixmap("music_play_pro2022\stopicon.jpeg")))
self.play_btn.clicked.connect(self.play_or_stop_mainwin_dbclk)
self.qlist=QListWidget(self)
self.qlist.doubleClicked.connect(self.doubleplay)
#self.qlist.setStyle(QStyleFactory.create('Fusion'))
self.qlist.setGeometry(220, 200, 300, 120)
self.list_music_lrc=QListWidget(self)
self.list_music_lrc.setGeometry(540,200,200,120)
self.list_music_lrc.addItem('')
self.timer=QTimer(self)
self.timer.start(100)
self.timer.timeout.connect(self.musictime)
#测试用
#self.lbl_text=QLabel(self)
#self.lbl_text.setGeometry(400,20,100,20)
#self.lbl_text.setText('000')
#设置窗口布局
self.h1_layout.addWidget(self.slider)
self.gb1.setLayout(self.h1_layout)
#self.h2_layout.addWidget(self.my_btn)
#self.h2_layout.addWidget(self.fav_btn)
#self.gb2.setLayout(self.h2_layout)
self.setGeometry(100, 100, 800, 400)
self.setWindowTitle('风尘播放器')
#self.setWindowFlag(Qt.FramelessWindowHint)
self.setStyleSheet(self.qss1)
self.setWindowIcon(QIcon("music_play_pro2022\musicicon2.jpeg"))
self.show()
def music_list_show_func(self):
"""显示播放列表"""
#self.music_list_win1=music_list_win(music_list)
self.music_list_win1.show()
def tool_change_bg_func(self):
"""更改背景色"""
def do_mediaplayer_statechanged(self,state):
if state == QMediaPlayer.PlayingState:
pass
if state == QMediaPlayer.PausedState:
pass
if state == QMediaPlayer.StoppedState:
self.is_pause = True
def sl_pr(self):
self.timer.stop()
self.cur_posi=self.slider.value()
def sl_re(self):
self.player.setPosition(self.slider.value()*1000)
self.timer.start()
#print(self.player.duration())
def sl_vc(self):
...
#self.lbl_text.setText(str(self.slider.value()))
def songvolunm(self):
self.volumevalue=self.volunm_slider.value()
self.player.setVolume(self.volumevalue)
self.lbl_volunm.setText(str(self.volumevalue))
self.lbl_volunm.adjustSize()
def songposition(self):
#获取歌曲的时间信息
self.p1=self.player.duration()
#将秒转换为00:00的格式
self.p2=self.p1 / 1000
self.p3=self.slider.value() * self.p2
self.ppp = self.slider.value()
#self.player.setPosition(int(self.p3))
#self.label1.setText(time.strftime('%M:%S', time.localtime(self.player.position() / 1000)))
def setsongposi_fwd(self):
self.p=self.player.position()+2000
self.player.setPosition(self.p)
def setsongposi_bkd(self):
self.pp=self.player.position()-2000
self.player.setPosition(self.pp)
def load_music_file_func(self):
#获取歌曲所在文件夹路径
self.qlist.clear()
self.cur_path=QFileDialog.getExistingDirectory(self, "选取文件夹", 'E:/')
#判断歌曲文件路径是否存在
if os.path.exists(self.cur_path):
#将文件夹中的所有歌曲添加到List中
for song in os.listdir(self.cur_path):
#print(song)
self.songs_list.append([song, os.path.join(self.cur_path, song).replace('\\', '/')])
music_list.append([song, os.path.join(self.cur_path, song).replace('\\', '/')])
self.qlist.addItem(song)
self.music_list_win1=music_list_win(music_list)
self.music_list_win1.show()
def musictime(self):
if self.is_playing:
self.slider.setMinimum(0)
self.slider.setMaximum(int(self.player.duration()/1000))
#设置歌曲实时播放时间进度
self.label_song_duration_runtime.setText(time.strftime('%M:%S', time.localtime(self.player.position() / 1000)))
#设置歌曲总时间
self.label_song_duration_all.setText(time.strftime('%M:%S', time.localtime(self.player.duration() / 1000)))
#歌曲当前播放位置
self.cur_posi = int(self.player.position()/1000)
#print(self.cur_posi)
self.slider.setValue(self.cur_posi)
def last_play_func(self):
"""上一首"""
self.is_playing=False
self.slider.setValue(0)
self.choosesongname_last()
self.is_playing=True
if self.volunm_slider.value() == 0:
self.volunm_slider.setValue(3)
self.play_or_stop_mainwin_next()
def next_play_func(self):
"""下一首"""
self.is_playing=False
self.slider.setValue(0)
self.choosesongname_next()
self.is_playing=True
if self.volunm_slider.value() == 0:
self.volunm_slider.setValue(3)
self.play_or_stop_mainwin_next()
def choosesongname_mainwin_dbclk(self):
"""主窗口双击播放"""
global music_list_index
self.index = self.qlist.currentRow()
music_list_index=self.index
#self.playsong = self.songs_list[self.index][-1]
#self.playsongname=self.songs_list[self.index][0]
#self.playsong1 = self.playsong.replace('\\', '/')
self.choose_song_name_2(self.index)
def choosesongname_subwin_dbclk(self):
"""播放列表窗口双击播放"""
global music_list_index
self.index2=self.music_list_win1.list_music_list.currentRow()
music_list_index=self.index2
#self.playsong =self.songs_list[self.index2][-1]
#self.playsongname=music_list[self.index2][0]
#self.playsong1 = self.playsong.replace('\\', '/')
self.choose_song_name_2(self.index2)
def choosesongname_last(self):
"""主窗口上一首播放"""
global music_list_index
if music_list_index > 0:
self.index_next=music_list_index-1
else:
self.index_next=len(self.songs_list)-1
self.music_list_win1.list_music_list.setCurrentRow(self.index_next)
self.choose_song_name_2(self.index_next)
music_list_index=self.index_next
def choosesongname_next(self):
"""主窗口下一首播放"""
global music_list_index
if music_list_index < len(self.songs_list)-1:
self.index_next=music_list_index+1
else:
self.index_next=0
self.music_list_win1.list_music_list.setCurrentRow(self.index_next)
self.choose_song_name_2(self.index_next)
music_list_index=self.index_next
def choose_song_name_2(self,current_ind:int):
self.playsong = self.songs_list[current_ind][-1]
self.playsongname=self.songs_list[current_ind][0]
self.playsong1 = self.playsong.replace('\\', '/')
self.get_music_info(self.playsong1)
self.player.setMedia(QMediaContent(QUrl(self.playsong)))
def doubleplay(self):
self.is_playing=False
self.slider.setValue(0)
self.choosesongname_mainwin_dbclk()
self.is_playing=True
if self.volunm_slider.value() == 0:
self.volunm_slider.setValue(6)
self.play_or_stop_mainwin_dbclk()
def doubleplay_subwin(self):
self.is_playing=False
self.slider.setValue(0)
self.choosesongname_subwin_dbclk()
self.is_playing=True
if self.volunm_slider.value() == 0:
self.volunm_slider.setValue(3)
self.play_or_stop_subwin_dbclk()
def play_or_stop_mainwin_dbclk(self):
if self.qlist.count()==0:
QMessageBox.about(self,'tips','no music')
return
if not self.player.isAudioAvailable():
self.choosesongname_mainwin_dbclk()
#self.choosesongname_subwin()
self.lbl_musicname.setText('歌曲名:' + self.playsongname)
self.lbl_musicname.adjustSize()
#print(self.slider.maximum())
if self.is_pause:
self.player.play()
#self.play_btn.setText('暂停')
self.is_pause=False
self.play_btn.setIcon(QIcon(QPixmap("music_play_pro2022\stopicon.jpeg")))
elif self.is_pause == False:
self.player.pause()
#self.play_btn.setText('播放')
self.is_pause=True
self.play_btn.setIcon(QIcon(QPixmap("music_play_pro2022\playicon.jpeg")))
def play_or_stop_subwin_dbclk(self):
if self.qlist.count()==0:
QMessageBox.about(self,'tips','no music')
return
if not self.player.isAudioAvailable():
#self.choosesongname()
self.choosesongname_subwin_dbclk()
self.lbl_musicname.setText('歌曲名:' + self.playsongname)
self.lbl_musicname.adjustSize()
self.music_lrc_text=self.load_music_lrc('music_play_pro2022\music_lrc\ghsy.lrc')
#print(self.music_lrc_text)
lrc_list2=self.fenxi_music_lrc(self.music_lrc_text)
for i in lrc_list2:
self.list_music_lrc.addItem(i[1])
#print(self.slider.maximum())
if self.is_pause:
self.player.play()
#self.play_btn.setText('暂停')
self.is_pause=False
self.play_btn.setIcon(QIcon(QPixmap("music_play_pro2022\stopicon.jpeg")))
elif self.is_pause == False:
self.player.pause()
#self.play_btn.setText('播放')
self.is_pause=True
self.play_btn.setIcon(QIcon(QPixmap("music_play_pro2022\playicon.jpeg")))
def play_or_stop_mainwin_next(self):
if self.qlist.count()==0:
QMessageBox.about(self,'tips','no music')
return
if not self.player.isAudioAvailable():
#self.choosesongname()
#self.choosesongname_subwin_dbclk()
#self.choosesongname_next()
self.lbl_musicname.setText('歌曲名:' + self.playsongname)
self.lbl_musicname.adjustSize()
self.music_lrc_text=self.load_music_lrc('music_play_pro2022\music_lrc\ghsy.lrc')
#print(self.music_lrc_text)
lrc_list2=self.fenxi_music_lrc(self.music_lrc_text)
for i in lrc_list2:
self.list_music_lrc.addItem(i[1])
#print(self.slider.maximum())
if self.is_pause:
self.player.play()
#self.play_btn.setText('暂停')
self.is_pause=False
self.play_btn.setIcon(QIcon(QPixmap("music_play_pro2022\stopicon.jpeg")))
elif self.is_pause == False:
self.player.pause()
#self.play_btn.setText('播放')
self.is_pause=True
self.play_btn.setIcon(QIcon(QPixmap("music_play_pro2022\playicon.jpeg")))
def get_music_info(self,filename):
self.fl=filename
#print(self.fl)
#self.probe = ffmpeg.probe(self.fl)
#self.format = self.probe['format']
#(self.format)
def load_music_lrc(self,music_file_name:str):
with open(music_file_name, "r",encoding="utf-8") as f:
return f.read()
def fenxi_music_lrc(self,lrc:str):
lrc1=lrc
lrc_list=lrc1.split("\n")
for i in range(len(lrc_list)):
lrc_list[i]=lrc_list[i][1:]
lrc_list[i]=lrc_list[i].split("]")
m1=int(lrc_list[i][0][:2]) * 60
m2=float(lrc_list[i][0][3:])
m=m1+m2
lrc_list[i][0]=m
print(lrc_list)
return lrc_list
if __name__ =='__main__':
app=QApplication(sys.argv)
mp1=Music_Play_win()
sys.exit(app.exec_())
qss样式文件:
/*
*
{
color:red;
}
窗体背景色为渐变色
*/
QWidget
{
background-color: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #81F5D8,stop:0.2 #43ABE7,stop:0.5 #57E7EC stop:1 #8EF068);
}
QListWidget
{
background-color:qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #81F5D8,stop:0.2 #43ABE7,stop:0.5 #57E7EC stop:1 #8EF068);
}
QMenuBar
{
background-color:#B5B0F7;
}
QMenu
{
background-color:#7FCDF1;
}
QPushButton
{
text-align:center;
color:rgb(14, 13, 13);
background-color:rgb(250, 250, 252);
}
QLabel
{
text-align: center;
font:lighter;
font-size:13px;
background-color:rgba(228, 236, 228, 0);
color:black;
}
QGroupBox
{
background-color:#9EF5E2;
}
QSlider
{
background-color:#4FF376;
}
QCheckBox
{
text-align: center;
}
QComboBox
{
text-align: center;
background-color: rgb(248, 249, 250);
}
QLineEdit
{
background-color: rgb(250, 250, 250);
}
QTextEdit
{
background-color:antiquewhite;
}
QMessageBox
{
icon:'CoDeSys.ico';
background-color: aquamarine;
}
最终效果(视频):
python音乐播放器演示(优化版)
转载:https://blog.csdn.net/normer123456/article/details/127567811