系统提醒

上班会忘记一些自己的事,所以你需要在上班的的时候突然给你弹窗,你就知道要做啥了

在这里插入图片描述
源码
这里有一个智能家居项目可以看看(开源)

# -*- 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 mathclass ReminderApp:def __init__(self, root):self.root = rootself.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 = Trueself.start_reminder_checker()def create_default_sound(self):"""创建默认提醒声音"""try:# 生成简单的提示音frequency = 2000  # 频率 (Hz)duration = 1000  # 持续时间 (ms)winsound.Beep(frequency, duration)# 保存为WAV文件import waveimport structsample_rate = 44100n_samples = int(sample_rate * duration / 1000)max_amplitude = 32767with 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(" 警告", "请先选择一个提醒")returnindex = 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(" 警告", "请先选择一个提醒")returnindex = 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)breaktask_time += interval# 更新下次提醒时间while task_time <= now:task_time += intervaltask["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()breaktime.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 = Falseself.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 = Noneif 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(" 错误", "提醒标题不能为空")returnif not message:messagebox.showerror(" 错误", "提醒内容不能为空")returnrepeat_interval = "5"if self.repeats_var.get():try:repeat_interval = str(int(self.interval_entry.get()))if int(repeat_interval) <= 0:raise ValueErrorexcept:messagebox.showerror(" 错误", "请输入有效的重复间隔(正整数)")returnself.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()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/78941.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/78941.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/78941.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos安装部署配置kafka

1、解压到目录 tar -zxvf kafka_2.13-2.8.2.tgz -C /usr/local/kafka2.进入目录 cd /usr/local/kafka/kafka_2.13-2.8.23.查看版本&#xff08;验证是否已解压&#xff09; bin/kafka-topics.sh --version4.修改配置&#xff0c;注意&#xff1a;此配置中有一个默认的zookee…

深⼊理解指针(7)

1.函数指针变量的创建 在x86环境下&#xff1a; 我们发现&#xff1a;以函数是有地址的&#xff0c;函数名就是函数的地址&#xff0c;当然也可以通过& 函数名 的⽅式获得函数的地址。 如果我们要将函数的地址存放起来&#xff0c;就得创建函数指针变量咯&#xff0c;函数…

AdaBoost算法的原理及Python实现

一、概述 AdaBoost&#xff08;Adaptive Boosting&#xff0c;自适应提升&#xff09;是一种迭代式的集成学习算法&#xff0c;通过不断调整样本权重&#xff0c;提升弱学习器性能&#xff0c;最终集成为一个强学习器。它继承了 Boosting 的基本思想和关键机制&#xff0c;但在…

《PyTorch documentation》(PyTorch 文档)

