Python Tkinter 學習成果:點歌軟件music


筆者工作業余時間也沒什么愛好,社交圈子也小,主要娛樂就是背着自己帶電瓶的賣唱音響到住地附近找個人多的位置唱唱KtV。

硬件上點歌就用筆記本電腦,歌曲都是網上下載的mkv格式的含有兩個音軌的視頻。因此點歌軟件成了筆者的需求。

點歌軟件需求極簡單:

  • 讀磁盤上的目錄取全部music,雙擊則調用播放器播放music。
  • 自己常唱的歌曲可以選到自選歌曲列表。
  • 支持按簡拼搜索music

之前已經用多種開發工具寫過,這次逢學習python的機會用它再寫一個python版。

 

軟件界面如下:

 

 雙擊啟動播放器。

 

就代碼量上和用筆者用C#寫的相同功能的軟件對比下:

C#版軟件提供的功能與本例子是完全相同。工作邏輯代碼約230行,設計器代碼(界面代碼,系統自動生成)約210行,還不算漢字轉拼音類的代碼。

python版界面加工作邏輯代碼一起約150行。也因此,筆者在編寫python版的music時,明顯感覺到python的代碼精練濃縮(何況筆者只是初學python幾天)。

 

c#版的相同功能的軟件

 

 

 完整的代碼如下(python3.6.1環境下開發):

  1 from tkinter import *
  2 import tkinter.messagebox as messagebox
  3 from xpinyin import Pinyin
  4 import os
  5 import win32api
  6 import win32con
  7 
  8 class music():
  9     __musicPlayPath='D:\\Program Files (x86)\\SPlayer\\splayer.exe'
 10     __userMusicDiskFilePath='D:\\usermusic.txt'
 11     __musicDefaultList=[]
 12     musicCurList=[]
 13     __userSelMusicList=[]
 14     def __init__(self,musicPath):
 15         self.__musicPath=musicPath
 16 
 17     def delUserMusicListItem(self,item):
 18         if item in music.__userSelMusicList:
 19             music.__userSelMusicList.remove(item)
 20             messagebox.showinfo('提示','刪除成功!')
 21 
 22     def addUserMusicListItem(self,item):
 23         if not(item in music.__userSelMusicList):
 24             music.__userSelMusicList.append(item)
 25 
 26     def readUserMuslicList(self):
 27         return  music.__userSelMusicList
 28 
 29     def getSerachList(self):
 30         return  music.musicCurList
 31 
 32     def setDefaultMuslic(self):
 33         music.__musicDefaultList = self.readMusicFromDisk()
 34 
 35     def readDefaultMuslic(self):
 36         return music.__musicDefaultList
 37 
 38     def getMusicListByUserKey(self,searchTxt):
 39         print(searchTxt)
 40         if str(searchTxt).__len__()<1:
 41             music.musicCurList=music.__musicDefaultList[:]
 42             return
 43         music.musicCurList.clear()
 44         p = Pinyin()
 45         for m in music.__musicDefaultList:
 46             py = p.get_initials(m, '')
 47             if (py.upper()).find(searchTxt.upper())>=0:
 48                 music.musicCurList.append(m)
 49 
 50     def saveUserMusicListToDisk(self):
 51         f=open(music.__userMusicDiskFilePath,'w')
 52         tmpAry=music.__userSelMusicList[:]
 53         def addReturn(x):
 54             return x+'\n'
 55         f.writelines(map(addReturn, tmpAry))
 56         f.close()
 57 
 58     def loadUserMusicListFromDisk(self):
 59         self.ifNotFileExistCreateEmptyFile()
 60         f=open(music.__userMusicDiskFilePath,'r')
 61         music.__userSelMusicList.clear()
 62         tmpAry=f.readlines()
 63         def delReturn(x):
 64             return x[0:len(x)-1]
 65         music.__userSelMusicList=list(map(delReturn, tmpAry))
 66         f.close()
 67 
 68     def ifNotFileExistCreateEmptyFile(self):
 69         if not(os.path.exists(music.__userMusicDiskFilePath)):
 70             f = open(music.__userMusicDiskFilePath, 'a')
 71             f.close()
 72 
 73     def readMusicFromDisk(self):
 74         music.__musicDefaultList= [d for d in os.listdir(self.__musicPath) if d.upper().find(".MKV")>=0]
 75         return  music.__musicDefaultList
 76 
 77     def playMusic(self,event):
 78         w = event.widget
 79         index = int(w.curselection()[0])
 80         value = w.get(index)
 81         win32api.ShellExecute(0, 'open', music.__musicPlayPath,
 82                               '\"'+ self.__musicPath+value+'\"', '', 1)
 83 
 84 class gui(music):
 85 
 86     def __init__(self,winName):
 87         self.winName=winName
 88         self._music__musicPath='D:\\KuGou\\'
 89         self.lbx = StringVar()
 90 
 91     def addMusicToUserList(self):
 92         index = int(self.listbox1.curselection()[0])
 93         value = self.listbox1.get(index)
 94         print(value)
 95         self.addUserMusicListItem(value)
 96         self.saveUserMusicListToDisk()
 97         messagebox.showinfo('成功','已經添加歌曲 \"'+value+'\"!')
 98 
 99     def UpdateUserMusicList(self):
