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

如何实现程序关闭后仍能在指定天数后触发通知(Python Tkinter)

解决方案:持久化到期任务并自动触发通知

我来帮你搞定这个问题,核心是要存储任务的到期时间而非剩余天数——毕竟程序关闭后,我们没法追踪原本的起始时间,存具体的datetime才能准确判断任务是否到期。下面是完善后的完整代码和关键解释:

完整代码实现

from tkinter import *
from datetime import datetime, timedelta
import pickle
from tkinter import messagebox

filename = "file.pk"  # 存储格式:{到期datetime: [姓名, 物品, 原设定天数]}
root = Tk()
root.title("延迟任务通知器")

# 定义界面输入变量
days_var = IntVar()
item_var = StringVar()
name_var = StringVar()

def show_notification(name, item, days):
    """触发到期提醒弹窗"""
    messagebox.showinfo("任务到期啦!", f"姓名:{name}\n物品:{item}\n设定天数:{days}")

def check_expired_tasks():
    """检查并处理所有到期的任务(核心完善函数)"""
    try:
        # 尝试加载存储的任务文件,文件不存在则初始化空字典
        with open(filename, "rb") as f:
            tasks = pickle.load(f)
    except FileNotFoundError:
        tasks = {}
    
    now = datetime.now()
    expired_task_times = []  # 记录需要删除的已到期任务时间
    
    # 遍历所有任务,判断是否到期
    for expire_time, task_info in tasks.items():
        name, item, original_days = task_info
        if expire_time <= now:
            # 触发通知
            show_notification(name, item, original_days)
            # 标记该任务为已处理,后续删除
            expired_task_times.append(expire_time)
    
    # 移除已触发通知的任务,避免重复提醒
    for task_time in expired_task_times:
        del tasks[task_time]
    
    # 保存更新后的任务列表回文件
    with open(filename, "wb") as f:
        pickle.dump(tasks, f)

def add_task():
    """添加新的延迟任务功能(补充原代码缺失的输入逻辑)"""
    try:
        days = days_var.get()
        name = name_var.get().strip()
        item = item_var.get().strip()
        
        # 校验输入合法性
        if days <= 0 or not name or not item:
            messagebox.showerror("输入错误", "请填写有效的姓名、物品和正整数天数!")
            return
        
        # 计算任务到期的具体时间
        expire_time = datetime.now() + timedelta(days=days)
        
        # 加载现有任务(不存在则初始化)
        try:
            with open(filename, "rb") as f:
                tasks = pickle.load(f)
        except FileNotFoundError:
            tasks = {}
        
        # 添加新任务到字典
        tasks[expire_time] = [name, item, days]
        
        # 保存任务到文件
        with open(filename, "wb") as f:
            pickle.dump(tasks, f)
        
        messagebox.showinfo("成功", "任务已添加!")
        # 清空输入框
        name_var.set("")
        item_var.set("")
        days_var.set(0)
    except Exception as e:
        messagebox.showerror("错误", f"添加任务失败:{str(e)}")

# 构建GUI界面
Label(root, text="姓名:").grid(row=0, column=0, padx=5, pady=5)
Entry(root, textvariable=name_var).grid(row=0, column=1, padx=5, pady=5)

Label(root, text="物品:").grid(row=1, column=0, padx=5, pady=5)
Entry(root, textvariable=item_var).grid(row=1, column=1, padx=5, pady=5)

Label(root, text="延迟天数:").grid(row=2, column=0, padx=5, pady=5)
Entry(root, textvariable=days_var).grid(row=2, column=1, padx=5, pady=5)

Button(root, text="添加任务", command=add_task).grid(row=3, column=0, columnspan=2, pady=10)

# 程序启动时立刻检查到期任务(核心需求实现)
check_expired_tasks()

root.mainloop()

关键逻辑说明

  • 存储到期时间而非天数:不再存剩余天数,而是直接计算任务的到期datetime并持久化。这样即使程序关闭,下次启动时也能准确对比当前时间判断任务是否到期。
  • 启动自动检查:程序一启动就调用check_expired_tasks(),处理所有到期任务,完美实现“中途关闭后,到期仍能触发通知”的需求。
  • 清理已处理任务:到期任务触发通知后会从字典中删除,避免下次启动时重复提醒同一任务。
  • 异常处理:针对文件不存在、非法输入等情况做了处理,保证程序稳定性。

使用方法

  1. 运行程序,输入姓名、物品和需要延迟的天数,点击「添加任务」即可保存。
  2. 关闭程序后,只要任务到期时间到了,下次启动程序就会自动弹出通知。
  3. 支持添加多个任务,程序会逐一检查并处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:53:35