我在tkinter中写了一个基本的倒数计时器。倒数计时器第一次使用时可以正常工作,但是如果我第二次输入倒计时,则计时器的倒数速度是上一个倒计时的两倍,如果我第三次使用它,则倒计时速度会再次加倍。等等等等。
i在self.after((命令中指定倒计时间隔为1000毫秒,但似乎每次输入新的倒数时间时,该值似乎都会减半。似乎等待时间在每次连续使用中都会减半。如果我关闭倒计时小部件并重新打开,则从正确的时间开始重复过程,然后将每次连续使用的时间减半。
以下是我完整应用程序的简化代码,该代码证明了问题。时间是在单词"秒到倒计时"的右侧的文本框中手动输入的,然后按下"启动倒数"按钮以开始倒计时。重复此过程证明了这个问题。
我认为包括update_idletasks命令在内的问题可能会解决问题,但事实并非如此。
from tkinter import *
class timerTestGui(Frame):
def __init__(self, parent=None):
Frame.__init__(self, parent)
self.pack(expand=YES, fill=BOTH)
self.makeWidgets()
def initiateCountdown(self):
time = self.text_timer.get("1.0", END).strip()
time = int(time)
#self.update_idletasks()
self.countdown(time)
def countdown(self, remaining=None):
if remaining is not None:
self.remaining = remaining
self.label_countdown.configure(text=self.remaining)
self.remaining = self.remaining - 1
self.after(1000,self.countdown)
def makeWidgets(self):
self.label_current_timer = Label(self,text='Seconds To Countdown')
self.label_current_timer.grid(row=0,column=2)
self.text_timer = Text(self, relief=SUNKEN, height=1, width=10)
self.text_timer.tag_configure("center", justify='center')
self.text_timer.grid(row=0,column=3)
self.label_countdown = Label(self, text='')
self.label_countdown.grid(row=0,column=4)
self.button_session_start = Button(self, text='StartnCountdown', command=self.initiateCountdown)
self.button_session_start.grid(row=0,column=5)
if __name__ == '__main__':
root = Tk()
root.title('Countdown Timer')
app = timerTestGui(root)
root.mainloop()
如果有人对如何使倒计时计时器正确工作有任何想法,我将感谢您的帮助。
您的问题是,在创建新计时器之前,您永远不会停止旧计时器。您第一次创建计时器时,每秒运行一个函数。下次创建计时器时,旧函数仍在运行,但是现在您添加了第二个功能,每秒称为每秒。下次您添加三分之一时,依此类推。因此,如果您按下了10次按钮,则最终每秒更新柜台10次。
假设您只需运行一个实例,则需要在启动新命令之前停止旧的after
命令。after
返回您可以用于此目的的ID。
首先,初始化一个可用于存储当前after
命令的ID的变量:
class timerTestGui(Frame):
def __init__(self, parent=None):
...
self.after_id = None
...
接下来,请确保每当您致电after
时,都保存返回的ID:
def countdown(self, remaining=None):
...
self.after_id = self.after(1000,self.countdown)
最后,创建新计时器时,首先杀死旧计时器:
def initiateCountdown(self):
...
if self.after_id is not None:
self.after_cancel(self.after_id)
self.countdown(time)
...