tkinter开发中定时器无法检测计时结束如何解决?
checkTimer逻辑修复方案
已确认的错误点
- 时间判断仅校验分钟和秒,未校验小时,跨小时计时场景完全失效
- 启动定时器的
setTimer函数未同步更新target_secs初始值,首次计时触发逻辑永远不匹配 - 每轮checkTimer都打开JSON文件但未重新读取内容,
drowsy状态永远是程序启动时的初始值,且文件打开后未关闭造成资源泄漏 setTimer设置了10秒延迟才启动checkTimer,属于无意义的启动滞后- 仅工作时段更新
target_secs,休息时段结束后下一轮计时的秒数判断基准错误
修复后的核心代码
# 先修改setTimer函数 def setTimer(): global target_minutes, target_hours, current_hrs, current_minutes, onBreak, periods, current_secs, target_secs t = time.localtime() current_hrs = int(time.strftime("%H")) current_minutes = int(time.strftime("%M")) current_secs = int(time.strftime("%S")) # 初始化目标时间:首次启动后1分钟触发 target_hours = current_hrs target_minutes = current_minutes + 1 target_secs = current_secs if target_minutes >= 60: target_minutes -= 60 target_hours +=1 timer.config(text="In Progress") # 移除无意义的10秒延迟,1秒后启动校验 window.after(1000, checkTimer) # 再修改checkTimer函数 def checkTimer(): global jsonFile, target_minutes, target_hours, current_hrs, current_minutes, onBreak, periods, drowsy, current_secs, target_secs # 修复JSON读取逻辑:每次读取最新值,读完自动关闭文件 with open("Real-Time Drowsiness Detection OpenCV Python Source Code/VALUE.json", 'r') as f: data = json.load(f) drowsy = int(data["VALUE"]) timer.config(text="In Progress") t = time.localtime() current_hrs = int(time.strftime("%H")) current_minutes = int(time.strftime("%M")) current_secs = int(time.strftime("%S")) if get_idle_duration() >= 600: reminderTitle.config(text="Make sure to work!") playsound(f'{os.getcwd()}/Audio/GETTOWORK.wav') if drowsy == 1: playsound(f'{os.getcwd()}/Audio/wakeup.wav') # 修复时间判断逻辑:转成总秒数对比,兼容跨小时、跨天场景 current_total = current_hrs * 3600 + current_minutes * 60 + current_secs target_total = target_hours * 3600 + target_minutes * 60 + target_secs # 处理跨天场景 if current_total < target_total: current_total += 86400 if current_total >= target_total: onBreak = not onBreak timer.config(text="Completed") playsound(f'{os.getcwd()}/Audio/notification.mp3') if onBreak: if periods == 4: add_time = 30 * 60 periods = 0 else: add_time = 5 * 60 else: # 测试用1分钟工作时长,正式环境改回25*60即可 add_time = 1 * 60 periods += 1 # 统一计算新的目标时间,避免分别处理时分秒的逻辑错误 new_target_total = current_total + add_time if new_target_total >= 86400: new_target_total -= 86400 target_hours = new_target_total // 3600 target_minutes = (new_target_total % 3600) // 60 target_secs = new_target_total % 60 else: timer.config(text="In Progress") window.after(1000, checkTimer)
修改说明
- 将时间判断逻辑改为总秒数对比,自动兼容跨小时、跨天场景,不会出现计时到了不触发的问题
- 统一使用总秒数计算目标时间,避免分别调整时分秒时出现的逻辑错误
- 修复JSON读取逻辑,每次获取最新的drowsy值,且使用with语句自动关闭文件避免资源泄漏
- 移除setTimer的10秒无意义延迟,启动后立即开始计时校验
- 所有时段更新
target_secs,保证每一轮计时的判断基准正确
内容的提问来源于stack exchange,提问作者Daniel Portas-Levy
相关产品推荐
相关产品推荐

