import tkinter as tk
class Timer:
def __init__(self, master):
self.master = master
master.title("Pomodoro Timer")
self.state = False
self.minutes = 25
self.seconds = 0
self.display = tk.Label(master, height=10, width=10, textvariable="")
self.display.config(text="00:00")
self.display.grid(row=0, column=0, columnspan=2)
self.start_button = tk.Button(master, bg="Green", activebackground="Dark Green", text="Start", width=8, height=4, command=self.start())
self.start_button.grid(row=1, column=0)
self.pause_button = tk.Button(master, bg="Red", activebackground="Dark Red", text="Pause", width=8, height=4, command=self.pause())
self.pause_button.grid(row=1, column=1)
self.countdown()
def countdown(self):
"""Displays a clock starting at min:sec to 00:00, ex: 25:00 -> 00:00"""
mins = self.minutes
secs = self.seconds
if self.state == True:
if secs < 10:
if mins < 10:
self.display.config(text="0%d : 0%d" % (mins, secs))
else:
self.display.config(text="%d : 0%d" % (mins, secs))
else:
if mins < 10:
self.display.config(text="0%d : %d" % (mins, secs))
else:
self.display.config(text="%d : %d" % (mins, secs))
if (mins == 0) and (secs == 0):
self.display.config(text="Done!")
else:
if secs == 0:
mins -= 1
secs = 59
else:
secs -= 1
self.master.after(1000, self.countdown())
elif self.state == False:
self.master.after(100, self.countdown())
def start(self):
if self.state == False:
self.state = True
def pause(self):
if self.state == True:
self.state = False
root = tk.Tk()
my_timer = Timer(root)
root.mainloop()
一般来说,对于Python来说是个新手,我试图制作一个本质上具有开始和暂停功能的简单倒数计时器。
我认为可行的方法是在窗口启动时调用倒计时功能,让它通过递归调用不断检查窗口的“状态”。当“状态”为False时,倒计时功能将跳过倒计时功能的“计时器”部分并再次调用它以查看“状态”是否已更改。
当用户点击开始按钮时,“状态”将变为True,倒计时功能现在会看到“状态”已经改变,然后开始实际倒计时。
然后当用户点击暂停按钮时,“状态”将再次变为False,倒计时功能将再次跳过该功能的“计时器”部分,然后再次调用它。
我一直遇到的问题是:
RecursionError: maximum recursion depth exceeded in comparison
我不知道如何通过我目前的实现来解决这个错误。
修改
因此,在两个实例(不在init下)中将self.countdown()更改为self.countdown确实会修复错误,但现在函数只是“卡住”了。出现所需的窗口,但没有一个按钮似乎正在工作。
答案 0 :(得分:1)
command=
,after()
和bind()
需要不带()
的函数名称(有时称为callback
)
countdown()
由after()
执行,就像任何其他函数一样(但稍后),这意味着:
countdown()
会在每次执行中重新创建所有本地值,因此他们不会保留值。您必须使用self.mins
和self.secs
来保留值。
countdown()
内无法使用
mins = self.minutes
secs = self.seconds
因为它会在每次执行中将时间重置为25:00。您必须在start()
工作代码
import tkinter as tk
class Timer:
def __init__(self, master):
self.master = master
master.title("Pomodoro Timer")
self.state = False
self.minutes = 25
self.seconds = 0
self.mins = 25
self.secs = 0
self.display = tk.Label(master, height=10, width=10, textvariable="")
self.display.config(text="00:00")
self.display.grid(row=0, column=0, columnspan=2)
self.start_button = tk.Button(master, bg="Green", activebackground="Dark Green", text="Start", width=8, height=4, command=self.start)
self.start_button.grid(row=1, column=0)
self.pause_button = tk.Button(master, bg="Red", activebackground="Dark Red", text="Pause", width=8, height=4, command=self.pause)
self.pause_button.grid(row=1, column=1)
self.countdown()
def countdown(self):
"""Displays a clock starting at min:sec to 00:00, ex: 25:00 -> 00:00"""
if self.state == True:
if self.secs < 10:
if self.mins < 10:
self.display.config(text="0%d : 0%d" % (self.mins, self.secs))
else:
self.display.config(text="%d : 0%d" % (self.mins, self.secs))
else:
if self.mins < 10:
self.display.config(text="0%d : %d" % (self.mins, self.secs))
else:
self.display.config(text="%d : %d" % (self.mins, self.secs))
if (self.mins == 0) and (self.secs == 0):
self.display.config(text="Done!")
else:
if self.secs == 0:
self.mins -= 1
self.secs = 59
else:
self.secs -= 1
self.master.after(1000, self.countdown)
else:
self.master.after(100, self.countdown)
def start(self):
if self.state == False:
self.state = True
self.mins = self.minutes
self.secs = self.seconds
def pause(self):
if self.state == True:
self.state = False
root = tk.Tk()
my_timer = Timer(root)
root.mainloop()
编辑:,因为@ EL3PHANTEN指出您可以使用字符串格式来缩短它:
text='{:02} : {:02}'.format(self.mins,self.secs)
或
text="%02d : %02d" % (self.mins,self.secs)
我还将self.countdown()
行从__init__
移到了start()
,现在我不需要after()
内的第二个countdown()
。
我还会在显示self.state = False
Done!
import tkinter as tk
class Timer:
def __init__(self, master):
self.master = master
master.title("Pomodoro Timer")
self.state = False
self.minutes = 25
self.seconds = 0
self.mins = 25
self.secs = 0
self.display = tk.Label(master, height=10, width=10, textvariable="")
self.display.config(text="00:00")
self.display.grid(row=0, column=0, columnspan=2)
self.start_button = tk.Button(master, bg="Green", activebackground="Dark Green", text="Start", width=8, height=4, command=self.start)
self.start_button.grid(row=1, column=0)
self.pause_button = tk.Button(master, bg="Red", activebackground="Dark Red", text="Pause", width=8, height=4, command=self.pause)
self.pause_button.grid(row=1, column=1)
def countdown(self):
"""Displays a clock starting at min:sec to 00:00, ex: 25:00 -> 00:00"""
if self.state == True:
if (self.mins == 0) and (self.secs == 0):
self.display.config(text="Done!")
self.state = False
else:
self.display.config(text="%02d:%02d" % (self.mins, self.secs))
if self.secs == 0:
self.mins -= 1
self.secs = 59
else:
self.secs -= 1
self.master.after(1000, self.countdown)
def start(self):
if self.state == False:
self.state = True
self.mins = self.minutes
self.secs = self.seconds
self.countdown()
def pause(self):
if self.state == True:
self.state = False
root = tk.Tk()
my_timer = Timer(root)
root.mainloop()
"{:02} : {:02}".format(10, 0)