Python小程序:上班该做点摸鱼的事情

news2025/7/14 12:22:14

系统提醒

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

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

# -*- 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()

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

飞云分仓操盘副图指标操作技术图文分解

如上图&#xff0c;副图指标-飞云分仓操盘指标&#xff0c;指标三条线蓝色“首峰线”&#xff0c;红色“引力1”&#xff0c;青色“引力2”&#xff0c;多头行情时“首峰线”和“引力1”之间显示为红色&#xff0c;“引力1”和“引力2”多头是区间颜色显示为紫色。 如上图图标信…

基于vueflow可拖拽元素的示例(基于官网示例的单文件示例)

效果图 代码 <template><div style"width: 100%;height: calc(100vh - 84px)"><VueFlow :nodes"nodes" :edges"edges" drop"onDrop" dragover"onDragOver" dragleave"onDragLeave"><div cl…

【MongoDB篇】MongoDB的副本集操作!

目录 引言第一节&#xff1a;副本集的核心概念&#xff1a;它是什么&#xff1f;为什么需要它&#xff1f;&#x1f914;&#x1f9e0;第二节&#xff1a;副本集的“骨架”&#xff1a;成员与数据同步机制 &#x1f451;&#x1f504;❤️‍&#x1f525;第三节&#xff1a;生死…

Kubernetes 集群优化实战手册:从零到生产级性能调优

一、硬件资源优化策略 1. 节点选型黄金法则 # 生产环境常见节点规格&#xff08;AWS示例&#xff09; - 常规计算型&#xff1a;m5.xlarge (4vCPU 16GB) - 内存优化型&#xff1a;r5.2xlarge (8vCPU 64GB) - GPU加速型&#xff1a;p3.2xlarge (8vCPU V100 GPU)2. 自动扩缩容…

【Redis分布式】主从复制

&#x1f525;个人主页&#xff1a; 中草药 &#x1f525;专栏&#xff1a;【中间件】企业级中间件剖析 一、主从复制 在分布式系统之中为了解决单点问题&#xff08;1、可用性问题&#xff0c;该机器挂掉服务会停止2、性能支持的并发量是有限的&#xff09;通常会把数据复制多…

用递归实现各种排列

为了满足字典序的输出&#xff0c;我采用了逐位递归的方法&#xff08;每一位的所能取到的最小值都大于前一位&#xff09; 1&#xff0c;指数型排列 #include<bits/stdc.h> using ll long long int; using namespace std; int a[10];void printp(int m) {for (int h …

测试用例介绍

文章目录 一、测试用例基本概念1.1 测试用例基本要素 二、测试用例的设计方法2.1 基于需求的设计方法2.2 等价类2.3 边界值2.4 错误猜测法2.6 场景设计法2.7 因果图2.5 正交排列 三、综合&#xff1a;根据某个场景去设计测试用例&#xff08;万能公式&#xff09;四、如何使用F…

phpstudy升级新版apache

1.首先下载要升级到的apache版本&#xff0c;这里apache版本为Apache 2.4.63-250207 Win64下载地址&#xff1a;Apache VS17 binaries and modules download 2.将phpstudy中原始apache复制备份Apache2.4.39_origin 3.将1中下载apache解压&#xff0c; 将Apache24复制一份到ph…

React Native基础环境配置

React Native基础环境配置 1.引言2.React-Native简介3.项目基础环境搭建1.引言 感觉自己掌握的知识面还是有点太窄了,于是决定看看移动端的框架,搞个react搭一个后端管理项目,然后拿react-native写个小的软件,试着找个三方上架一下应用市场玩玩。毕竟不可能一直在简历上挂一…

【Linux修炼手册】Linux开发工具的使用(一):yum与vim

文章目录 一、Linux 软件包管理器——yum安装与卸载的使用方法查看软件包 二、Linux编辑器——vimvim命名模式常用指令底行模式常用指令 一、Linux 软件包管理器——yum Linux安装软件的方式有3种&#xff1a; 源代码安装——成本极高rmp安装——具有安装依赖、安装源、安装版…

