You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Tkinter实现双消息弹窗?解决弹窗互斥无法打开问题

Tkinter任务提醒工具:弹窗阻塞问题修复

你遇到的核心问题是模态对话框阻塞主线程+错误的循环方式导致Tk事件循环无法正常运行,同时每次弹窗都新建Tk实例会引发内部冲突。具体来说:

  • messagebox.showinfo是模态对话框,弹出后会阻塞整个程序直到用户关闭,此时另一个弹窗的触发逻辑会被卡住。
  • 主循环用while True + time.sleep(0)完全绕过了Tkinter的事件循环,导致Tk无法处理后续的弹窗请求。
  • 重复创建Tk()实例会产生多个独立主窗口,引发控件冲突。

修复后的代码

import time
import tkinter as tk
from tkinter import messagebox

routine_schedule = [
    (8, 0, "Wake up and hydrate"),
    (8, 15, "Mindfulness or meditation"),
    (8, 30, "Morning exercise"),
    (9, 0, "Healthy breakfast"),
    (9, 30, "Start coding session"),
    (10, 55, "Pomodoro break - Stretch and hydrate"),
    (11, 0, "Back to coding"),
    (12, 30, "Lunch break"),
    (13, 30, "Outdoor time"),
    (14, 0, "Continue coding"),
    (15, 25, "Pomodoro break - Creative activity"),
    (15, 30, "Coding session"),
    (17, 0, "Evening workout/activity"),
    (18, 0, "Healthy dinner"),
    (19, 0, "Relaxation time"),
    (20, 0, "Digital detox"),
    (21, 0, "Prepare for sleep"),
]

# 全局唯一Tk主窗口,复用它弹出所有消息框
root = tk.Tk()
root.withdraw()  # 隐藏主窗口

def notify_task(task):
    messagebox.showinfo("Task Reminder", f"It's time to: {task}")

def get_next_task():
    current_time = time.localtime()
    current_hour, current_min = current_time.tm_hour, current_time.tm_min
    for schedule_hour, schedule_minute, schedule_task in routine_schedule:
        if (schedule_hour > current_hour) or (schedule_hour == current_hour and schedule_minute > current_min):
            return schedule_hour, schedule_minute, schedule_task
    # 当天任务结束后返回次日第一个任务
    return routine_schedule[0] if routine_schedule else None

def display_next_task():
    next_task = get_next_task()
    if next_task:
        next_hour, next_minute, next_task_description = next_task
        next_task_text = f"Next task: {next_task_description}\nTime: {next_hour:02d}:{next_minute:02d}"
        messagebox.showinfo("Next Task", next_task_text)
    # 每分钟更新一次下一个任务(可自定义间隔)
    root.after(60000, display_next_task)

def check_current_task():
    current_time = time.localtime()
    current_hour, current_min = current_time.tm_hour, current_time.tm_min
    for schedule_hour, schedule_minute, schedule_task in routine_schedule:
        if current_hour == schedule_hour and current_min == schedule_minute:
            notify_task(schedule_task)
    # 每10秒检查一次当前时间,避免错过整点
    root.after(10000, check_current_task)

if __name__ == "__main__":
    display_next_task()
    check_current_task()
    root.mainloop()

关键修改说明

  • 复用单个Tk实例:只创建一个全局root窗口并隐藏,所有消息框基于此实例弹出,避免多窗口冲突。
  • 用Tk的after()替代while循环:after()在Tk事件循环中定时触发函数,不会阻塞主线程,模态弹窗关闭后程序能继续运行。
  • 调整检查频率:当前任务每10秒检查一次,下一个任务每分钟更新一次,平衡准确性和资源占用。
  • 完善任务循环逻辑:当天任务全部结束后自动返回次日第一个任务,避免空值报错。

内容的提问来源于stack exchange,提问作者Hatchy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 00:54:54