Python使用PyQt5/PySide2編寫一個極簡的音樂播放器功能
疫情肆虐,憋在家實在無聊,索性寫點(diǎn)東西,于是就有了這個極極極極極簡的音樂播放器。

這個極極極簡的音樂播放器類似于“閱后即焚”的軟件,播放器可以隨機(jī)播放歌曲,獲取下一首歌曲,不能重新播放上一首歌曲,不能獲取歌曲的名稱和演唱者。聽過的歌曲,就像過眼云煙,放完即散。
下面來看看如何用Python實現(xiàn)這個音樂播放器軟件吧!
一、創(chuàng)建UI界面
首先,我們來創(chuàng)建這個播放器的UI界面。這個播放器一共有6個控件:
- 左上角的程序關(guān)閉按鈕;
- 左側(cè)的播放狀態(tài)標(biāo)簽;
- 頂部的slogan;
- 播放/暫停按鈕;
- 下一首按鈕;
- 播放進(jìn)度條;
基于以上控件,我們用一個網(wǎng)格布局來排列;
class Music(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.setFixedSize(400,200)
self.setWindowTitle("州的先生")
self.init_ui()
self.custom_style()
self.playing = False # 播放狀態(tài)初始化為否
self.player = QMediaPlayer(self)
# 設(shè)置樣式
def custom_style(self):
self.setStyleSheet('''
#main_widget{
border-radius:5px;
}
#play_btn,#pervious_btn,#next_btn{
border:none;
}
#play_btn:hover,#pervious_btn:hover,#next_btn:hover{
background:gray;
border-radius:5px;
cursor:pointer;
}
''')
self.close_btn.setStyleSheet('''
QPushButton{
background:#F76677;
border-radius:5px;
}
QPushButton:hover{
background:red;
}''')
self.status_label.setStyleSheet('''
QLabel{
background:#F7D674;
border-radius:5px;
}
''')
# 初始化UI界面
def init_ui(self):
# 窗口布局
self.main_widget = QtWidgets.QWidget()
self.main_widget.setObjectName("main_widget")
self.main_layout = QtWidgets.QGridLayout()
self.main_widget.setLayout(self.main_layout)
# 標(biāo)題
self.title_lable = QtWidgets.QLabel("聽者,如過眼云煙……")
# 關(guān)閉按鈕
self.close_btn = QtWidgets.QPushButton("") # 關(guān)閉按鈕
self.close_btn.setFixedSize(15,15)
# 音樂狀態(tài)按鈕
self.status_label = QtWidgets.QLabel("")
self.status_label.setFixedSize(15,15)
# 播放按鈕
play_icon = qta.icon("fa.play-circle",)
self.play_btn = QtWidgets.QPushButton(play_icon,"")
self.play_btn.setIconSize(QtCore.QSize(80, 80))
self.play_btn.setFixedSize(82,82)
self.play_btn.setObjectName("play_btn")
# 下一首按鈕
next_icon = qta.icon("fa.play-circle-o")
self.next_btn = QtWidgets.QPushButton(next_icon,"")
self.next_btn.setIconSize(QtCore.QSize(80,80))
self.next_btn.setFixedSize(82,82)
self.next_btn.setObjectName("next_btn")
# 進(jìn)度條
self.process_bar = QtWidgets.QProgressBar()
self.process_value = 0
self.process_bar.setValue(self.process_value)
self.process_bar.setFixedHeight(5)
self.process_bar.setTextVisible(False)
self.main_layout.addWidget(self.close_btn,0,0,1,1)
self.main_layout.addWidget(self.title_lable,0,1,1,1)
self.main_layout.addWidget(self.status_label,1,0,1,1)
self.main_layout.addWidget(self.play_btn, 1, 1, 1, 1)
self.main_layout.addWidget(self.next_btn, 1, 2, 1, 1)
self.main_layout.addWidget(self.process_bar,2,0,1,3)
self.setCentralWidget(self.main_widget)
在上面的代碼中,我們通過Qt內(nèi)置的按鈕控件QPushButton、標(biāo)簽控件QLabel、進(jìn)度條控件QProgressBar等把播放器的基礎(chǔ)界面構(gòu)建好了,然后通過setStyleSheet()方法設(shè)置各個控件的樣式,最終得到下面的界面:

頂部的邊框有點(diǎn)丑丑的,我們通過setWindowFlag()將其隱藏起來:
self.setWindowFlag(QtCore.Qt.FramelessWindowHint) # 隱藏邊框
這樣,完整且好看的界面就完成了,如下圖所示:

二、獲取網(wǎng)絡(luò)歌曲
既然是音樂播放器,當(dāng)然要能夠播放音樂。我們創(chuàng)建的這個音樂播放器不能添加本地的音樂,那就只能播放網(wǎng)絡(luò)的音樂了。州的先生(https://zmister.com)在網(wǎng)上找了很久,終于找到了一個免費(fèi)穩(wěn)定的音樂接口。請求這個接口會隨機(jī)返回一個音樂的播放地址。正好符合我們的播放器的設(shè)定,就它了:
def run(self):
reps = requests.post("https://api.uomg.com/api/rand.music?format=json")
# print(reps.json())
file_url = reps.json()['data']['url']
self.finished_signal.emit(file_url)
我們將其用Qt的線程模塊QThread包裝起來,作為一個異步的子線程調(diào)用:

有了UI界面和網(wǎng)絡(luò)音樂,下面我們UI界面上的控件與音樂的播放通過信號槽(事件響應(yīng))連接起來。
三、創(chuàng)建和鏈接信號槽
因為我們隱藏的UI界面自帶的邊框,所以沒有了關(guān)閉按鈕。我們之前創(chuàng)建了左側(cè)小紅點(diǎn)作為播放器關(guān)閉的按鈕,接著還需要一個響應(yīng)函數(shù)來關(guān)閉播放器:
# 關(guān)閉程序 def close_btn_event(self): self.close() self.close_btn.clicked.connect(self.close_btn_event)
這樣,點(diǎn)擊小紅點(diǎn),播放器就可以關(guān)閉退出了。下面來處理音樂的播放。
在這里,我們借助Qt提供的QtMultimedia子模塊中的QMediaPlayer來實現(xiàn)MP3音樂的播放,QtMultimedia的詳細(xì)使用可見Qt的官方文檔:https://doc.qt.io/qtforpython/PySide2/QtMultimedia/index.html#module-PySide2.QtMultimedia:

這個方法,接受一個MP3音樂的網(wǎng)絡(luò)地址參數(shù),然后通過配置,對其進(jìn)行播放。
我們之前創(chuàng)建了一個繼承于QThread的網(wǎng)絡(luò)歌曲獲取類GetMusicThread,通過創(chuàng)建另一個方法對其進(jìn)行調(diào)用,并將完成信號(finished_signal)連接到init_player()方法即可實現(xiàn)網(wǎng)絡(luò)歌曲的獲取和播放:

在這里,next_music()方法調(diào)用GetMusicThread隨機(jī)獲取一首歌曲,然后將歌曲的URL地址返回給init_player()方法,以實現(xiàn)播放。
next_music()方法是播放歌曲的主要方法,播放按鈕、下一首按鈕、一首歌曲播放完之后自動播放下一首歌曲都可以調(diào)用它。
播放音樂按鈕需要控制和判斷音樂的狀態(tài),可通過QMediaPlayer的mediaStatus()方法獲取,并以此來進(jìn)行判斷:

為了能夠在播放完一首歌曲后自動獲取和播放下一首歌曲,我們需要創(chuàng)建一個計時器,每隔一秒獲取當(dāng)前播放器的狀態(tài),判斷其是否已經(jīng)播放完了音樂,如果播放完了,就調(diào)用next_music()方法:
self.timer = QtCore.QTimer()
self.timer.setInterval(1000)
self.timer.start()
self.timer.timeout.connect(self.check_music_status)
def check_music_status(self):
player_status = self.player.mediaStatus()
player_duration = self.player.duration()
# print("音樂時間:",player_duration)
# print("當(dāng)前播放器狀態(tài)",player_status)
if player_status == 7:
self.next_music()
再經(jīng)過一些細(xì)節(jié)調(diào)整,我們就完成了這個“聽后即焚”的網(wǎng)絡(luò)音樂播放器:

完整的代碼可以前往州的先生在Gitee上的倉庫(https://gitee.com/zmister/yunyan_music )
總結(jié)
以上所述是小編給大家介紹的使用PyQt5/PySide2編寫一個極簡的音樂播放器功能,希望對大家有所幫助!
相關(guān)文章
django 實現(xiàn)將本地圖片存入數(shù)據(jù)庫,并能顯示在web上的示例
今天小編就為大家分享一篇django 實現(xiàn)將本地圖片存入數(shù)據(jù)庫,并能顯示在web上的示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08
numpy如何取出對角線元素、計算對角線元素和np.diagonal
這篇文章主要介紹了numpy如何取出對角線元素、計算對角線元素和np.diagonal問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06
Python實現(xiàn)批量合并Excel文件的第二張合并Excel
在數(shù)據(jù)處理和分析中,經(jīng)常需要對多個Excel文件進(jìn)行批量操作,特別是當(dāng)這些文件具有相似的結(jié)構(gòu)時,下面我們就來看看Python如何實現(xiàn)批量合并文件夾下所有Excel文件的第二張表吧2024-03-03
Python輕松獲取網(wǎng)絡(luò)時間和本地時間技巧揭秘
這篇文章主要為大家介紹了Python輕松獲取網(wǎng)絡(luò)時間和本地時間技巧揭秘,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
python實現(xiàn)識別手寫數(shù)字 python圖像識別算法
這篇文章主要為大家詳細(xì)介紹了python實現(xiàn)識別手寫數(shù)字,python圖像識別算法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01

