Python Tkinter赛事倒计时器:实现指定次数重复倒计时的问题
赛事倒计时器重复执行问题解决建议
问题背景
开发基于Tkinter的赛事倒计时器,需求如下:
- 通过输入框获取整数
levels(重复次数X) - 收集倒计时时长,倒计时结束后重复执行X次
- 点击
set按钮后显示start和stop按钮
现有代码中,尝试在start_time函数的while循环外层添加for x in range(0,levels):实现重复,但仅运行一次就结束。
核心问题分析
- 第一次倒计时结束后,
self.time_left被减至0,后续循环的while条件self.time_left > 0直接不成立,导致无法重复执行 - 未在每次循环开始时重置倒计时时长为初始值
- 缺少对当前重复次数(盲注等级)的显示逻辑
解决方案代码修改
步骤1:在Get_Time中保存初始时长和重复次数
首先需要在Get_Time函数中,把用户设置的初始时长和levels值保存为类属性,方便后续重复使用:
def Get_Time(self): self.time_display = Label(self.time_frame, font=('Helvetica', 124 , "bold"), bg = 'gray35', fg = 'yellow') self.time_display.place(x=430, y=240) # 创建盲注等级显示标签(改为类属性,方便后续更新) self.blind_level = Label(self.window, text="Blinds: Level 1", font=("helvetica",42, "bold"), bg='gray35',fg='yellow') self.blind_level.place(x=450, y=470) try: # 总时长(秒) m = (int(self.minute_combobox.get())*60) s = (int(self.second_combobox.get())) self.time_left = m + s # 保存初始时长,用于重复倒计时时重置 self.initial_time = m + s # 获取用户输入的重复次数levels(假设输入框名为levels_entry) self.levels = int(self.levels_entry.get()) # 若用户设置默认时间(0:0:0)则弹出警告 if s == 0 and m == 0: messagebox.showwarning('Warning!', 'Not a valid time!') else: # 开始按钮 start_button = Button(self.button_frame, text='Start', font=('Helvetica',12), bg="green", fg="white", command=self.Threading) start_button.place(x=160, y=0) # 暂停按钮 pause_button = Button(self.button_frame, text='Pause', font=('Helvetica',12), bg="red", fg="white", command=self.pause_time) pause_button.place(x=240, y=0) except Exception as es: messagebox.showerror("Error!", f"Error due to {es}")
步骤2:修改start_time函数实现重复倒计时
修改计时函数,在外层加入for循环,每次循环开始时重置self.time_left为初始值,并更新当前盲注等级:
def start_time(self): self.pause = False # 循环执行levels次倒计时 for level in range(1, self.levels + 1): if self.pause: break # 重置倒计时时长为初始值 self.time_left = self.initial_time # 更新当前盲注等级显示 self.blind_level.config(text=f"Blinds: Level {level}") self.blind_level.update() while self.time_left > 0: if self.pause: break mins, secs = divmod(self.time_left, 60) # 处理小时逻辑(修正原代码的错误,divmod返回元组,需要正确解构) hours, mins = divmod(mins, 60) # 格式化显示时间,补零确保两位数字 time_str = f"{hours:02d}:{mins:02d}:{secs:02d}" if hours > 0 else f"{mins:02d}:{secs:02d}" self.time_display.config(text=time_str) self.time_display.update() time.sleep(1) self.time_left -= 1 # 如果是主动暂停,直接跳出外层循环 if self.pause: break # 倒计时结束后可以添加提示音或其他逻辑(可选) # messagebox.showinfo("提示", f"Level {level} 倒计时结束!")
额外优化点
- 修正原代码中小时处理的逻辑错误,正确解构
divmod返回的元组 - 对时间显示进行补零处理,保证格式统一(如
02:30而非2:30) - 将盲注等级标签改为类属性,方便每次循环更新显示
关键说明
- 必须保存初始时长
self.initial_time,否则第一次倒计时结束后self.time_left为0,无法再次启动循环 - 外层for循环遍历
range(1, self.levels+1),直接显示从1开始的等级,更符合赛事等级习惯 - 每次循环开始前检查
self.pause状态,确保暂停操作能立即终止所有循环
内容的提问来源于stack exchange,提问作者Daniel Larson
相关产品推荐
相关产品推荐

