如何用python GUI(tkinter)寫一個鬧鈴小程序(思路詳解)

事情的起因是幫助一個朋友寫一個程序,來控制他們單位的鈴聲,平時竟然是手動打鈴(闊怕)

事情的第一步:理清思路。需要用到python的幾個知識:1、tkinter一些函數控件,2、控件和函數之間的聯系(主用TreeView控件),3、讀寫數據入txt文檔(高級版可換為數據庫),4、數據的類的封裝。

需要其他方面的知識:1、簡單設計界面佈局,2、確保程序易於使用的不反人類細節。

考慮清楚後,那麼我開始學習一下相關知識。

(1)python中作為面向對象的一份子,Class(類)和Instance(實例)的兩個概念必須要清楚,

class Student(object):
    pass

class後面緊接著是類名,Student,緊接著是(object),表示該類是從哪個類繼承下來的,如果沒有合適的繼承類,就使用object類,這是所有類最終都會繼承的類。

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score

註意到__init__方法的第一個參數永遠是self,表示創建的實例本身,因此,在__init__方法內部,就可以把各種屬性綁定到self,因為self就指向創建的實例本身。
有瞭__init__方法,在創建實例的時候,就不能傳入空的參數瞭,必須傳入與__init__方法匹配的參數,但self不需要傳,Python解釋器自己會把實例變量傳進去:
eg:  Tom = Student(‘Bart Simpson’, 59)
要定義一個方法,除瞭第一個參數是self外,其他和普通函數一樣。要調用一個方法,隻需要在實例變量上直接調用,除瞭self不用傳遞,其他參數正常傳入。
PS:看瞭網上幾個教程,有的class類出現不同的寫法:
class App:   class App():   class App(Frame):
需要特別說明的是,不帶()與帶()效果一樣,而Class A(B):是繼承關系,A繼承瞭B。
(2)tkinter中ttk中的Treeview控件,

ttk.Treeview(self.frame_center, show="headings", height=18, columns=("a", "b", "c", "d", "e"))

show=”heading”表示第一行是隱藏的,show=”tree”表示顯示第一行。

其實項目沒什麼難度,貼上源代碼:

