2017-08-02 91 views
0

我試圖做一個番茄鍾計時器,它將顯示不同的倒計時三個按鈕選項之一的點擊。設置tkinter標籤顯示倒數計時器

這裏的問題是,每次我點擊一個按鈕後,先前點擊一個按鈕,該標籤掙扎與顯示哪個定時器。它試圖同時顯示兩個計時器倒計時。

我需要標籤停止顯示第一個按鈕的計時器倒計時,當我點擊另一個按鈕。這裏是我的代碼:

from tkinter import * 

class Application(Frame): 
    def __init__(self,master): 
     super(Application,self).__init__(master) 
     self.pack() 
     self.createWidgets() 

    def createWidgets(self): 

     self.labelvariable = StringVar() 
     self.labelvariable.set("25:00") 

     self.thelabel = Label(self,textvariable = self.labelvariable,font=('Helvetica',50)) 
     self.thelabel.pack(side=TOP) 

     self.firstButton = Button(self,text="pomodoro",command=self.pomodoro) 
     self.firstButton.pack(side=LEFT) 

     self.secondButton = Button(self,text="short break",command=self.shortBreak) 
     self.secondButton.pack(side=LEFT) 

     self.thirdButton = Button(self,text="long break",command=self.longBreak) 
     self.thirdButton.pack(side=LEFT) 

    def pomodoro(self): 
     countdown(1500) 

    def shortBreak(self): 
     countdown(300) 

    def longBreak(self): 
     countdown(600) 





def countdown(timeInSeconds): 
    mins,secs = divmod(timeInSeconds,60) 
    timeformat = "{0:02d}:{1:02d}".format(mins,secs) 
    app.labelvariable.set(timeformat) 
    root.after(1000,countdown,timeInSeconds-1) 



if __name__ == '__main__': 
    root = Tk() 
    root.title("Timer") 
    app = Application(root) 
    root.mainloop() 
+2

使用after_cancel()取消前()調用之後http://effbot.org/tkinterbook/widget.htm我建議您等待像1/10秒,併發出另一個after_cancel( ),以防在程序在函數中,但在after()語句之上的地方點擊。 –

回答

0

這裏是一個可能的解決方案。這個將countdown函數移入Application類,並使其自由運行。然後,我添加了一個類屬性來跟蹤當前剩餘時間,並將其減少到0.這樣做的缺點是可能需要幾秒鐘來顯示新的計數。

from tkinter import * 
from threading import Event 

class Application(Frame): 
    def __init__(self,master): 
     super(Application,self).__init__(master) 
     self.pack() 
     self.createWidgets() 
     self._count = 0 
     self.countdown() 

    def createWidgets(self): 

     self.labelvariable = StringVar() 

     self.thelabel = Label(self,textvariable = self.labelvariable,font=('Helvetica',50)) 
     self.thelabel.pack(side=TOP) 

     self.firstButton = Button(self,text="pomodoro",command=self.pomodoro) 
     self.firstButton.pack(side=LEFT) 

     self.secondButton = Button(self,text="short break",command=self.shortBreak) 
     self.secondButton.pack(side=LEFT) 

     self.thirdButton = Button(self,text="long break",command=self.longBreak) 
     self.thirdButton.pack(side=LEFT) 

    def pomodoro(self): 
     self._count = 1500 

    def shortBreak(self): 
     self._count = 300 

    def longBreak(self): 
     self._count = 600 

    def countdown(self): 
     mins,secs = divmod(self._count,60) 
     timeformat = "{0:02d}:{1:02d}".format(mins,secs) 
     app.labelvariable.set(timeformat) 
     if self._count > 0: 
      self._count -= 1 
     root.after(1000,self.countdown) 



if __name__ == '__main__': 
    root = Tk() 
    root.title("Timer") 
    app = Application(root) 
    root.mainloop() 

這是基於捲毛喬的comment另一種選擇。這一個使用after_cancel通過取消下一個警報來停止當前正在運行的倒計時。它的好處是新的倒計時立即開始。

from tkinter import * 


class Application(Frame): 
    def __init__(self,master): 
     super(Application,self).__init__(master) 
     self.pack() 
     self.createWidgets() 
     self._alarm_id = None 

    def createWidgets(self): 

     self.labelvariable = StringVar() 
     self.labelvariable.set("25:00") 

     self.thelabel = Label(self,textvariable = self.labelvariable,font=('Helvetica',50)) 
     self.thelabel.pack(side=TOP) 

     self.firstButton = Button(self,text="pomodoro",command=self.pomodoro) 
     self.firstButton.pack(side=LEFT) 

     self.secondButton = Button(self,text="short break",command=self.shortBreak) 
     self.secondButton.pack(side=LEFT) 

     self.thirdButton = Button(self,text="long break",command=self.longBreak) 
     self.thirdButton.pack(side=LEFT) 

    def pomodoro(self): 
     if self._alarm_id is not None: 
      self.master.after_cancel(self._alarm_id) 
     self.countdown(1500) 

    def shortBreak(self): 
     if self._alarm_id is not None: 
      self.master.after_cancel(self._alarm_id) 
     self.countdown(300) 

    def longBreak(self): 
     if self._alarm_id is not None: 
      self.master.after_cancel(self._alarm_id) 
     self.countdown(600) 

    def countdown(self, timeInSeconds): 
     mins,secs = divmod(timeInSeconds, 60) 
     timeformat = "{0:02d}:{1:02d}".format(mins, secs) 
     app.labelvariable.set(timeformat) 
     self._alarm_id = self.master.after(1000, self.countdown, timeInSeconds-1) 


if __name__ == '__main__': 
    root = Tk() 
    root.title("Timer") 
    app = Application(root) 
    root.mainloop() 
+0

沒有理由做'self.after(0,self.countdown)'。直接調用它:'self.countdown()'。 –

+0

這太好了。非常感謝大家 –

+0

@BryanOakley這是一個很好的觀點。我使用'後'來推遲實際運行'倒計時',直到主循環開始。不過,這種情況的好處是微不足道的。 – FamousJameous