本来想把之前OCR重写UI再端上来的说
但是马上就期中了,所以就把之前的音乐播放器拿出来给大家看看吧

Python 库的导入

1
2
3
4
5
6
7
import tkinter
from tkinter import *
from tkinter import filedialog
from tkinter import messagebox
from tkinter import ttk
import os.path
import pygame

这里用的是tkinter图形库,pygame来做播放音乐的模块,os.path检测文件是否存在

初始化列表

1
2
music_show=[]
music_list=[]

这两个列表,music_list来储存音乐路径,music_show来储存显示的歌曲名字

检测文件是否存在

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if os.path.exists('song.txt'):
with open('song.txt', 'r')as rf:
content = rf.readlines() # 读取所有行
for i in content:
i = str(i).replace('\n', '')
music_list.append(i)
print(content)
print(music_list)
for item in music_list:
filename = os.path.basename(item)
music_show.append(filename)
else:
file_path = None
music_list = []
music_show = []

检测文件是否存在,并替换其中的换行符储存到music_list中
如果不存在就初始化变量

注意这边要写readlines不然会把所有的一个个字母拆分下来储存到列表中去

按照我写代码的习惯,我喜欢先空出地方,把UI放在后面,先写UI。但是想了想发现写博客不易看懂,所以提前到这里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
def root():
global musiclist
root = tkinter.Tk()
root.geometry('1035x715')
root.title('音乐播放器')
information = Label(root, text='音乐播放器', font=('微软雅黑', 20))
information.place(relx=0.0772946859903382, rely=0.0839160839160839)
musiclist = Listbox(root, width=130, height=30)
musiclist.place(relx=0.0772946859903382, rely=0.1398601398601399,
relwidth=0.8, relheight=0.741958041958042)
gun = Scrollbar(musiclist, orient=VERTICAL, width=20)
gun.pack(side=tkinter.RIGHT, fill=tkinter.Y)
addmusic = Button(root, text='添加音乐', font=('微软雅黑', 10), command=add)
addmusic.place(relx=0.0966183574879227, rely=0.9230769230769231,
relheight=0.0559440559440559, relwidth=0.0676328502415459)
playmusic = Button(root, text='开始播放', font=('微软雅黑', 10), command=play)
playmusic.place(relx=0.21256038647343, rely=0.9230769230769231,
relheight=0.0559440559440559, relwidth=0.0676328502415459)
stopmusic = Button(root, text='停止', font=('微软雅黑', 10), command=stop)
stopmusic.place(relx=0.3285024154589372, rely=0.9230769230769231,
relheight=0.0559440559440559, relwidth=0.0676328502415459)
deletmusci = Button(root, text='删除', font=('微软雅黑', 10), command=delet)
deletmusci.place(relx=0.4444444444444444, rely=0.9230769230769231,
relheight=0.0559440559440559, relwidth=0.0676328502415459)
continuemusic = Button(root, text='继续播放', font=(
'微软雅黑', 10), command=continueplay)
continuemusic.place(relx=0.5603864734299517, rely=0.9230769230769231,
relheight=0.0559440559440559, relwidth=0.0676328502415459)
loud = Button(root, text='音量', font=('微软雅黑', 10), command=voice)
loud.place(relx=0.6763285024154589, rely=0.9230769230769231,
relheight=0.0559440559440559, relwidth=0.0676328502415459)
for i in music_show:
musiclist.insert(tkinter.END, i)
root.mainloop()

添加UI,没什么东西
我用的是相对坐标,比值算的比较细(就细了那么亿点)应该能看得懂吧
字体我是随便选的,不过我还是觉得苹果的苹方看着舒服

添加音乐

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def add():
file_types = [('Audio', '*.mp3'), ('Audio', '*.wav'), ('Audio', '*.ogg')]
file_path = filedialog.askopenfilename(filetypes=file_types)
# music_list.append(file_path)
if file_path:
music_list.append(file_path)
with open('song.txt', 'w', encoding='utf-8')as f:
for i in music_list:
i = i+'\n'
f.write(i)

for item in music_list:
filename = os.path.basename(item)
music_show = []
music_show.append(filename)
for i in music_show:
musiclist.insert(tkinter.END, i)

先调用tkinter的文件选择,并限定格式,防止选中一些奇奇怪怪的东西进去
(什么?你问我为什么就这三种格式?想要别的格式可以pydub,可惜我不会用ffmpeg所以不多阐述)
然后将路径添加至music_list并IO写入文件保存下来(我为了省事直接txt了,感兴趣的可以json)

filename=os.path.basename(item) 分离文件名和路径并存入music_show,待会用于展示

删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
def delet():
global index
if musiclist.curselection(): # 检查是否有选中的条目
index = musiclist.curselection()[0]
del music_list[index]
# print (music_list)
with open('song.txt', 'w', encoding='utf-8')as f:
for i in music_list:
i = i+'\n'
f.write(i)
music_show = []
for item in music_list:
filename = os.path.basename(item)
music_show.append(filename)
# print (music_show)
musiclist.delete(0, tkinter.END)
try:
for i in music_show:
musiclist.insert(tkinter.END, i)
except:
musiclist.delete(0, tkinter.END)

else:
messagebox.showinfo("提示", "请先选择一首音乐。")

首先,获取选中Listbox的条目的索引
然后删除对应索引的元素

注意:当列表中只剩下一个元素又被删干净之后,list列表内无元素,无法写入show列表,所以try except排异

删除完记得重写覆写文件

播放音乐(终于能听个响了)

1
2
3
4
5
6
7
8
9
10
11
12
13
def play():
global current_music, sign, index
pygame.mixer.init()
pygame.mixer.music.stop()
if musiclist.curselection(): # 检查是否有选中的条目
index = musiclist.curselection()[0]
sign = index
pygame.mixer.init()
pygame.mixer.music.load(music_list[index])
pygame.mixer.music.play(0)
else:
messagebox.showinfo("提示", "请先选择一首音乐。")

global声明全局变量,因为下面暂停播放和取消播放也要用到
调用pygame模块,先停止所有音乐播放(防止冲突)再根据所选索引播放音乐
如果没有选择,则messagebox提示

停止

1
2
def stop():
pygame.mixer.music.pause()

暂时暂停而不是取消播放,取消是stop

继续播放

与普通的播放不同,这个是继续刚刚暂停的任务

1
2
def continueplay():
pygame.mixer.music.unpause()

音量调整

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def voice():
global setloud
voice = Toplevel()
voice.geometry('170x300')
voice.title('音量调整')
setloud = ttk.Scale(voice, from_=0, to=100,
orient="horizontal", command=adjust_volume)
setloud.pack()


def adjust_volume(event):
volume = setloud.get() / 100.0 # 将滑块值转换为0.0到1.0之间的音量值
pygame.mixer.init()
pygame.mixer.music.set_volume(volume) # 设置声道的音量

先全局变量
然后创建一个子窗口voice
创建滑条并关联音量百分比

root()

启动!