使用Python編寫一個(gè)定時(shí)任務(wù)提醒系統(tǒng)
更新時(shí)間:2025年05月06日 09:07:39 作者:小羊客棧
上班有時(shí)會忘記一些自己的事,所以可能需要在上班的的時(shí)候突然給你彈窗,你就知道要做啥了,所以下面我們就來使用Python編寫一個(gè)定時(shí)任務(wù)提醒系統(tǒng)吧
系統(tǒng)提醒
上班會忘記一些自己的事,所以你需要在上班的的時(shí)候突然給你彈窗,你就知道要做啥了
源碼
# -*- 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(" 定時(shí)任務(wù)提醒系統(tǒng)") 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): """創(chuàng)建默認(rèn)提醒聲音""" try: # 生成簡單的提示音 frequency = 2000 # 頻率 (Hz) duration = 1000 # 持續(xù)時(shí)間 (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(" 警告", "無法創(chuàng)建默認(rèn)聲音文件,將使用系統(tǒng)蜂鳴聲") def create_widgets(self): """創(chuàng)建界面組件""" # 主框架 main_frame = ttk.Frame(self.root, padding="10") main_frame.pack(fill=tk.BOTH, expand=True) # 任務(wù)列表 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) # 狀態(tài)欄 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): """編輯現(xiàn)有提醒""" selected = self.task_listbox.curselection() if not selected: messagebox.showwarning(" 警告", "請先選擇一個(gè)提醒") 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(" 警告", "請先選擇一個(gè)提醒") return index = selected[0] task_title = self.tasks[index]["title"] if messagebox.askyesno(" 確認(rèn)", 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): """刷新任務(wù)列表顯示""" 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}分鐘重復(fù))" self.task_listbox.insert(tk.END, f"{task['title']} - {task['time']}{repeat_text}") def load_tasks(self): """從文件加載任務(wù)""" if os.path.exists("reminders.json"): try: with open("reminders.json", "r") as f: self.tasks = json.load(f) except: self.tasks = [] messagebox.showwarning(" 警告", "無法加載提醒列表,已創(chuàng)建新列表") def save_tasks(self): """保存任務(wù)到文件""" 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 # 更新下次提醒時(shí)間 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) # 默認(rèn)蜂鳴聲 except: pass # 顯示對話框 self.root.after(0, lambda: messagebox.showinfo(task["title"], task["message"])) def on_closing(self): """關(guān)閉窗口時(shí)清理資源""" self.check_reminders_active = False self.root.destroy() class ReminderDialog(tk.Toplevel): """提醒設(shè)置對話框""" def __init__(self, parent, dialog_title="設(shè)置提醒", title_text="", message="", time=None, repeats=False, repeat_interval="5"): super().__init__(parent) self.title(dialog_title) # 窗口標(biāo)題 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) # 標(biāo)題 ttk.Label(main_frame, text="提醒標(biāo)題:").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="提醒內(nèi)容:").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) # 時(shí)間設(shè)置 time_frame = ttk.Frame(main_frame) time_frame.grid(row=2, column=0, columnspan=2, sticky="ew", pady=5) ttk.Label(time_frame, text="提醒時(shí)間:").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) # 重復(fù)設(shè)置 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="重復(fù)提醒", 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): """切換重復(fù)設(shè)置狀態(tài)""" if self.repeats_var.get(): self.interval_entry.config(state=tk.NORMAL) else: self.interval_entry.config(state=tk.DISABLED) def on_ok(self): """確認(rèn)設(shè)置""" 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(" 錯(cuò)誤", "提醒標(biāo)題不能為空") return if not message: messagebox.showerror(" 錯(cuò)誤", "提醒內(nèi)容不能為空") 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(" 錯(cuò)誤", "請輸入有效的重復(fù)間隔(正整數(shù))") 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(" 錯(cuò)誤", "請輸入有效的時(shí)間格式(YYYY-MM-DD HH:MM)") if __name__ == "__main__": root = tk.Tk() app = ReminderApp(root) root.protocol("WM_DELETE_WINDOW", app.on_closing) root.mainloop()
到此這篇關(guān)于使用Python編寫一個(gè)定時(shí)任務(wù)提醒系統(tǒng)的文章就介紹到這了,更多相關(guān)Python定時(shí)任務(wù)提醒內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
OpenCV學(xué)習(xí)方框?yàn)V波實(shí)現(xiàn)圖像處理代碼示例
這篇文章主要為大家介紹了OpenCV學(xué)習(xí)如何使用方框?yàn)V波實(shí)現(xiàn)對圖像處理代碼示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-10-10