如何查看电脑显卡配置参数 一文读懂

显卡是电脑的重要硬件之一&#xff0c;尤其对于游戏玩家、设计师、视频编辑等用户来说&#xff0c;显卡的性能直接影响电脑的使用体验。如果您想知道电脑的显卡信息&#xff0c;或者打算升级显卡&#xff0c;那么了解如何查看显卡配置是非常必要的。本文将为您提供多种简单实用…

spring中的@ComponentScan注解详解

ComponentScan 是 Spring 框架中用于自动扫描并注册组件的核心注解&#xff0c;它简化了 Spring 应用中 Bean 的发现和装配流程。以下从核心功能、属性解析、使用场景及示例等方面进行详细说明。 一、核心功能与作用 自动扫描组件 ComponentScan 会扫描指定包及其子包下的类&am…

深入剖析 I/O 复用之 select 机制

深入剖析 I/O 复用之 select 机制 在网络编程中&#xff0c;I/O 复用是一项关键技术&#xff0c;它允许程序同时监控多个文件描述符的状态变化&#xff0c;从而高效地处理多个 I/O 操作。select 作为 I/O 复用的经典实现方式&#xff0c;在众多网络应用中扮演着重要角色。本文…

SpringBoot指定项目层日志记录

1、新建一个Springboot项目&#xff0c;添加Lombok依赖&#xff08;注意&#xff1a;这里使用的Lombok下的Slf4j快速日志记录方式&#xff09; <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependenc…

RISC-V hardfault分析工具,RTTHREAD-RVBACKTRACE

RV BACKTRACE 简介 本文主要讲述RV BACKTRACE 的内部主要原理 没有接触过rvbacktrace可以看下面两篇文章&#xff0c;理解一下如何使用RVBACKTRACE RVBacktrace RISC-V极简栈回溯组件&#xff1a;https://club.rt-thread.org/ask/article/64bfe06feb7b3e29.html RVBacktra…

matlab 中function的用法

matlab 中function的用法 前言介绍1. 基本语法示例&#xff08;1&#xff09;可以直接输出&#xff08;2&#xff09;调用函数 2.输入参数和输出参数示例多输入参数和输出参数定义一个函数&#xff0c;计算两个数的和与差&#xff1a;调用该函数&#xff1a; 3. 默认参数示例 4…

解锁 LLM 推理速度:深入 FlashAttention 与 PagedAttention 的原理与实践

写在前面 大型语言模型 (LLM) 已经渗透到我们数字生活的方方面面,从智能问答、内容创作到代码辅助,其能力令人惊叹。然而,驱动这些强大模型的背后,是对计算资源(尤其是 GPU)的巨大需求。在模型推理 (Inference) 阶段,即模型实际对外提供服务的阶段,速度 (Latency) 和吞…

4个纯CSS自定义的简单而优雅的滚动条样式

今天发现 uni-app 项目的滚动条不显示&#xff0c;查了下原来是设置了 ::-webkit-scrollbar {display: none; } 那么怎么用 css 设置滚动条样式呢&#xff1f; 定义滚动条整体样式‌ ::-webkit-scrollbar 定义滚动条滑块样式 ::-webkit-scrollbar-thumb 定义滚动条轨道样式‌…

查看jdk是否安装并且配置成功?(Android studio安装前的准备)

WinR输入cmd打开命令提示窗口 输入命令 java -version 回车显示如下&#xff1a;

5月8日直播见!Atlassian Team‘25大会精华+AI实战分享

在刚刚落幕的 Atlassian Team’25 全球大会上&#xff0c;Atlassian发布了多项重磅创新&#xff0c;全面升级其协作平台&#xff0c;涵盖从Al驱动、知识管理到跨团队协作&#xff0c;再到战略执行的各个方面。 为帮助中国用户深入了解这些前沿动态&#xff0c;Atlassian全球白…