# coding=utf-8
import tkinter
from tkinter import ttk
import os,sys
import time
from playsound import playsound
import threading
import winsound
class Application():
    def __init__(self,master):
        self.master=master  #master就是Tk(),也就是windows
        self.num01=0  # 用於兩個button狀態切換
        self.run01=1    # 用於 啟動和停止 狀態切換,1為啟動
        self.datatxt = "日常模式_保存配置.txt"    #用於 儲存生成txt文件
    def creatThings(self):
        self.myStr01 = tkinter.StringVar()     #如果想讓該變量成為整個Class的全局變量,則必須加self
        self.myStr01.set('正在運行')
        self.myVar01 = tkinter.IntVar()
        self.buttonA1=tkinter.Button(self.master,text="日常",bg='#D1EEEE',width=20,command=self.buttonA1_Func)
        self.buttonB2=tkinter.Button(self.master,text="特殊",bg='#D1EEEE',width=20,command=self.buttonB2_Func)
        self.buttonA1.pack()
        self.buttonB2.pack()
        self.label_status=tkinter.Label(self.master,text="當前狀態",background="#ffffe0",width=20)
        self.label_status.pack()
        self.label_st2=tkinter.Label(self.master,bg='green', fg='yellow', font=('Arial', 12), width=10, textvariable=self.myStr01)
        self.label_st2.pack()
        self.radioButtonA1=tkinter.Radiobutton(self.master,text="啟動",variable=self.myStr01,value='啟動',command=self.Change_SelectionA)
        # 其中variable=self.myStr01, value='啟動'的意思就是,當我們鼠標選中瞭其中一個選項,把value的值'啟動'放到變量self.myStr01中,然後賦值給variable
        self.radioButtonB2 = tkinter.Radiobutton(self.master, text="停止",variable=self.myStr01,value='停止',command=self.Change_SelectionB)
        self.radioButtonA1.pack()
        self.radioButtonB2.pack()
        self.buttonC3 = tkinter.Button(self.master, text="保存當前配置",width=15,height=2,command=self.Set2Txt)#
        self.buttonC3.pack()
        self.buttonD4 = tkinter.Button(self.master, text="新建事件",width=15,height=2,command=self.New_Building)
        self.buttonD4.pack()
    def creatTree(self):
        treecol=["序號","時間","事件","鈴聲"]
        global tree
        tree=self.tree=ttk.Treeview(self.master,columns=treecol, height=10, show="headings")
        tree.column('0', width=50, anchor='center')  # 指定第一列的寬度和名稱, 如果show = "headings", 這一列就被隱藏。
        tree.column('1', width=150, anchor='center')    #表示列,headings時不顯示
        tree.column('2', width=150, anchor='center')
        tree.column('3', width=350, anchor='center')
        tree.heading('0', text='序號')
        tree.heading('1', text='時間')
        tree.heading('2', text='事件')
        tree.heading('3', text='鈴聲')
        self.data = {"item0": ["1", "06:20", "起床", "起床號.mp3"],"item1": ["2", "06:30", "早操", "早操號.mp3"]}
        tree.insert('', 'end', values=self.data["item0"])
        tree.insert('', 'end', values=self.data["item1"])   #這裡,使用字典不適合,無序
        self.newdata = {"num01": ["", "", "", ""]}
        tree.pack()     #這一行是必須的
        tree.bind('<ButtonRelease-1>', self.Tree_Selection)
        print("階段執行檢測")
    def Gui_arrange(self):
        self.buttonA1.place(x=100, y=20)
        self.buttonB2.place(x=300, y=20)
        self.tree.place(x=50,y=100)
        self.label_status.place(x=950,y=80)
        self.label_st2.place(x=980,y=105)
        self.radioButtonA1.place(x=950,y=150)
        self.radioButtonB2.place(x=1050, y=150)
        self.buttonC3.place(x=1000,y=500)
        self.buttonD4.place(x=600,y=500)
    #各種點擊函數集合:
    def Change_SelectionA(self): #用於點選框變更
        self.label_st2.config(text=self.myStr01.get())
        self.run01=1
    def Change_SelectionB(self):  # 用於點選框變更
        self.label_st2.config(text=self.myStr01.get())
        self.run01=0
    def WriteToTree(self):  #未完成
        #清空newdata中原始數據
        for item in self.tree.get_children():
            self.tree.delete(item)
        f2=open(os.getcwd()+r"\\"+self.datatxt,'r')     #讀數據文件datatxt
        cont2=f2.readlines()
        #self.newdata = {"num01": ["", "", "", ""]}  #當然上面這個不行
        self.newdata = cont2
        for i in range(len(self.newdata)):
            '''
            for j in range(len(cont2[0])):  # 取數組中一個元素的最大長度
                self.newdata[i][j].replace('\'','')
            '''
            a=self.newdata[i]
            b=a.replace('\'','')    # b是字符串
            c=b.split(',')          # c變為瞭數組
self.tree.insert('',i,values=c)        
#self.tree.update() 該行好像沒起什麼作用
# self.tree.insert('','end',values=["1", "06:20", "起床", "起床號2.mp3"])
def New_Building(self):        
self.tree.insert('','end',values=["1", "06:20", "起床", "起床號2.mp3"])    
def Tree_Selection(self,event):  #這裡的event和前面的self是同一個東東, 如果單一參數的話會報錯
for item2 in tree.selection():           item_text=tree.item(item2
,"values")  #item是I001、I002
print(item_text[1:3])           
print(item_text)        
#item1 = tree.selection()[0]
        #print(item1)
        column = tree.identify_column(event.x)  #列column
row=tree.identify_row(event.y)  #行row
print("正確的column是"+column)        
print("the items has been selected = ",tree.selection())        entryedit=tkinter.Text(
self.master,width=40,height=2)        entryedit.place(
x=90,y=60)        
def save_edit():            
print("==== = ", tree.selection())            tree.set(item2
,column=column,value=entryedit.get(0.0,"end").replace('\n',''))            
# 官方手冊解釋 set the value of given column in given item to the specified value.
            entryedit.destroy()            Obutton.destroy()        Obutton=tkinter.Button(
self.master,text="更 改",bg="gray",width=4,command=save_edit)        Obutton.place(
x=390,y=60)    
def Set2Txt(self):        
print("num01:",self.num01)        
if self.num01==0:            file01=
open(currentDir+'\\日常模式_保存配置.txt','w')            
for i in range(21):  # 寫入數據
#問題是如何輸出當前表格數的最大行數,以後再說
try:                    item_text = tree.item(
"I00"+str(i+1), "values") #這是針對列表寫的
                    file01.write(str(item_text).replace("(", "").replace(")", "") + '\n') #這是針對列表寫的
