使用Python编写一个定时任务提醒系统
作者:小羊客栈
上班有时会忘记一些自己的事,所以可能需要在上班的的时候突然给你弹窗,你就知道要做啥了,所以下面我们就来使用Python编写一个定时任务提醒系统吧
系统提醒
上班会忘记一些自己的事,所以你需要在上班的的时候突然给你弹窗,你就知道要做啥了
源码
# -*- coding:utf-8 -*- """ 作者:YTQ 日期: 2025年04日29 21:51:24 """ import datetime import time import threading import winsound import tkinter as tk from tkinter import ttk, messagebox from plyer import notification import json import os import math class ReminderApp: def __init__(self, root): self.root = root self.root.title(" 定时任务提醒系统") self.root.geometry("500x400") self.tasks = [] self.load_tasks() # 初始化声音文件 self.sound_file = "reminder.wav" if not os.path.exists(self.sound_file): self.create_default_sound() self.create_widgets() self.check_reminders_active = True self.start_reminder_checker() def create_default_sound(self): """创建默认提醒声音""" try: # 生成简单的提示音 frequency = 2000 # 频率 (Hz) duration = 1000 # 持续时间 (ms) winsound.Beep(frequency, duration) # 保存为WAV文件 import wave import struct sample_rate = 44100 n_samples = int(sample_rate * duration / 1000) max_amplitude = 32767 with wave.open(self.sound_file, 'w') as f: f.setparams((1, 2, sample_rate, n_samples, 'NONE', 'not compressed')) for i in range(n_samples): value = int(max_amplitude * (0.5 * (1 + math.sin(2 * math.pi * frequency * i / sample_rate)))) data = struct.pack('<h', value) f.writeframesraw(data) except: messagebox.showwarning(" 警告", "无法创建默认声音文件,将使用系统蜂鸣声") def create_widgets(self): """创建界面组件""" # 主框架 main_frame = ttk.Frame(self.root, padding="10") main_frame.pack(fill=tk.BOTH, expand=True) # 任务列表 self.task_listbox = tk.Listbox(main_frame, height=10, selectmode=tk.SINGLE) self.task_listbox.pack(fill=tk.BOTH, expand=True, pady=(0, 10)) self.refresh_task_list() # 滚动条 scrollbar = ttk.Scrollbar(main_frame, orient="vertical") scrollbar.config(command=self.task_listbox.yview) self.task_listbox.config(yscrollcommand=scrollbar.set) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) # 按钮框架 button_frame = ttk.Frame(main_frame) button_frame.pack(fill=tk.X, pady=(10, 0)) ttk.Button(button_frame, text="添加提醒", command=self.add_reminder).pack(side=tk.LEFT, padx=5) ttk.Button(button_frame, text="编辑提醒", command=self.edit_reminder).pack(side=tk.LEFT, padx=5) ttk.Button(button_frame, text="删除提醒", command=self.delete_reminder).pack(side=tk.LEFT, padx=5) # 状态栏 self.status_var = tk.StringVar() self.status_var.set(" 就绪") ttk.Label(main_frame, textvariable=self.status_var, relief=tk.SUNKEN).pack(fill=tk.X, pady=(10, 0)) def add_reminder(self): """添加新提醒""" dialog = ReminderDialog(self.root, "添加新提醒") if dialog.result: self.tasks.append({ "title": dialog.result["title"], "message": dialog.result["message"], "time": dialog.result["time"].strftime("%Y-%m-%d %H:%M"), "repeats": dialog.result["repeats"], "repeat_interval": dialog.result["repeat_interval"] }) self.save_tasks() self.refresh_task_list() self.status_var.set(f" 已添加新提醒: {dialog.result['title']}") def edit_reminder(self): """编辑现有提醒""" selected = self.task_listbox.curselection() if not selected: messagebox.showwarning(" 警告", "请先选择一个提醒") return index = selected[0] task = self.tasks[index] time_obj = datetime.datetime.strptime(task["time"], "%Y-%m-%d %H:%M") dialog = ReminderDialog( parent=self.root, dialog_title="编辑提醒", title_text=task["title"], message=task["message"], time=time_obj, repeats=task["repeats"], repeat_interval=task["repeat_interval"] ) if dialog.result: self.tasks[index] = { "title": dialog.result["title"], "message": dialog.result["message"], "time": dialog.result["time"].strftime("%Y-%m-%d %H:%M"), "repeats": dialog.result["repeats"], "repeat_interval": dialog.result["repeat_interval"] } self.save_tasks() self.refresh_task_list() self.status_var.set(f" 已更新提醒: {dialog.result['title']}") def delete_reminder(self): """删除提醒""" selected = self.task_listbox.curselection() if not selected: messagebox.showwarning(" 警告", "请先选择一个提醒") return index = selected[0] task_title = self.tasks[index]["title"] if messagebox.askyesno(" 确认", f"确定要删除提醒 '{task_title}' 吗?"): del self.tasks[index] self.save_tasks() self.refresh_task_list() self.status_var.set(f" 已删除提醒: {task_title}") def refresh_task_list(self): """刷新任务列表显示""" self.task_listbox.delete(0, tk.END) for task in self.tasks: repeat_text = "" if task["repeats"]: interval = task["repeat_interval"] repeat_text = f" (每{interval}分钟重复)" self.task_listbox.insert(tk.END, f"{task['title']} - {task['time']}{repeat_text}") def load_tasks(self): """从文件加载任务""" if os.path.exists("reminders.json"): try: with open("reminders.json", "r") as f: self.tasks = json.load(f) except: self.tasks = [] messagebox.showwarning(" 警告", "无法加载提醒列表,已创建新列表") def save_tasks(self): """保存任务到文件""" with open("reminders.json", "w") as f: json.dump(self.tasks, f, indent=2) def start_reminder_checker(self): """启动提醒检查线程""" def check_reminders(): while self.check_reminders_active: now = datetime.datetime.now() for task in self.tasks: task_time = datetime.datetime.strptime(task["time"], "%Y-%m-%d %H:%M") if task["repeats"]: interval = datetime.timedelta(minutes=int(task["repeat_interval"])) while task_time <= now: if task_time + datetime.timedelta(seconds=30) >= now: self.show_reminder(task) break task_time += interval # 更新下次提醒时间 while task_time <= now: task_time += interval task["time"] = task_time.strftime("%Y-%m-%d %H:%M") self.save_tasks() else: if task_time <= now <= task_time + datetime.timedelta(seconds=30): self.show_reminder(task) # 一次性提醒完成后删除 self.tasks.remove(task) self.save_tasks() self.refresh_task_list() break time.sleep(1) threading.Thread(target=check_reminders, daemon=True).start() def show_reminder(self, task): """显示提醒通知""" # 桌面通知 notification.notify( title=task["title"], message=task["message"], timeout=10 ) # 播放声音 try: if os.path.exists(self.sound_file): winsound.PlaySound(self.sound_file, winsound.SND_FILENAME) else: winsound.Beep(2000, 1000) # 默认蜂鸣声 except: pass # 显示对话框 self.root.after(0, lambda: messagebox.showinfo(task["title"], task["message"])) def on_closing(self): """关闭窗口时清理资源""" self.check_reminders_active = False self.root.destroy() class ReminderDialog(tk.Toplevel): """提醒设置对话框""" def __init__(self, parent, dialog_title="设置提醒", title_text="", message="", time=None, repeats=False, repeat_interval="5"): super().__init__(parent) self.title(dialog_title) # 窗口标题 self.result = None if time is None: time = datetime.datetime.now() + datetime.timedelta(minutes=5) # 主框架 main_frame = ttk.Frame(self, padding="10") main_frame.pack(fill=tk.BOTH, expand=True) # 标题 ttk.Label(main_frame, text="提醒标题:").grid(row=0, column=0, sticky="w", pady=5) self.title_entry = ttk.Entry(main_frame, width=30) self.title_entry.grid(row=0, column=1, sticky="ew", pady=5) self.title_entry.insert(0, title_text) # 消息 ttk.Label(main_frame, text="提醒内容:").grid(row=1, column=0, sticky="nw", pady=5) self.message_text = tk.Text(main_frame, width=30, height=4) self.message_text.grid(row=1, column=1, sticky="ew", pady=5) self.message_text.insert("1.0", message) # 时间设置 time_frame = ttk.Frame(main_frame) time_frame.grid(row=2, column=0, columnspan=2, sticky="ew", pady=5) ttk.Label(time_frame, text="提醒时间:").pack(side=tk.LEFT) self.time_var = tk.StringVar(value=time.strftime("%Y-%m-%d %H:%M")) self.time_entry = ttk.Entry(time_frame, textvariable=self.time_var, width=16) self.time_entry.pack(side=tk.LEFT, padx=5) # 重复设置 repeat_frame = ttk.Frame(main_frame) repeat_frame.grid(row=3, column=0, columnspan=2, sticky="ew", pady=5) self.repeats_var = tk.BooleanVar(value=repeats) self.repeat_check = ttk.Checkbutton( repeat_frame, text="重复提醒", variable=self.repeats_var, command=self.toggle_repeat) self.repeat_check.pack(side=tk.LEFT) ttk.Label(repeat_frame, text="间隔(分钟):").pack(side=tk.LEFT, padx=(10, 5)) self.interval_entry = ttk.Entry(repeat_frame, width=5) self.interval_entry.pack(side=tk.LEFT) self.interval_entry.insert(0, repeat_interval) self.toggle_repeat() # 按钮 button_frame = ttk.Frame(main_frame) button_frame.grid(row=4, column=0, columnspan=2, pady=(10, 0)) ttk.Button(button_frame, text="确定", command=self.on_ok).pack(side=tk.RIGHT, padx=5) ttk.Button(button_frame, text="取消", command=self.destroy).pack(side=tk.RIGHT) self.transient(parent) self.grab_set() self.wait_window(self) def toggle_repeat(self): """切换重复设置状态""" if self.repeats_var.get(): self.interval_entry.config(state=tk.NORMAL) else: self.interval_entry.config(state=tk.DISABLED) def on_ok(self): """确认设置""" try: time_obj = datetime.datetime.strptime(self.time_var.get(), "%Y-%m-%d %H:%M") title = self.title_entry.get().strip() message = self.message_text.get("1.0", "end-1c").strip() if not title: messagebox.showerror(" 错误", "提醒标题不能为空") return if not message: messagebox.showerror(" 错误", "提醒内容不能为空") return repeat_interval = "5" if self.repeats_var.get(): try: repeat_interval = str(int(self.interval_entry.get())) if int(repeat_interval) <= 0: raise ValueError except: messagebox.showerror(" 错误", "请输入有效的重复间隔(正整数)") return self.result = { "title": title, "message": message, "time": time_obj, "repeats": self.repeats_var.get(), "repeat_interval": repeat_interval } self.destroy() except ValueError: messagebox.showerror(" 错误", "请输入有效的时间格式(YYYY-MM-DD HH:MM)") if __name__ == "__main__": root = tk.Tk() app = ReminderApp(root) root.protocol("WM_DELETE_WINDOW", app.on_closing) root.mainloop()
到此这篇关于使用Python编写一个定时任务提醒系统的文章就介绍到这了,更多相关Python定时任务提醒内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!