用python的tkinter写一个音乐播放器

花了几天时间用python写里一个音乐播放器

最近对用python做gui很感兴趣,就学了一下tkinter,主要参考的《疯狂python》这本书,期间碰到一些比较i麻烦的问题,但最终都解决了,然后也解决了很多bug,做出来的播放器虽然不好看(完全没怎么在意美观的问题,界面美化的话花的时间总能做好的,作为实用主义就不花时间做美化了),但是自己用的时候感觉还是满意的,作为播放器该有的功能也有,当然不能和网易云音乐比,也只能播放本地音乐,不能在线。下面是代码,差不多1000行,菜鸟水平所以代码编得啰嗦才这么多行。

from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from tkinter import simpledialog
import re
import psutil as ps
import os
import pathlib as pa
# from tkinter import messagebox
from pygame import mixer
# import eyed3
# import time
from tinytag import TinyTag as ti
from threading import Timer
from random import randint


##music list choose
class mlf(Toplevel):
    def __init__(self, parent, stems, lb_test, musiclist, playlist):
        Toplevel.__init__(self, parent)
        self.transient(parent)
        self.title('Files you find')
        self.parent = parent
        self.grab_set()
        self.lb_test = lb_test
        self.fr = ttk.Labelframe(self, text='Choose desks to scan')
        self.fr.pack(side=TOP, fill=BOTH, expand=YES)
        self.stems = stems
        self.select_stem = []
        self.musiclsit = musiclist
        self.playlist = playlist
        self.lb = Listbox(self.fr, font=('微软雅黑', 10, 'bold'), selectmode='extended')
        self.lb.pack(side=LEFT, fill=BOTH, expand=YES)
        for stem in stems:
            self.lb.insert(END, pa.Path(stem).stem)
        scroll = ttk.Scrollbar(self.fr, command=self.lb.yview)
        scroll.pack(side=RIGHT, fill=BOTH)
        self.lb.configure(yscrollcommand=scroll.set)
        self.select_all = ttk.Button(self, text='Select all', command=self.select_allf)
        self.select_all.pack(side=LEFT, fill=Y, expand=YES)
        self.ok = ttk.Button(self, text='Ok', command=self.okf)
        self.ok.pack(side=LEFT, fill=Y, expand=YES)
        self.quit_all = ttk.Button(self, text='Quit all', command=self.quit_allf)
        self.quit_all.pack(side=RIGHT, fill=Y, expand=YES)

    def select_allf(self):
        self.lb.selection_set(0, END)

    def okf(self):
        print(self.lb.curselection())
        for x in self.lb.curselection():
            if x not in self.select_stem:
                self.select_stem.append(self.stems[x])
        print(self.select_stem)
        for x in self.select_stem:  # should create a txt to save musiclist !!
            if x not in self.musiclsit:
                self.musiclsit.append(x)
                self.lb_test.insert(END, pa.Path(x).stem)
                self.playlist.append(x)
        self.destroy()

    def quit_allf(self):
        self.lb.selection_clear(0, END)


# Custom Dialog
class sfs(Toplevel):
    def __init__(self, parent, lb, sf, musiclist, save, playlist):
        Toplevel.__init__(self, parent)
        self.transient(parent)
        self.title('Choose desks and Scan files')
        self.parent = parent
        self.grab_set()
        self.lb_test = lb
        self.musiclist = musiclist
        self.playlist = playlist
        self.sf = sf
        self.save = save
        fr = ttk.Labelframe(self, text='Choose desks to scan')
        fr.pack()
        d = ps.disk_partitions()
        # limit files size
        self.test = FALSE
        self.maxs = IntVar()
        self.mins = IntVar()
        self.maxs.set(50)
        self.mins.set(1)
        self.ax = []
        self.bool = BooleanVar()
        self.bool.set(FALSE)

        for xx in d:
            if not xx[3] == 'cdrom':
                print(xx[0])
                self.ax.append(xx[0])
        i = 0
        self.desks = []
        for desk in self.ax:
            strVar = StringVar()
            self.desks.append(strVar)
            cb = ttk.Checkbutton(self, text=desk, variable=strVar, onvalue=str(i), offvalue='none',
                                 command=self.choose);
            i += 1
            cb.pack(anchor=W)
        self.ok = ttk.Button(self, text='Ok', command=self.okf);
        self.ok.pack(side=LEFT, fill=Y, expand=YES)
        self.cancel = ttk.Button(self, text='Return', command=self.cancelf)
        self.cancel.pack(side=LEFT, fill=Y, expand=YES)
        self.sizel = ttk.Button(self, text='Limit the file size', command=self.sizelf)
        self.sizel.pack(side=RIGHT, fill=Y, expand=YES)

    def choose(self):
        st = [e.get() for e in self.desks]
        print(st)

    def okf(self):
        st = [e.get() for e in self.desks]
        # print(st)
        sc = []
        for xx in range(len(st)):
            if str(xx) in st:
                sc.append(self.ax[xx])
        print(sc)

        stems = []
        # for format in ('.mp3','.flac'):\for x in p.glob('**/*'):
        for fx in sc:
            px = pa.Path(fx)
            for x in px.glob('**/*'):
                if ti.is_supported(str(x.name)):
                    # print(x)
                    if (os.path.getsize(x)) > self.mins.get() * 1024 * 1024 and (
                    os.path.getsize(x)) < self.maxs.get() * 1024 * 1024:
                        stems.append(x)
        test = mlf(self, stems, self.lb_test, self.musiclist, self.playlist)

    def cancelf(self):
        self.parent.focus_set()
        self.destroy()
        print('sss')
        self.bool.set(TRUE)
        self.test = TRUE
        self.sf['style'] = 'SM.TLabel'
        self.save()

    def sizelf(self):
        maxs = simpledialog.askinteger('Minimum szie', 'the minimum size of files (\M)', initialvalue=1, )
        mins = simpledialog.askinteger('Maximum szie', 'the maximum size of files (\M)', initialvalue=50)
        if maxs:
            self.mins.set(maxs)
        if mins:
            self.maxs.set(mins)

        print(self.maxs.get())
        print(self.mins.get())