PyTorch documentation(PyTorch 文档) PyTorch is an optimized tensor library for deep learning using GPUs and CPUs. (PyTorch是一个优化的张量库,用于使用GPU和CPU进行深度学习。) Features described in this documentation are classified by release status: (此…

Android学习总结之算法篇六(数组和栈)

括号匹配 public static boolean isValid(String s) {// 创建一个栈用于存储左括号Stack<Character> stack new Stack<>();// 遍历字符串中的每个字符for (char c : s.toCharArray()) {if (c ( || c [ || c {) {// 如果是左括号&#xff0c;将其压入栈中stack…

遗传算法(Genetic Algorithm,GA)

遗传算法&#xff08;Genetic Algorithm&#xff0c;GA&#xff09;是一种受生物进化理论启发的优化算法&#xff0c;通过模拟自然选择和遗传机制来搜索复杂问题的最优解。 ​​核心原理​​ ​​自然选择与适者生存​​&#xff1a;适应度高的个体更有可能繁殖&#xff0c;将…

消防应急物资智能调用立库:豪越科技助力消防“速战速决”

在消防救援的战场上&#xff0c;时间就是生命&#xff0c;每一秒都关乎着人民群众的生命财产安全。然而&#xff0c;在过去的紧急救援中&#xff0c;应急物资无法及时到位的情况时有发生&#xff0c;成为制约救援效率的关键难题&#xff0c;给救援工作带来了巨大的困境。 想象一…

【MySQL】数据类型和表的操作

目录 一. 常用的数据类型 1.数值类型 1.1 整形类型 1.2 浮点型类型 2.字符串类型 char和varchar的区别 如何选择char和varchar 3.日期类型 4.二进制类型 二. 表的操作 1.查看所有表 2.表的创建 3.查看表的结构 4.表的修改 4.1 添加新的列 4.2 修改表中现有的列 4…

涨薪技术|0到1学会性能测试第43课-apache status模块监控

前面的推文我们认识了apache目录结构与配置知识,今天我们继续来看下apache监控技术,究竟是怎么做性能监控的。后续文章都会系统分享干货,带大家从0到1学会性能测试。 Apache监控技术 关于apache监控通常会有两种方法: 一是:使用apache自带的status监控模块进行监控; 二是…

关于 MCP 的理论知识学习

文章目录 1. 写在最前面2. 基本概念2.1 Why MCP2.1.1 大模型访问的局限2.1.2 过渡阶段—Function Call2.1.3 当前阶段— MCP 3. 碎碎念4. 参考资料 1. 写在最前面 最近有一项任务是写旧版本迁移到新版本的支持文档&#xff0c;文档的编写是借助于 cursor 帮忙写的。但是实现的…

C++学习之路,从0到精通的征途:List类的模拟实现

目录 一.list的介绍 二.list的接口实现 1.结点 2.list结构 3.迭代器 &#xff08;1&#xff09;begin &#xff08;2&#xff09;end 4.修改 &#xff08;1&#xff09;insert &#xff08;2&#xff09;push_back &#xff08;3&#xff09;push_front &#xff0…

【游戏ai】从强化学习开始自学游戏ai-2 使用IPPO自博弈对抗pongv3环境

文章目录 前言一、环境设计二、动作设计三、状态设计四、神经网路设计五、效果展示其他问题总结 前言 本学期的大作业&#xff0c;要求完成多智能体PPO的乒乓球对抗环境&#xff0c;这里我使用IPPO的方法来实现。 正好之前做过这个单个PPO与pong环境内置的ai对抗的训练&#…

计算机考研精炼 操作系统

第 14 章 操作系统概述 14.1 基本概念 14.1.1 操作系统的基本概念 如图 14 - 1 所示&#xff0c;操作系统是计算机系统中的一个重要组成部分&#xff0c;它位于计算机硬件和用户程序&#xff08;用户&#xff09;之间&#xff0c;负责管理计算机的硬件资源&#xff0c;为用户和…

什么是基尔霍夫第一定律

基尔霍夫第一定律&#xff08;Kirchhoffs First Law&#xff09;&#xff0c;也称为基尔霍夫电流定律&#xff08;Kirchhoffs Current Law&#xff0c;简称 KCL&#xff09;&#xff0c;是电路分析中最基础的定律之一。它描述了电路中电流的守恒特性&#xff0c;适用于任何集总…

解决 RN Switch 组件在安卓端样式很丑的问题

解决此种问题的方式有很多 可以导入原生库react-native-switch 切图 (会缺少动画) 使用 js 组件 这里使用 js 绘制组件&#xff08;原生体验&#xff09;解决此类问题 Switch.tsx import React, { useEffect, useRef, useState } from react; import { Animated, Pressabl…

【AI】【MCP】搭建私人王炸MCP自动化工作流

目录 一、什么是MCP 二、MCP大集合 三、准备工作 3.1 安装node.js 3.2 安装vscode 3.3 安装cline插件 3.3.1 安装 3.3.2 配置Cline 四、配置MCP服务 4.1 Search-mcp服务 4.2 playwright-mcp 服务 前言&#xff1a;梦想组合&#xff0c;轻松办公&#xff0c;告别手动&a…

Git 实操:如何使用交互式 Rebase 移除指定提交(真实案例分享)

在日常开发中&#xff0c;有时候我们提交了一些不想保留的记录&#xff0c;比如测试代码、错误的功能提交等。 ⚠️ 在操作 4. 强制推送到远程仓库前的注意事项 强制推送&#xff08;git push --force 或 git push -f&#xff09;确实很强大但也危险&#xff0c;因为它会重写…

11.Excel:函数

一 函数是什么 函数是定义好的公式。 单元格内输入sum然后tab&#xff0c;框选要求和的范围&#xff0c;然后回车键。 补充&#xff1a;公式。 公式以开头&#xff0c;可以用于计算&#xff0c;返回数值。 分别点击各个数值&#xff0c;中间用加号连接。这样很不方便&#xff…

Springboot使用ThreadLocal提供线程局部变量,传递登录用户名

文章目录 概述使用创建ThreadLocalUtil工具类在登录拦截器中使用ThreadLocal存储登录用户名在/userInfo接口中获取登录用户名 注意事项参考视频 概述 使用 创建ThreadLocalUtil工具类 utils/ThreadLocalUtil.java package org.example.utils;/*** ThreadLocal 工具类*/ Supp…

1399. 统计最大组的数目

1399. 统计最大组的数目 题目链接&#xff1a;1399. 统计最大组的数目 代码如下&#xff1a; class Solution { public:int countLargestGroup(int n) {int res 0;unordered_map<int, int> um;int maxValue 0;for (int i 1;i < n;i) {string value to_string(i);…