玩壞了,用 Python 制作 GUI 鋼琴~
↑ 關(guān)注 + 星標(biāo) ,每天學(xué)Python新技能
后臺(tái)回復(fù)【大禮包】送你Python自學(xué)大禮包
前一段時(shí)間刷b站,看到一些up主制作的Matlab鋼琴很火,很好玩的樣子
作為 Python 區(qū)技術(shù)博主,第一想法當(dāng)然是能否用 Python 也做一個(gè),既好玩也能用于教學(xué),經(jīng)過一番研究總算折騰出來一個(gè)簡易版??
本文就分享一下思路與代碼。
實(shí)現(xiàn)思路
在寫代碼之前,還是先整理下思路,用Python實(shí)現(xiàn)的話,只需要?jiǎng)?chuàng)建界面與按鈕,并給每個(gè)按鈕綁定播放音階的函數(shù)即可,這樣簡單的功能肯定用不著PyQt這樣的大家伙,tkinter就能完美實(shí)現(xiàn)。
下面的問題就轉(zhuǎn)到如何使用Python播放音頻文件,首先搜了下,了解到playsound庫
from playsound import playsound
playsound('A4.mp3')
就像上面代碼展示的一樣,兩行代碼就能播放mp3,但也僅限于此,無法指定播放時(shí)長等功能,如果一個(gè)音階時(shí)長8s,必須要等上一個(gè)播放完畢才能播放下一個(gè),這樣的話輸出的聲音就不能連貫。
繼續(xù)研究之后發(fā)現(xiàn)pygame可以完美實(shí)現(xiàn)音頻播放與簡單處理,并且配合time庫可以控制播放時(shí)長,例如每個(gè)音階只播放 1s
from pygame import mixer
pygame.mixer.music.play()
time.sleep(10)
pygame.mixer.music.stop()
但是這樣的話,在兩個(gè)音階之間切換時(shí)會(huì)有一個(gè)爆音,于是可以使用fadeout(time)進(jìn)行淡出,在指定時(shí)間內(nèi)音量由初始值漸變?yōu)?,最后停止播放。
但這樣的話,會(huì)在兩個(gè)音階切換時(shí)有延遲,如果想要沒有延遲的話就需要使用多線程來進(jìn)行播放,但在tkinter中使用多線程似乎是比較復(fù)雜的,遂切換思路,使用mixer.Sound方法來進(jìn)行播放,仍是兩行代碼就能播放,并且可以同時(shí)按下多個(gè)按鍵!
from pygame import mixer
mixer.Sound("mp3/Cs1.wav").play()
搞定了音樂播放后面就是體力活了,下面開寫代碼!
Python實(shí)現(xiàn)
首先是下載對(duì)應(yīng)的全部音階文件,隨便找個(gè)鋼琴網(wǎng)站 F12 一下就能找到,至于tkinter的部分并沒有太多,只是常規(guī)的創(chuàng)建標(biāo)題、按鈕
master.title("Python_Piano_GUI")
master.geometry("1766x460")
self.Cs1_button = Button(master,bg="black", fg='white',text="C1#", command=Cs1, height=180, width=50)
self.Cs1_button.grid(row=1, columnspan=2)
self.D1_button = Button(master, bg="white", text="D1", height=200, width=50)
self.D1_button.grid(row=5, column=1)
self.Ds1_button = Button(master, bg="black", fg="white", text="D1#", command=Ds1, height=180, width=50)
self.Ds1_button.grid(row=1, columnspan=4)
·······
需要注意的是,在mac系統(tǒng)下是無法通過設(shè)置background調(diào)整按鈕的背景顏色,需要安裝tkmacosx來解決。
此外,為了讓按下按鈕能對(duì)應(yīng)變化按鈕顏色需要監(jiān)聽系統(tǒng)鍵盤的按下(press)與釋放(release)
def on_key_release(event):
if event.keysym in keys:
keys[event.keysym].config(bg=btn_bg)
master.bind('<KeyPress>', play_music)
master.bind("<KeyRelease>", on_key_release)
其余部分的代碼就都是重復(fù)且枯燥的復(fù)制粘貼播放音樂,此處不再解釋,最終效果如下
-END-
推薦閱讀
您看此文用 ![]()
分
![]()
秒,轉(zhuǎn)發(fā)只需1秒

分
秒,轉(zhuǎn)發(fā)只需1秒