class App():
    def __init__(self, master):
        self.master = master
        self.initt()

    def initt(self):
        titlefont = ('simkai', 15, 'bold')
        self.musiclist = []
        self.playlist = []#播放列表
        self.lines = []
        self.pbl = []
        self.pl = []  # playlist  歌单列表
        self.like=[]#like 歌单第一个
        self.filepathlist=[]  #file path list
        self.play_if = BooleanVar()
        self.play_if.set(FALSE)
        self.is_all = BooleanVar()
        self.is_all.set(TRUE)
        self.playinglist = StringVar()

        self.filename = 'save_music.txt'
        mixer.init()
        self.playing = StringVar()
        self.endsave=[]#save_end_

        try:
            with open(self.filename, 'r+', True, 'UTF-8') as ff:
                self.lines = ff.readlines()
        except:
            f = open(self.filename, 'w+', True, 'UTF-8')
            f.write('musiclist--> \n')
            f.write('playlist--> \n')
            f.write('Like (protected playlist)\n')
            f.write('end--> \n')
            f.write("mode 3\n")
        with open(self.filename, 'r+', True, 'UTF-8') as ff:
            self.lines = ff.readlines()
            if self.lines[1] == 'playlist--> \n':
                print('musiclist is empty')
            else:
                print('tt')
                for line in self.lines[1:self.lines.index(('playlist--> \n'))]:
                    if not line == '\n':
                        self.musiclist.append(line[0:-1])
            if self.lines.index('playlist--> \n') == self.lines.index('end--> \n') - 1:
                print('playlist is empty')
            else:
                for line in self.lines[self.lines.index('playlist--> \n') + 1:self.lines.index('end--> \n')]:
                    if not line == '\n':
                        self.pbl.append(line[0:-1])
                for line in self.lines[self.lines.index('end--> \n')+1: ]:
                    self.endsave.append(line)
                #print(self.pbl)
            #print(self.lines)
        for pb in self.pbl:
            if not ti.is_supported(pb):
                self.pl.append(pb)
        if len(self.musiclist)!=0:
            self.playing.set(self.musiclist[0])
        for x in self.pbl[1:]:
            if pa.Path(x).is_file():
                self.like.append(x)
                #print(x)
            else:
                break
        #print(self.like)
        style = ttk.Style()
        style.configure("BW.TLabel", foreground="blue", background="white", font=titlefont, anchor=W)
        style.configure("CL.TLabel", foreground="blue", background='gray', font=titlefont, anchor=W)
        style.configure("SM.TLabel", foreground="blue", background='white', font=('微软雅黑', 10, 'bold'), anchor=W)
        style.configure("SMCL.TLabel", foreground="blue", background='gray', font=('微软雅黑', 10, 'bold'), anchor=W)
        fmlt = ttk.Frame(self.master, height=1000, width=800)
        fmlt.pack(side=TOP, fill=BOTH, expand=YES, padx=10, pady=10, anchor=NW)
        fml = ttk.Frame(fmlt, height=100, width=100)
        fml.pack(side=LEFT, fill=NONE, expand=NO, padx=10, pady=10, anchor=NW)
        fmb = ttk.Frame(self.master, width=800)
        fmb.pack(side=BOTTOM, fill=X, expand=NO, anchor=S, padx=10, pady=10)
        fmr = ttk.Frame(fmlt, width=500)
        fmr.pack(side=RIGHT, fill=BOTH, expand=YES, anchor=W, padx=5, pady=5)

        fm1 = ttk.Labelframe(fml, text='Playlist setting')
        fm1.pack(side=TOP, fill=NONE, expand=YES, anchor=NW)
        fm1.bind('<Leave>', self.leave_lefttop)
        self.ap = ttk.Button(fm1, text='Add playlist', style='BW.TLabel', command=self.add_pl)
        self.ap.pack(side=TOP, fill=X, expand=YES)
        self.am = ttk.Button(fm1, text='All added mousic', style='BW.TLabel', command=self.all_music)
        self.am.pack(side=TOP, fill=X, expand=YES)
        self.fm2 = ttk.Labelframe(fml, text='Playlist list')
        self.fm2.pack(side=TOP, fill=BOTH, expand=YES, anchor=N, pady=10)
        self.fm3 = ttk.Labelframe(fmr, text='Music list')
        self.fm3.pack(side=BOTTOM, fill=BOTH, expand=YES)
        self.lb = Listbox(self.fm3, selectmode='browse', font=titlefont, foreground="green", background="white")#four mode
        self.lb.pack(side=LEFT, fill=BOTH, expand=YES)
        self.lb.bind('<Button-3>', self.pop)
        self.lb.bind('<Motion>', self.lb_focus)
        self.pb = Listbox(self.fm2, selectmode='browse', font=titlefont)
        self.pb.pack(side=LEFT, fill=BOTH, expand=YES)
        self.pb.bind('<Button-1>', self.artist_play)
        self.pb.bind('<Button-3>', self.pbpop)
        self.pb.bind('<Motion>', self.pb_focus)
        self.pb.bind('<Control-1>',self.ctrlpb)
        self.pb.bind('<ButtonRelease-3>',self.pbrel)
        self.ctrl=BooleanVar()
        self.ctrl.set(FALSE)
        self.popmenu = Menu(self.lb, tearoff=0)
        self.popmenu.add_cascade(label='play', command=self.play_it)
        self.popmenu.add_cascade(label='pause or play', command=self.pause)
        self.m = Menu(self.popmenu, tearoff=0)
        self.popmenu.add_cascade(label='add to playlist', menu=self.m)
        self.popmenu.add_cascade(label='delate', command=self.del_music)

        self.pbmenu = Menu(self.pb, tearoff=0)
        self.pbmenu.add_cascade(label='delate', command=self.del_list)
        self.pbmenu.add_cascade(label='rename', command=self.rename)
        self.pbmenu.add_cascade(label='add', command=self.add_pl)

        fm2 = ttk.Frame(fml)
        fm2.pack(side=BOTTOM, fill=BOTH, expand=YES, anchor=N, pady=10)
        ttk.Button(fm2, text='delate playlist', style='SM.TLabel', command=self.del_list).pack(side=LEFT, expand=NO,
                                                                                               padx=5,
                                                                                               anchor=SW)  # ddddeeettt
        ttk.Button(fm2, text='rename', style='SM.TLabel', command=self.rename).pack(side=LEFT, expand=NO,
                                                                                    padx=5, anchor=SW)
        self.sort=ttk.Button(fm2, text='sort by artist', style='SM.TLabel', command=self.artist)
        self.sort.pack(side=LEFT, expand=NO,padx=5, anchor=SW)
        self.artistnow = BooleanVar()
        self.artistnow.set(FALSE)
        scrollp = ttk.Scrollbar(self.fm2, command=self.pb.yview)
        scrollp.pack(side=RIGHT, fill=Y)
        self.pb.configure(yscrollcommand=scrollp.set)
        for x in self.pl:  # should create a txt to save musiclist !!
            self.pb.insert(END, x)
            self.m.add_command(label=x, command=self.testt(self.add_topl, x=x))
        # ttk.Button(fm2, text='All added mousic', style='BW.TLabel').pack(side=BOTTOM, fill=X, expand=YES)
        fm4 = ttk.Frame(fmr);
        fm4.pack(side=TOP, fill=NONE, expand=NO, anchor=W)
        self.sf = ttk.Button(fm4, text='Scan files', style='SM.TLabel', command=self.sff)
        self.sf.pack(side=LEFT, expand=YES, padx=5, anchor=W)
        self.af = ttk.Button(fm4, text='Add file path', style='SM.TLabel',command=self.aff)
        self.af.pack(side=LEFT, expand=YES, padx=5, anchor=W)
        self.ms = ttk.Button(fm4, text='Browse', style='SM.TLabel',command=self.modechange)
        self.ms.pack(side=LEFT, expand=YES, padx=5, anchor=W)
        self.strVar = StringVar()

        self.cb = ttk.Button(fm4, text=self.endsave[0][0:-1] , style='SM.TLabel', command=self.change_module)
        self.cb.pack(side=LEFT, expand=YES, fill=BOTH, padx=5, anchor=W)
        # Combobox(fm4,textvariable=self.strVar,values=['play in order','random play','loop play in list','loop play single song']), four play model to select
        if len(self.endsave)>1:
            for x in self.endsave[1:]:
                if 'mode' not in x and x!='\n':
                    self.playlist.append(x[0:-1])
                    self.lb.insert(END, pa.Path(x).stem)
                    #print(x)
        else:
            for x in self.musiclist:  # should create a txt to save musiclist !!
                self.lb.insert(END, pa.Path(x).stem)
                self.playlist.append(x)


        scroll = ttk.Scrollbar(self.fm3, command=self.lb.yview)
        scroll.pack(side=LEFT, fill=Y)
        self.lb.configure(yscrollcommand=scroll.set)
        self.lb.bind('<Double-1>', self.choose_play)
        self.cv = Canvas(fmb, background='white', height=40)
        self.cv.pack(fill=BOTH, expand=NO)
        self.cv.bind('<Button-1>', self.click)
        self.cv.bind('<ButtonRelease-1>', self.release)
        self.cv.create_line(97.5 - 5, 22.5 - 10, 97.5 - 5, 22.5 + 10, fill='red', width=4, tag='g1')  # playing
        self.cv.create_line(97.5 + 5, 22.5 - 10, 97.5 + 5, 22.5 + 10, fill='red', width=4, tag='g1')
        self.play_name = self.cv.create_text(220, 5, text=' ', font='simkai', fill='blue', anchor=W, justify=LEFT,
                                             tag='g3')  # play_name
        self.spand = self.cv.create_rectangle(260, 35, 260, 40, fill='green', tag='g3')
        self.cv.tag_lower('g3')

        self.cv.create_line(220, 5 + 2, 220, 35, arrow=FIRST, width=2, fill='red', tag='m2', arrowshap=(5, 10, 5))
        self.cv.create_line(220, 5, 250 - 2, 5, arrow=LAST, width=2, fill='red', tag='m2', arrowshap=(5, 10, 5))
        self.cv.create_line(250, 5, 250, 35 - 2, arrow=LAST, width=2, fill='red', tag='m2', arrowshap=(5, 10, 5))
        self.cv.create_line(250, 35, 220 + 2, 35, arrow=LAST, width=2, fill='red', tag='m2', arrowshap=(5, 10, 5))

        self.cv.create_line(220, 5, 220, 35, arrow=FIRST, width=2, fill='violet', tag='m3', arrowshap=(5, 10, 5))
        self.cv.create_line(220, 5, 250, 5, arrow=None, width=2, fill='violet', tag='m3', arrowshap=(5, 10, 5))
        self.cv.create_line(250, 5, 250, 35, arrow=None, width=2, fill='violet', tag='m3', arrowshap=(5, 10, 5))
        self.cv.create_line(250, 35, 220, 35, arrow=None, width=2, fill='violet', tag='m3', arrowshap=(5, 10, 5))
        self.cv.create_oval(235 - 10, 20 - 10, 235 + 10, 20 + 10, fill='yellow', outline='green', tag='m3')
        self.name=self.cv.create_text(235, 20, text=' ', width=2, fill='blue', tag='m3')

        self.cv.create_line(235 - 5, 20 + 5, 220, 35, arrow=LAST, width=2, fill='violet', tag='m4',
                            arrowshap=(5, 10, 5))
        self.cv.create_line(235 - 5, 20 - 5, 220, 5, arrow=LAST, width=2, fill='violet', tag='m4', arrowshap=(5, 10, 5))
        self.cv.create_line(235 + 5, 20 + 5, 250, 35, arrow=LAST, width=2, fill='violet', tag='m4',
                            arrowshap=(5, 10, 5))
        self.cv.create_line(235 + 5, 20 - 5, 250, 5, arrow=LAST, width=2, fill='violet', tag='m4', arrowshap=(5, 10, 5))

        self.cv.create_rectangle(0, 1, 200 - 5, 42, fill='yellow', width=0)
        self.cv.create_rectangle(200, 1, 260, 42, fill='white', width=0)
        self.cv.create_line(225, 5, 225, 35, arrow=LAST, width=2, fill='red', tag='m1', arrowshap=(5, 10, 5))
        self.cv.create_line(235, 5, 235, 35, arrow=LAST, width=2, fill='red', tag='m1', arrowshap=(5, 10, 5))
        self.cv.create_line(245, 5, 245, 35, arrow=LAST, width=2, fill='red', tag='m1', arrowshap=(5, 10, 5))

        self.cv.create_oval(20, 5, 60 - 5, 40, fill='pink', outline='green')
        self.cv.create_oval(80, 5, 120 - 5, 40, fill='pink', outline='green')
        self.cv.create_oval(140, 5, 180 - 5, 40, fill='pink', outline='green')
        self.cv.create_polygon(22.5, 22.5, 45, 22.5 - 7.5 * 3 ** 0.5, 45, 22.5 + 7.5 * 3 ** 0.5, fill='red')
        self.cv.create_polygon(172.5 - 60, 22.5, 150 - 60, 22.5 - 7.5 * 3 ** 0.5, 150 - 60, 22.5 + 7.5 * 3 ** 0.5,
                               fill='red', tag='g2')  # stop playing
        self.cv.create_polygon(172.5, 22.5, 150, 22.5 - 7.5 * 3 ** 0.5, 150, 22.5 + 7.5 * 3 ** 0.5,
                               fill='red')  # 190-22.5
        self.cv.create_rectangle(500,0,600,10,fill='orange')
        self.cv.create_text(470,6,text='Volume',fill='blue')
        self.vol=self.cv.create_rectangle(500,0,600,10,fill='green')
        self.to_like = self.cv.create_polygon(190, 30, 210, 30, 200, 0, fill='gray')
        self.to_like=self.cv.create_polygon(190,15,210,15,200,30,fill='gray')
        # 定时器需要
        self.pause = BooleanVar()
        self.pause.set(FALSE)
        self.press_3=BooleanVar()
        self.press_3.set(FALSE)#youjian
        self.save()
        self.func()  # check playing_if
        self.speed = 1
        self.long = DoubleVar()
        self.long.set(260.)
        self.control_play = BooleanVar()
        self.control_play.set(FALSE)
        self.change_module();self.change_module();self.change_module();self.change_module();self.change_module();
    def func(self):#实时更新
        if self.play_if.get() and mixer.music.get_busy():
            test = ti.get(self.playing.get())
            self.speed = 24 / float(test.duration)
            self.long.set(self.long.get() + self.speed)
            #self.name['text']=self.playing.get()
            self.cv.itemconfigure(self.name,text=self.playing.get())
            # print(str(self.long.get()))
            self.cv.coords(self.spand, 260, 33, float(self.long.get()), 42)
        elif self.play_if.get() and not mixer.music.get_busy() and not len(self.playlist) == 0:
            self.to_next()
            #print('to_next')
        elif not self.play_if.get() and not mixer.music.get_busy() and not len(self.playlist) == 0:
            self.playing.set(self.playlist[0])
            # print('start')
            # self.t.cancel()
        if len(self.playlist) == 0 and not mixer.music.get_busy():
            self.play_if.set(FALSE)
            self.cv.tag_raise('g2')
            self.cv.tag_lower('g1')
        if self.playing.get() in self.like:
            self.cv.itemconfigure(self.to_like,fill='red')
        else:
            self.cv.itemconfigure(self.to_like,fill='gray')
        t = Timer(0.1, self.func)
        t.setDaemon(TRUE)
        t.start()

    def to_next(self):
        if self.cb['text'] == 'mode 1':
            if self.playing.get() not in self.playlist:
                self.playing.set(self.playlist[0])
            elif self.playlist.index(self.playing.get()) == len(self.playlist) - 1:
                if not mixer.music.get_busy():
                    mixer.music.stop()
                    self.play_if.set(FALSE)  # notplaying
                    print('busy')
                    self.cv.tag_raise('g2')
                    self.cv.tag_lower('g1')
                else:
                    self.playing.set(self.playlist[0])
                    self.play_music(self.playing.get())
            elif self.play_if.get():
                self.playing.set(self.playlist[self.playlist.index(self.playing.get()) + 1])
                self.play_music(self.playing.get())
            else:
                self.play_music(self.playing.get())
               # print('??')
        elif self.cb['text'] == 'mode 2':
            if self.playlist.index(self.playing.get()) == len(self.playlist) - 1:
                self.playing.set(self.playlist[0])
                self.play_music(self.playing.get())
            else:
                self.playing.set(self.playlist[self.playlist.index(self.playing.get()) + 1])
                self.play_music(self.playing.get())
        elif self.cb['text'] == 'mode 3':
            if self.play_if.get() and not mixer.music.get_busy():
                self.play_music(self.playing.get())
            elif self.playlist.index(self.playing.get()) == len(self.playlist):
                self.playing.set(self.playlist[0])
                self.play_music(self.playing.get())
            else:
                self.playing.set(self.playlist[self.playlist.index(self.playing.get()) + 1])
                self.play_music(self.playing.get())
        elif self.cb['text'] == 'mode 4':
            self.playing.set(self.playlist[randint(0, len(self.playlist)) - 1])
            self.play_music(self.playing.get())
          #  print(self.playing.get())
       # print('ss')

    def to_before(self):
        if self.cb['text'] == 'mode 1':
            self.playing.set(self.playlist[self.playlist.index(self.playing.get()) - 1])
            self.play_music(self.playing.get())
        elif self.cb['text'] == 'mode 2':
            self.playing.set(self.playlist[self.playlist.index(self.playing.get()) - 1])
            self.play_music(self.playing.get())
        elif self.cb['text'] == 'mode 3':
            self.playing.set(self.playlist[self.playlist.index(self.playing.get()) - 1])
            self.play_music(self.playing.get())
        elif self.cb['text'] == 'mode 4':
            self.playing.set(self.playlist[randint(0, len(self.playlist)) - 1])
            self.play_music(self.playing.get())
        print('ss')

    def to_play(self):
        if self.cb['text'] == 'mode 4':
            self.playing.set(self.playlist[randint(0, len(self.playlist)) - 1])
            self.play_music(self.playing.get())
        else:
            self.play_music(self.playing.get())
        print('ss')

    def add_pl(self):
        if not self.artistnow.get():
            self.ap['style'] = 'CL.TLabel'
            self.am['style'] = 'BW.TLabel'
            print('no')
            name = simpledialog.askstring('Create a playlist', 'input the name of playlist:',
                                          initialvalue='New playlist')
            print(name)
            if name:
                i = 0
                strr = ''
                while name in self.pl:
                    for xx in range(len(name)):
                        if re.match(r'\d', name[len(name) - 1 - xx]):
                            strr += name[len(name) - 1 - xx]
                            name = name[0:len(name) - 1 - xx]
                    i += 1
                    name = name + str(i)
                self.pb.insert(END, name)
                self.m.add_command(label=name)
                self.pl.append(name)
                self.pbl.append(name)
                print(name)
            self.save()

    def all_music(self):
        self.am['style'] = 'CL.TLabel'
        self.ap['style'] = 'BW.TLabel'
        self.is_all.set(TRUE)
        if self.artistnow.get():
            self.artistnow.set(FALSE)
        self.pb.delete(0, END)
        for x in self.pl:  # should create a txt to save musiclist !!
            self.pb.insert(END, pa.Path(x).stem)
        self.lb.delete(0, END)
        self.playlist=[]
        for x in self.musiclist:  # should create a txt to save musiclist !!
            self.lb.insert(END, pa.Path(x).stem)
            self.playlist.append(x)

    def sff(self):
        self.sf['style'] = 'SMCL.TLabel'
        self.af['style'] = 'SM.TLabel'
        self.ms['style'] = 'SM.TLabel'
        test = sfs(self.master, self.lb, self.sf, self.musiclist, self.save, self.playlist)
    def aff(self):
        filepath=filedialog.askdirectory(title='choose file path',initialdir='F:/')
        stems = []
        # for format in ('.mp3','.flac'):\for x in p.glob('**/*'):
        for x in pa.Path(filepath).glob('**/*'):
            if ti.is_supported(str(x.name)):
                if (os.path.getsize(x)) > 1 * 1024 * 1024 and (
                        os.path.getsize(x)) < 50 * 1024 * 1024:
                    stems.append(x)

        test = mlf(self.master, stems, self.lb, self.musiclist, self.playlist)
    def save(self):
        self.endsave=['mode 3']
        self.endsave.extend(self.playlist)
        #print(self.endsave)
        self.lines = ['musiclist--> \n'] + self.musiclist + ['playlist--> \n'] + self.pbl + ['end--> \n']+self.endsave
        # print('save_test')
        # print(self.lines)
        with open(self.filename, 'w', True, 'UTF-8') as ff:
            for x in self.lines:
                if not '\n' in x.__str__():
                    ff.write(x.__str__() + '\n')
                    #print(x.__str__() + '\n')
                elif x !='\n':
                    ff.write(x.__str__())

    def choose_play(self, event):
        print(u"播放音乐1")
       # track = mixer.music.load(str(self.playlist[self.lb.curselection()[0]]))
        # print(track)
        self.play_music(self.playlist[self.lb.curselection()[0]])
        self.play_if.set(TRUE)

    #  'play in order', 'random play', 'loop play in list', 'loop play single song'
    def play_music(self, file):
        print(file)
        mixer.init()
        try:
            track = mixer.music.load(str(file))
        except:
            self.lb.delete(self.playlist.index((file)))
            self.musiclist.remove(file)
            track = mixer.music.load(str(self.playlist[(self.playlist.index(file)+1)%len(self.playlist)]))
            print(str(self.playlist[(self.playlist.index(file)+1)%len(self.playlist)]))
            self.playlist.remove(file)

        self.playing.set(str(file))
        self.play_if.set(TRUE)
        self.long.set(260.)
        mixer.music.play()
        self.lb.selection_clear(0, END)
        self.lb.selection_set(self.playlist.index(file))
        self.lb.see(self.playlist.index(file))
        test = ti.get(file)
        self.cv.tag_raise('g1')
        self.cv.tag_lower('g2')
        self.cv.delete('g3')
        self.play_name = self.cv.create_text(260, 20, text=pa.Path(file).name, font='simkai', fill='green',
                                             anchor=W, justify=LEFT, tag='g3')
        self.cv.create_text(510, 35, text=str(int(test.duration)) + ' s', font=('simkai', 10, 'bold'), fill='green',
                            anchor=W, justify=LEFT, tag='g3')
        self.cv.create_rectangle(260, 33, 500, 42, fill='blue', width=0, tag='g3')
        self.spand = self.cv.create_rectangle(260, 35, 260, 40, fill='yellow', tag='g3')

        self.cv.tag_raise('g3')

    def change_module(self):
        if self.cb['text'] == 'mode 1':
            self.cb['text'] = 'mode 2'
            self.cv.tag_raise('m2')
            self.cv.tag_lower('m1')
        elif self.cb['text'] == 'mode 2':
            self.cb['text'] = 'mode 3'
            self.cv.tag_raise('m3')
            self.cv.tag_lower('m2')
        elif self.cb['text'] == 'mode 3':
            self.cb['text'] = 'mode 4'
            self.cv.tag_raise('m4')
            self.cv.tag_lower('m3')
        elif self.cb['text'] == 'mode 4':
            self.cb['text'] = 'mode 1'
            self.cv.tag_raise('m1')
            self.cv.tag_lower('m4')

    def click(self, event):
        if event.x > 80 and event.x < 115 and mixer.music.get_busy() and not len(self.playlist) == 0:
            if self.pause.get():
                print('??')
                self.pause.set(FALSE)
                mixer.music.unpause()
                self.play_if.set(TRUE)
                self.cv.tag_raise('g1')
                self.cv.tag_lower('g2')
            else:
                mixer.music.pause()
                self.play_if.set(FALSE)
                print('busy')
                self.cv.tag_raise('g2')
                self.cv.tag_lower('g1')
                self.pause.set(TRUE)
        if event.x > 80 and event.x < 115 and not mixer.music.get_busy() and not len(self.playlist) == 0:
            print('stt')
            self.to_play()
        elif event.x > 140 and event.x < 175 and not len(self.playlist) == 0:
            self.to_next()
        elif event.x > 20 and event.x < 55 and not len(self.playlist) == 0:
            self.to_before()
        elif event.x > 260 and event.x < 500 and event.y > 30 and self.play_if.get():
            self.control_play.set(TRUE)
        elif event.x > 220 and event.x < 250:
            self.change_module()
        elif event.x>500 and event.x<600 and event.y<11:
            mixer.music.set_volume((event.x-500)/100)
            self.cv.coords(self.vol,500,0,event.x,10)
        elif event.x>190 and event.x<210 and event.y>15 and event.y<30:

            if self.playing.get() not in self.like:
                self.like.append(self.playing.get())
                self.pbl.insert(1,self.playing.get())
                self.cv.itemconfigure(self.to_like, fill='red')
            else:
                self.like.remove(self.playing.get())
                self.pbl.remove(self.playing.get())
                self.cv.itemconfigure(self.to_like, fill='gray')
    def release(self, event):
        print('release')
        if event.x > 260 and event.x < 500 and event.y > 30 and self.control_play.get() and mixer.music.get_busy():
            test = ti.get(self.playing.get())
            self.long.set(event.x)
            mixer.music.rewind()
            mixer.music.play(start=(event.x - 260.) / 240. * float(test.duration))
            print('??')
            self.pause.set(FALSE)
            # mixer.music.unpause()
            self.play_if.set(TRUE)
            self.cv.tag_raise('g1')
            self.cv.tag_lower('g2')
        elif event.x>500 and event.x<600 and event.y<11:
            mixer.music.set_volume((event.x-500)/100)
            self.cv.coords(self.vol,500,0,event.x,10)
            print(mixer.music.get_volume())
        # pygame.mixer.music.pause() #暂停
        # pygame.mixer.music.unpause()#取消暂停

    def del_list(self):
        if not len(self.pb.curselection()) == 0 and (not self.pb.curselection()[0] == 0) and not self.artistnow.get():
            #print(str(self.pb.curselection()))
            self.m.delete(self.pb.curselection()[0]), (self.pb.curselection()[0])

            print(self.pl)
            for xxx in self.pb.curselection():
                i = 0
                for xx in self.pbl[self.pbl.index(self.pl[xxx]):]:
                    if ti.is_supported(xx) or i == 0:
                        self.pbl.remove(xx)
                        i= 1
                    else:
                        break
                self.pl.pop(xxx)
                self.pb.delete(xxx)
            self.save()
        elif not len(self.pb.curselection()) == 0 and self.sort['text']=='sort by filepath':
            ss=self.pb.curselection()
            sel,pl,plist=[],[],[]
            for x in ss:
                print(len(self.filepathlist))
                sel.append(self.filepathlist[x])
            self.pb.delete(0,END)
            self.lb.delete(0,END)
            for xxx in sel:
                self.filepathlist.remove(xxx)
            print(self.filepathlist)
            for xx in self.musiclist:
                    if pa.Path(xx).parent in self.filepathlist:
                        pl.append(xx)
                        print(xx)
                        if xx in self.playlist:
                            self.lb.insert(END,pa.Path(xx).stem)
                            plist.append(xx)
            self.musiclist=pl.copy()
            self.playlist=plist.copy()
           # print(self.musiclist)
            for x in self.filepathlist:
                self.pb.insert(END,x)
        for x in self.pbl[1:]:
            if pa.Path(x).is_file():
                self.like.append(x)
            else:
                break
        self.save()
    def rename(self):
        if not len(self.pb.curselection()) == 0 and (not self.pb.curselection()[0] == 0) and not self.artistnow.get():
            num = int(str(self.pb.curselection())[1:-2])
            test = simpledialog.askstring('Rename the playlist', 'input a name:',
                                          initialvalue=str(self.pl[int(str(self.pb.curselection())[1:-2])]))
            if test:
                print(num)
                self.pb.delete(num)
                self.pb.insert(num, test)
                self.m.delete(num, num)
                self.m.insert_command(num, label=test, command=self.testt(self.add_topl, x=test))
                self.pbl[self.pbl.index(self.pl[num])] = test
                self.pl[num] = test

    def artist(self):
        if self.artistnow.get() and self.sort['text']=='sort by filepath':
            self.pb['selectmode']='browse'
            self.ctrl.set(FALSE)
            print('sss')
            self.press_3.set(FALSE)
            self.sort['text']='sort by artist'
            self.artistnow.set(FALSE)
            self.pb.delete(0, END)
            for x in self.pl:  # should create a txt to save musiclist !!
                self.pb.insert(END, pa.Path(x).stem)
        elif self.artistnow.get() and self.sort['text']=='sort by artist':
            self.sort['text']='sort by filepath'
            self.pb.delete(0, END)
            self.filepathlist=[]
            for x in self.musiclist:
                if pa.Path(x).parent not in self.filepathlist:
                    self.filepathlist.append(pa.Path(x).parent)
            self.all_path=[pa.Path(x).parent for x in self.musiclist]
            print(self.all_path)
            print(self.filepathlist)
            ind=[self.all_path.count(x) for x in self.filepathlist]
            inds=ind.copy()
            self.pathcopy=self.filepathlist.copy()
            inds.sort(reverse=TRUE)
            nosame=[]
            #print(ind)
            for x in inds:
                if x not in nosame:
                    nosame.append(x)
            i=0
            for x in nosame:
                ax=ind.index(x)
                for a in range(inds.count(x)):
                    self.filepathlist[i]=self.pathcopy[ind.index(x,ax)]
                    if not a ==inds.count(x)-1:
                        ax=ind.index(x,ax+1)
                    i+=1
            for x in self.filepathlist:
                self.pb.insert(END, str(x)+ '  (' + str(inds[self.filepathlist.index(x)]) + ')')

        else :
            self.artistnow.set(TRUE)
            self.pb.delete(0, END)
            self.artistlist, allartistlist = [], []
            for x in self.musiclist:
                #print(x)
                try:
                    tag = ti.get(x)
                    allartistlist.append(tag.artist)
                    if tag.artist not in self.artistlist:
                        self.artistlist.append(tag.artist)
                except:
                    if x in self.playlist:
                        self.lb.delete(self.playlist.index((x)))
                        self.playlist.remove(x)
                    self.musiclist.remove(x)
                    #print(x)
                    self.save()
            ind = [allartistlist.count(xx) for xx in self.artistlist]
            inds = ind.copy()  # 这里有点绕,利用指标辅助帮助艺术家根据歌曲数目排序,不简单
            inds.sort(reverse=True)
            artistlistsort = self.artistlist.copy()
            for x in artistlistsort:
                self.artistlist[artistlistsort.index(x)] = '0'
            for art in artistlistsort:
                i = inds.index(ind[artistlistsort.index(art)])
                while True:
                    if self.artistlist[i] == '0':
                        self.artistlist[i] = art
                        break
                    else:
                        i += 1
            for x in self.artistlist:  # should create a txt to save musiclist !!
                # print(x)
                if not x:
                    self.pb.insert(END, 'Unkonw' + ' (' + str(inds[self.artistlist.index(x)]) + ') ')
                else:
                    self.pb.insert(END, x + '  (' + str(inds[self.artistlist.index(x)]) + ')')

    def artist_play(self, event):  # 事件响应一定要记得加event!!!!!
        if self.artistnow.get() and not str(self.pb.curselection()) == '()' and self.sort['text']=='sort by artist':
            # print(str(self.pb.curselection()))
            x = self.pb.curselection()[0]
            self.lb.delete(0, END)
            self.playlist.clear()
            # print(self.artistlist[x])
            for xx in self.musiclist:
                try:
                    tag = ti.get(xx)
                    if tag.artist:
                        # print(tag.artist)
                        if tag.artist == self.artistlist[x]:
                            self.lb.insert(END, pa.Path(xx).stem)
                            self.playlist.append(xx)
                    elif not self.artistlist[x]:
                        self.lb.insert(END, pa.Path(xx).stem)
                        self.playlist.append(xx)
                except:
                    self.lb.delete(self.playlist.index((xx)))
                    self.musiclist.remove(xx)
                    self.playlist.remove(xx)
                    #print(xx)
                    self.save()
        elif self.artistnow.get() and not str(self.pb.curselection()) == '()' and self.sort['text']=='sort by filepath':
            x = self.pb.curselection()[0]
            self.is_all.set(TRUE)
            self.lb.delete(0, END)
            self.playlist.clear()
            for xx in self.musiclist:
                if pa.Path(xx).parent==self.filepathlist[x]:
                    self.lb.insert(END, pa.Path(xx).stem)
                    self.playlist.append(xx)


        elif not str(self.pb.curselection()) == '()':
            x = self.pb.curselection()[0]
            self.lb.delete(0, END)
            self.playlist.clear()
            self.playlist = []
            self.is_all.set(FALSE)
            self.playinglist.set(self.pl[x])
            for xx in self.pbl[self.pbl.index(self.pl[x]) + 1:]:
                if ti.is_supported(pa.Path(xx).name):
                    self.lb.insert(END, pa.Path(xx).stem)
                    self.playlist.append(xx)
                else:
                    break

    def pop(self, event):
        self.popmenu.post(event.x_root, event.y_root)

    def pbpop(self, event):
        self.pbmenu.post(event.x_root, event.y_root)
        self.press_3.set(TRUE)
    def pbrel(self,event):
        self.press_3.set(FALSE)
        print('xxxx')
    def play_it(self):
        print(self.lb.curselection())
        if str(self.lb.curselection()) == '()':
            print('ddd')
            self.to_play()
        else:
            self.play_music(self.playlist[self.lb.curselection()[0]])
            self.play_if.set(TRUE)

    def pause(self):
        if self.pause.get():
            print('??')
            self.pause.set(FALSE)
            mixer.music.unpause()
            self.play_if.set(TRUE)
            self.cv.tag_raise('g1')
            self.cv.tag_lower('g2')
        else:
            mixer.music.pause()
            self.play_if.set(FALSE)
            print('busy')
            self.cv.tag_raise('g2')
            self.cv.tag_lower('g1')
            self.pause.set(TRUE)

    def add_topl(self, x):
        # print(str(self.lb.curselection())[1:-2])
        # print(self.lb.curselection()[0])
        #print(self.playlist)
        if not str(self.lb.curselection()) == '()':
            for ax in self.lb.curselection():
                # print(self.pbl.index(x))
                if x == self.pl[-1] and self.playlist[ax] not in self.pbl[int(self.pbl.index(x)):]:
                    self.pbl.insert(int(self.pbl.index(x)) + 1, self.playlist[ax])
                    #print(self.pbl)
                    self.save()
                elif x == self.pl[-1]:
                    pass
                elif self.playlist[ax] not in self.pbl[int(self.pbl.index(x)):int(self.pbl.index(self.pl[self.pl.index(x) + 1]))]:
                    self.pbl.insert(int(self.pbl.index(x)) + 1, self.playlist[ax])
                    #print(self.pbl)
                    self.save()
        for x in self.pbl[1:]:
            if pa.Path(x).is_absolute():
                self.like.append(x)
            else:
                break



    def testt(self, fun, **kwds):
        # print('xx')
        return lambda fun=fun, kwds=kwds: fun(**kwds)

    def leave_lefttop(self, event):
        self.am['style'] = 'BW.TLabel'
        self.ap['style'] = 'BW.TLabel'

    def del_music(self):
        print('de l')
        if not len(self.lb.curselection()) == 0 and self.is_all.get():
            self.musiclist.remove(self.playlist[self.lb.curselection()[0]])
            self.playlist.pop(self.lb.curselection()[0])
            self.lb.delete(self.lb.curselection()[0])
            print('del')
        elif not len(self.lb.curselection()) == 0:
            print(self.playinglist.get())
            for ax in self.lb.curselection():
                if ax<len(self.playlist):
                    print(len(self.playlist))
                    print(ax)
                    m = self.playlist.pop(ax)
                    print(m)
                    self.lb.delete(ax)
                    x = self.pbl.index(self.playinglist.get())
                    print(x)
                    if x == len(self.pl) - 1:
                        if m in self.pbl[x:]:
                            print(self.pbl.pop(self.pbl.index(m, x)))
                    else:
                        y = self.pbl.index(self.pl[self.pl.index(self.playinglist.get()) + 1])
                        print(self.pbl.pop(self.pbl.index(m, x, y)))



    def lb_focus(self, event):
        if self.ms['text']=='Browse' or self.ms['text']=='Single':
            self.lb.selection_clear(0,END)
            self.lb.selection_set(self.lb.nearest(event.y))
    def pb_focus(self, event):
        if not self.press_3.get():
            if not self.ctrl.get():
                self.pb.selection_clear(0, END)
            self.pb.selection_set(self.pb.nearest(event.y))
            #print(self.pb.curselection())


    def modechange(self):
        if self.ms['text']=='Browse':
            self.ms['text']='Single'
            self.lb['selectmode']='single'
        elif self.ms['text']=='Single':
            self.ms['text']='Multiple'
            self.lb['selectmode'] = 'multiple'
        elif self.ms['text']=='Multiple':
            self.ms['text']='Extended'
            self.lb['selectmode'] = 'extended'
        elif self.ms['text']=='Extended':
            self.ms['text']='Browse'
            self.lb['selectmode'] = 'browse'
    def ctrlpb(self,event):
        if self.ctrl.get() and self.sort['text']=='sort by filepath':
            self.ctrl.set(FALSE)
        elif self.sort['text']=='sort by filepath' :
            self.ctrl.set(TRUE)
            #print('ttt')
        print(self.ctrl.get())
root = Tk()
root.title('Music')
test = App(root)
if not root.mainloop():
    mixer.music.stop()
    test.save()
    # root.quit()

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值