Tkinter中datetime时间相等判断提前且重复触发问题求解
问题根因分析
- 核心错误:目标时间被意外覆盖
你在checkTimer()函数开头写了target_time = datetime.now(),直接把setTimer()中预设的倒计时结束时间覆盖成了当前时间,后续判断datetime.now() == target_time自然会立刻成立,这就是代码远早于设定时间触发的根本原因。 - 逻辑缺陷:时间判断规则不合理
datetime.now()返回的时间精确到微秒,而window.after(500, checkTimer)的调度存在毫秒级误差,几乎不可能刚好命中完全相等的时间点,即使偶发匹配也很容易出现漏掉触发的问题,正确的判断逻辑应该用>=检测当前时间是否超过目标时间。 - 反复执行的原因
每次进入checkTimer()都会把target_time重置为当前时间,导致datetime.now() == target_time判断每次都成立,分支代码自然会被反复执行。
修复方案
只需要修改checkTimer()函数的两处逻辑即可解决所有问题:
- 删除函数开头覆盖
target_time的错误代码 - 将时间相等判断改为大于等于判断
另外你代码中手动判断target_minutes >= 60调整小时的逻辑完全冗余,用timedelta更新datetime类型的target_time时会自动处理时间进位,不需要手动维护时分变量。
修复后的核心代码片段:
def checkTimer(): global jsonFile, target_minutes, target_hours, current_hrs, current_minutes global onBreak, periods, drowsy, current_secs, target_secs, target_time # 已删除原错误代码 target_time = datetime.now() 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') # 原 == 改为 >= if datetime.now() >= target_time: onBreak = not onBreak timer.config(text="Completed") playsound(f'{os.getcwd()}/Audio/notification.mp3') if onBreak: if periods == 4: target_time = datetime.now() + timedelta(minutes=30) periods = 0 else: target_time = datetime.now() + timedelta(minutes=5) else: target_time = datetime.now() + timedelta(minutes=1) periods += 1 else: timer.config(text="In Progress") window.after(500, checkTimer)
内容的提问来源于stack exchange,提问作者Daniel Portas-Levy
相关产品推荐
相关产品推荐