100         self.lbx.set(self.readUserMuslicList())
101 
102     def searchMusic(self,event):
103         w = event.widget
104         txt = w.get()
105         self.getMusicListByUserKey(txt)
106         self.lbx.set(self.getSerachList())
107 
108     def delUserMusic(self):
109         index = int(self.listbox1.curselection()[0])
110         value = self.listbox1.get(index)
111         self.delUserMusicListItem(value)
112         self.lbx.set(self.readUserMuslicList())
113         self.saveUserMusicListToDisk()
114 
115     def allmusic(self):
116         self.lbx.set(self.readDefaultMuslic())
117 
118     def initForm(self):
119         self.winName.title("music v1.0 by 劉小勇")
120         self.winName.geometry('600x480+10+10')
121         self.winName['bg']="pink"
122         self.winName.resizable(width=False,height=False)
123 
124         self.btn1=Button(self.winName,text='全部歌曲',bg='lightblue',command=self.allmusic)
125         self.btn1.grid(row=1,column=1)
126         self.btn2=Button(self.winName,text='選中的歌曲',bg='lightblue',command=self.UpdateUserMusicList)
127         self.btn2.grid(row=1,column=2)
128         self.btn3=Button(self.winName,text='添加到選中的歌曲',bg='lightyellow',command=self.addMusicToUserList)
129         self.btn3.grid(row=1,column=3)
130         self.btn4=Button(self.winName,text='刪除歌曲',bg='lightyellow',command=self.delUserMusic)
131         self.btn4.grid(row=1,column=4)
132 
133         self.lab1=Label(self.winName,text='搜索:')
134         self.lab1.grid(row=1,column=5)
135         self.txt1=Entry(self.winName, width=20)
136         self.txt1.bind('<Return>',self.searchMusic)
137         self.txt1.grid(row=1,column=6)
138 
139         self.scrollbar = Scrollbar()
140         self.scrollbar.grid(row=2,column=13,rowspan=13,sticky='NS')
141         self.listbox1=Listbox(self.winName,listvariable=self.lbx,width = 82,height=25,yscrollcommand=self.scrollbar.set)
142         self.setDefaultMuslic();
143         self.lbx.set(self.readDefaultMuslic())
144         self.listbox1.bind('<Double-Button-1>',self.playMusic)
145         self.listbox1.grid(row=2,column=1,columnspan=12)
146         self.scrollbar.config(command=self.listbox1.yview)
147         self.loadUserMusicListFromDisk()
148 
149 
150 tk=Tk()
151 form=gui(tk)
152 form.initForm()
153 tk.mainloop()

 

 在編碼過程中研究過的一些知識點匯集如下:

1.  如何在搜索框觸發搜索后更新listbox, 這個是利用tkinter的 StringVar()

  參考筆者貼子:Python tkinter 控件更新信息

2.  控件listbox的滾動條

  參考筆者貼子:python tkinter Listbox用法

3. 控件的事件綁定

  參考筆者貼子:python tkinter教程-事件綁定

4. 控件的布局

  參考筆者貼子:python tkinter學習——布局

5. 高階函數

  參考筆者貼子:python 函數式編程:高階函數,map/reduce

6. 漢字轉拼音

  參考筆者貼子:Python漢字轉換成拼音

7. win32模塊

  參考筆者貼子:Python中四種運行其他程序的方式

 

筆者寫python程序時的開發ide集成環境是pycharm,在寫tkinter代碼時,關於控件的屬性沒有什么有意義的提示。因為去記住控件屬性的完整拼寫是不容易也是沒有意義的事。

這也是寫界面代碼比較麻煩的地方。

長期依賴visual studio c#的IDE強大的語法提示、拼寫補全功能, 已經讓筆者手工編碼的能力高度退化,對於沒有屬性提示的編程環境已經無法想像。

 

 原創文章,出處 : http://www.cnblogs.com/hackpig/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM