我正在尝试制作一个番茄钟计时器,它会在点击三个按钮选项之一时显示不同的倒计时。
这里的问题是,每次我在之前点击一个按钮后点击一个按钮,标签就会与要显示的定时器之间的关系挣扎。它尝试同时显示两个计时器倒计时。
当我点击另一个按钮时,我需要标签停止显示第一个按钮的计时器倒计时。这是我的代码:
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()
答案 0 :(得分:0)
这是一种可能的解决方案。这个将countdown
函数移动到Application
类中并使其自由运行。然后我添加了一个class属性来跟踪剩下的当前时间,然后将其减少到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()
这是另一个基于Curly Joe 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()