⾃⼰⽤python做的⼀款超炫酷⾳乐播放器
⽬录
前⾔
⼀、核⼼功能设计
UI设计排版布局
关键字⾳乐列表爬⾍
⾳乐播放
附加功能
⼆、实现步骤
1.UI设计排版布局
2.关键字⾳乐列表爬⾍
3.⾳乐播放
故障灯亮4.附加功能
三、结束语
前⾔
晚上坐在电脑⾯前,想着⼀边撸代码,⼀边听⾳乐。搜了搜⾃⼰想听的歌,奈何好多歌曲都提⽰需要版权,⽆法播放!
没办法,想听歌还是得靠⾃⼰解决!今天就⼀起⽤python⾃制⼀款炫酷的⾳乐播放器吧~
⾸先⼀起来看看最终实现的⾳乐播放器效果:
下⾯,我们开始介绍这个⾳乐播放器的制作过程。
⼀、核⼼功能设计
总体来说,我们⾸先需要设计UI界⾯,对播放器的画⾯布局进⾏排版设计;其次我们的这款⾳乐播放器的主要功能包括根据关键字搜索⾃动爬取⾳乐,获取⾳乐列表,能进⾏⾳乐播放。
当然还少不了⼀些附加功能,例如播放⽅式列表循环、单曲循环、随机播放,当前上⼀⾸下⼀⾸播放,播放暂停开始,⾳量增加减少,播放历史查看等。
拆解需求,⼤致可以整理出核⼼功能如下:
UI设计排版布局
头部主要包括关键字搜索和⾳乐来源选择,以及窗体最⼩化,最⼤化,关闭功能
中间主体包含左右两侧,左侧⽤来显⽰播放⾳乐封⾯图,右侧⽤来进⾏⾳乐列表显⽰
底部主要来显⽰当前播放⾳乐,播放进度条,⾳量控制,上⼀⾸/下⼀⾸,暂停/开始,播放⽅式等附加功能关键字⾳乐列表爬⾍
通过输⼊的搜索关键字和选择的⾳乐来源,⾃动爬取对应的⾳乐数据
将爬取获取的⾳乐名进⾏列表显⽰,显⽰在中间主体搜索页
肝虚怎么调理
⾳乐播放
⾳乐列表中我们需要双击某⼀⾸歌,对爬取的歌曲封⾯图和歌曲进⾏下载
牛的饲养管理下载成功,对⾳乐⽂件根据播放进度条进⾏播放
附加功能
播放⾳乐时,我们还需要有播放暂停和启动功能
⾳量控制提⾼或者降低
当前播放歌曲上⼀⾸、下⼀⾸
⾳乐列表播放⽅式,列表循环、单曲循环、随机播放
⼆、实现步骤
1. UI设计排版布局
基于功能点,我们⾸先考虑进⾏简单的UI布局设计,这⾥我们使⽤的是pyqt5。核⼼设计代码如下:
def init_ui(lf):
global type
lf.tFixedSize(1025, 750)
lf.main_widget = QWidget() # 创建窗⼝主部件
lf.main_layout = QGridLayout() # 创建主部件的⽹格布局
觉多音字
lf.main_widget.tLayout(lf.main_layout) # 设置窗⼝主部件布局为⽹格布局
lf.clo_widget = QWidget() # 创建关闭侧部件
lf.clo_widget.tObjectName('clo_widget')
lf.clo_layout = QGridLayout() # 创建左侧部件的⽹格布局层
lf.clo_widget.tLayout(lf.clo_layout) # 设置左侧部件布局为⽹格
lf.left_widget = QWidget() # 创建左边侧部件
lf.left_widget.tObjectName('left_widget')
lf.left_layout = QGridLayout() # 创建左侧部件的⽹格布局层
lf.left_widget.tLayout(lf.left_layout) # 设置左侧部件布局为⽹格
lf.right_widget = QWidget() # 创建右侧部件
lf.right_widget.tObjectName('right_widget')
lf.right_layout = QGridLayout()
lf.right_widget.tLayout(lf.right_layout) # 设置右侧部件布局为⽹格
lf.down_widget = QWidget() # 创建下⾯部件
lf.down_widget.tObjectName('down_widget')
lf.down_layout = QGridLayout()
lf.down_widget.tLayout(lf.down_layout) # 设置下侧部件布局为⽹格
lf.up_widget = QWidget() # 创建下⾯部件
lf.up_widget.tObjectName('up_widget')
lf.up_layout = QGridLayout()
lf.up_widget.tLayout(lf.up_layout) # 设置下侧部件布局为⽹格
lf.label = QLabel(lf)
lf.label.tText("还没有播放歌曲呢╰(*°▽°*)╯")
lf.label.tStyleSheet("color:white")
lf.label.tMaximumSize(310, 20)
lf.main_layout.addWidget(lf.up_widget, 0, 0, 1, 115)
lf.main_layout.addWidget(lf.left_widget, 1, 0, 90, 25)
lf.main_layout.addWidget(lf.right_widget, 1, 25, 90, 90) # 22右侧部件在第0⾏第3列,占8⾏9列
lf.main_layout.addWidget(lf.down_widget, 100, 0, 10, 115)
lf.main_layout.addWidget(lf.clo_widget, 0, 110, 1, 5) # 左侧部件在第0⾏第0列,占1⾏3列
lf.down_layout.addWidget(lf.label, 1, 0, 1, 1)
lf.tCentralWidget(lf.main_widget) # 设置窗⼝主部件
lf.tabWidget = QTabWidget(lf)
lf.tabWidget.tGeometry(QRect(33, 20, 716, 471))
lf.tab = QWidget()
lf.tab.tObjectName("tab")
lf.tab_layout = QGridLayout()
lf.tab.tLayout(lf.tab_layout)
lf.listwidget = QListWidget(lf.tab)
lf.t(lambda: lf.change_func(lf.listwidget))
lf.listwidget.tContextMenuPolicy(Qt.CustomContextMenu)
lf.listwidget.customContextMenuRequested[QPoint].ListWidgetContext)
lf.listwidget.tObjectName("listWidget")
lf.tab_layout.addWidget(lf.listwidget, 0, 0, 1, 1)
lf.tabWidget.addTab(lf.tab, " 搜索页 ")
lf.tab2 = QWidget()
lf.tab2.tObjectName("tab")
lf.tab2_layout = QGridLayout()
lf.tab2.tLayout(lf.tab2_layout)
lf.listwidget2 = QListWidget(lf.tab2)
lf.t(lambda: lf.change_func(lf.listwidget2))
lf.listwidget2.tContextMenuPolicy(Qt.CustomContextMenu)
lf.listwidget2.customContextMenuRequested[QPoint].ListWidgetContext2)
lf.listwidget2.tObjectName("listWidget2")
lf.listwidget2.tContextMenuPolicy(3)
lf.tab2_layout.addWidget(lf.listwidget2, 0, 0, 1, 1)
lf.tabWidget.addTab(lf.tab2, " 最近播放 ")
lf.right_layout.addWidget(lf.tabWidget, 3, 0, 100, 90)
lf.left_clo = QPushButton("") # 关闭按钮
lf.left_t(lf.clo)
lf.left_visit = QPushButton("") # 空⽩按钮
lf.left_t(lf.big)
lf.left_mini = QPushButton("") # 最⼩化按钮
lf.left_t(lf.mini)
lf.clo_layout.addWidget(lf.left_mini, 0, 0, 1, 1)
lf.clo_layout.addWidget(lf.left_clo, 0, 2, 1, 1)
lf.clo_layout.addWidget(lf.left_visit, 0, 1, 1, 1)
lf.left_clo.tFixedSize(15, 15) # 设置关闭按钮的⼤⼩
lf.left_visit.tFixedSize(15, 15) # 设置按钮⼤⼩
lf.left_mini.tFixedSize(15, 15) # 设置最⼩化按钮⼤⼩
lf.left_clo.tStyleSheet(
'''QPushButton{background:#F76677;border-radius:5px;}QPushButton:hover{background:red;}''')
lf.left_visit.tStyleSheet(
'''QPushButton{background:#F7D674;border-radius:5px;}QPushButton:hover{background:yellow;}''') lf.left_mini.tStyleSheet(
'''QPushButton{background:#6DDF6D;border-radius:5px;}QPushButton:hover{background:green;}''') lf.button_123 = QLabel("")
lf.left_layout.addWidget(lf.button_123, 0, 2, 2, 2)
lf.label2 = QLabel(lf)
lf.label2.tText("当前为顺序播放")
lf.label2.tStyleSheet("color:green")
lf.left_layout.addWidget(lf.label2, 4, 0, 2, 1)
lf.button_1234 = QPushButton(icon('fa.download', color='#3FC89C', font=24), "")
lf.button_t(lf.down)
lf.button_1234.tStyleSheet(
'''QPushButton{background:#222225;border-radius:5px;}QPushButton:hover{background:#3684C8;}''') lf.left_layout.addWidget(lf.button_1234, 4, 2, 2, 1)
lf.button_1234 = QPushButton(icon('fa.heart', color='#3FC89C', font=24), "")
lf.button_t(lf.lovesong)
lf.button_1234.tStyleSheet(
'''QPushButton{background:#222225;border-radius:5px;}QPushButton:hover{background:#3684C8;}''') lf.left_layout.addWidget(lf.button_1234, 4, 3, 2, 2)
lf.label3 = QLabel(lf)
lf.label3.tText("")
lf.label3.tStyleSheet("color:white")
lf.down_layout.addWidget(lf.label3, 1, 3, 1, 1)
lf.label7 = QLabel(lf)
lf.label7.tText("")
lf.label7.tStyleSheet("color:white")
lf.label5 = QLabel(lf)
pix_img = QPixmap(str(data + '/backdown.png'))
pix = pix_img.scaled(300, 300, Qt.KeepAspectRatio)
lf.label5.tPixmap(pix)
# lf.label5.tMaximumSize(1,1)
lf.left_layout.addWidget(lf.label5, 2, 0, 2, 8)
lf.label6 = QLabel(lf)
lf.label6.tText("")
lf.label6.tStyleSheet("color:#6DDF6D")
lf.left_layout.addWidget(lf.label6, 2, 0, 2, 2)
lf.label23 = QLabel(lf)
lf.label23.tText(" ")
lf.label23.tStyleSheet("color:#6DDF6D")
lf.up_layout.addWidget(lf.label23, 0, 100, 1, 20)
lf.shuru = QLineEdit("")
lf.up_layout.addWidget(lf.shuru, 0, 120, 1, 40)
t)
lf.label23 = QLabel(lf)
lf.label23.tText(" 软件")
lf.label23.tStyleSheet("color:#6DDF6D")
我是你的小妖lf.up_layout.addWidget(lf.label23, 0, 160, 1, 10)
lf.label61 = QLabel(lf)
lf.label61.tText("")
lf.label61.tStyleSheet("color:#6DDF6D")
lf.up_layout.addWidget(lf.label61, 0, 200, 1, 50)
lf.cb = QComboBox(lf)
lf.cb.addItems(['⽹易云', '酷狗', 'qq'])
lf.up_layout.addWidget(lf.cb, 0, 180, 1, 30)
lf.cb.currentIndexChanged[int].connect(lf.print)
lf.button_1 = QPushButton(icon('fa.arch', color='white'), "")
lf.button_t)
lf.button_1.tStyleSheet(
'''
QPushButton{color:white;border-radius:5px;}QPushButton:hover{background:green;}
''')
lf.up_layout.addWidget(lf.button_1, 0, 155, 1, 5)
lf.right_process_bar = QProgressBar() # 播放进度部件
lf.right_process_bar.tValue(49)
lf.right_process_bar.tFixedHeight(3) # 设置进度条⾼度
lf.right_process_bar.tTextVisible(Fal) # 不显⽰进度条⽂字
lf.right_process_bar.tRange(0, 10000)
lf.right_playconsole_widget = QWidget() # 播放控制部件
lf.right_playconsole_layout = QGridLayout() # 播放控制部件⽹格布局层
lf.right_playconsole_widget.tLayout(lf.right_playconsole_layout)
'''QPushButton{background:#222225;border-radius:5px;}QPushButton:hover{background:#3684C8;}''') lf.console_button_2 = QPushButton(icon('fa.forward', color='#3FC89C'), "")
'''QPushButton{background:#222225;border-radius:5px;}QPushButton:hover{background:#3684C8;}''') lf.console_button_3 = QPushButton(icon('fa.pau', color='#3FC89C', font=18), "")
'''QPushButton{background:#222225;border-radius:5px;}QPushButton:hover{background:#3684C8;}''') lf.console_button_4 = QPushButton(icon('fa.volume-down', color='#3FC89C', font=18), "")
'''QPushButton{background:#222225;border-radius:5px;}QPushButton:hover{background:#3684C8;}''') lf.console_button_5 = QPushButton(icon('fa.volume-up', color='#3FC89C', font=18), "")
'''QPushButton{background:#222225;border-radius:5px;}QPushButton:hover{background:#3684C8;}''') lf.console_button_6 = QPushButton(icon('fa.align-center', color='#3FC89C', font=18), "")
'''QPushButton{background:#222225;border-radius:5px;}QPushButton:hover{background:#3684C8;}''')
心血宁片
lf.right_playconsole_layout.sole_button_4, 0, 0)
lf.right_playconsole_layout.sole_button_1, 0, 1)
电脑怎么保存图片lf.right_playconsole_layout.sole_button_3, 0, 2)
lf.right_playconsole_layout.sole_button_2, 0, 3)
lf.right_playconsole_layout.sole_button_5, 0, 4)
lf.right_playconsole_layout.sole_button_6, 0, 5)
lf.right_playconsole_layout.tAlignment(Qt.AlignCenter) # 设置布局内部件居中显⽰
芒果木lf.down_layout.addWidget(lf.right_process_bar, 0, 0, 1, 4) # 第0⾏第0列,占8⾏3列
# 第0⾏第0列,占8⾏3列
lf.down_layout.addWidget(lf.label7, 1, 2, 1, 1)
lf.down_layout.addWidget(lf.right_playconsole_widget, 1, 0, 1, 4)
lf.tWindowOpacity(0.95) # 设置窗⼝透明度
lf.tAttribute(Qt.WA_TranslucentBackground)
lf.tWindowFlag(Qt.FramelessWindowHint) # 隐藏边框
lf.main_layout.tSpacing(0)
实现效果如下:
2. 关键字⾳乐列表爬⾍
我们可以根据输⼊的关键字和⾳乐来源进⾏⾳乐爬取。这⾥我们需要通过多线程,将歌曲、歌⼿、歌曲url地址全都获取。核⼼代码如下:
def run(lf):
qmut.lock()
try:
global paing
global stop
global lrcs
global urls
global songs
global name
global songid
global proxies
global pic
global tryed