except:                    
#file01.write(str(item_text).replace("(","").replace(")","")+'\n')
pass
            file01.close()        
elif self.num01==1:            file02=
open(currentDir+'\\休息模式_保存配置.txt','w')            
for i in range(21):  # 寫入數據
#問題是如何輸出當前表格數的最大行數,以後再說
try:                    item_text = tree.item(
"I00"+str(i+1), "values")                    file02.write(
str(item_text).replace("(", "").replace(")", "") + '\n')                
except:                    
pass
            file02.close()    
def buttonA1_Func(self):        
self.num01 = 0
self.buttonA1['bg']='#71C671'
self.buttonB2['bg'] = '#D1EEEE'
print("效果生成 =0")        
self.datatxt="日常模式_保存配置.txt"
self.WriteToTree()        
#導入日常模式—數據
pass
    def buttonB2_Func(self):        
self.num01 = 1
self.buttonB2['bg']='#71C671'
self.buttonA1['bg'] = '#D1EEEE'
print("效果生成 =1")        
self.datatxt = "休息模式_保存配置.txt"
self.WriteToTree()        
# 導入休息模式—數據
pass
    def Test(self):        
print("純測試")    
def Belling(self):        
self.num01 = 0  #日常模式0 休息模式1
        #currentDir = os.getcwd()
while True & self.run01==1:            
if self.num01 == 0:                
self.datatxt = "日常模式_保存配置.txt"
elif self.num01 == 1:                
self.datatxt = "休息模式_保存配置.txt"
            f1 = open(os.getcwd() + r"\\" + self.datatxt, 'r')            contect = f1.readlines()  
# contect = []
            # print(contect)
            f1.close()            t = time.localtime()            now = time.strftime(
"%H %M", t).split()            
for i in contect:                
print(i)                
print("鬧鈴監測正在運行中...")                a = i.split(
',')                
#print(a[1])  # 時間 06:20
                #print(a[3])  # 鈴聲 起床號.mp3
                h = a[1].replace('\'','').replace(' ','').split(':')                
a2=h                a3=a[
3].replace('\'','').replace('\n','').replace(' ','')                
a4=(currentDir+'\\'+a3)                
if h[0] == now[0] and h[1] == now[1]:                    
print("時間到!")                    
#playsound(r'C:\Users\Jesse Eisenberg\PycharmProjects\Zidonghua\ZidonghuaExcel\一個鬧鈴.mp3')
                    #playsound(a4)
                    #playsound(currentDir + '\\' + a[3])
                    #采用playsound會報線程錯誤
                    a4='C:\\Users\\Jesse Eisenberg\\PycharmProjects\\Zidonghua\\ZidonghuaExcel\\一個鬧鈴.wav'
                    winsound.PlaySound(a4, winsound.SND_FILENAME)                    time.sleep(
56)                
else:                    
#time.sleep(0.5)
continue
def mainpro():    windows = tkinter.Tk()    windows.title(
"打鈴系統v1.0")    windows.geometry(
'1200x600')    windows.resizable(
0,0)  #禁止更改窗口大小
    app = Application(windows)    app.creatTree()    app.creatThings()    app.Gui_arrange()    app.Test()    
def looppro():        app.Belling()    threadObj01 = threading.Thread(
target=looppro)    threadObj01.start()    windows.mainloop()    sys.exit()currentDir=os.getcwd()
print("os.getcwd()=%s" % os.getcwd())
if __name__ == '__main__':    
print("game starts")    mainpro()    
print("game ends")
#開始之後,鬧鈴檢測程序自動啟動,點擊“停止”圓框選項後,鬧鈴檢測程序停止,在按“啟動”圓框選項,程序並未啟動

到此這篇關於如何用python GUI(tkinter)寫一個鬧鈴小程序(思路詳解)的文章就介紹到這瞭,更多相關python 鬧鈴小程序內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: