当前位置: 首页 > news >正文

windows定时闹钟

特点:会播报当前时间、距离ddl还剩多少时间,避免赖床

import tkinter as tk
from tkinter import ttk, messagebox
import datetime, time, threading, json, os, pyttsx3class AlarmClock:def __init__(self):self.root = tk.Tk()self.root.title("定时闹钟")self.root.geometry("500x400")self.init_voice_engine()self.config_file = "alarm_config.json"self.custom_message = self.load_custom_message()self.target_event = "上班"  # 默认事件名称self.setup_ui()self.alarm_thread = Noneself.voice_thread = Noneself.is_running = Falseself.is_alarming = Falsedef init_voice_engine(self):self.engine = pyttsx3.init()self.engine.setProperty('rate', 150)self.engine.setProperty('volume', 1.0)voices = self.engine.getProperty('voices')for voice in voices:if "chinese" in voice.id.lower():self.engine.setProperty('voice', voice.id)breakdef num_to_chinese(self, num):"""将数字转换为中文"""chinese_numbers = {'0': '零', '1': '一', '2': '二', '3': '三', '4': '四','5': '五', '6': '六', '7': '七', '8': '八', '9': '九', '10': '十'}if num <= 10:return chinese_numbers.get(str(num), str(num))elif num < 20:return f"十{chinese_numbers.get(str(num-10), '')}"elif num < 100:tens = num // 10ones = num % 10if ones == 0:return f"{chinese_numbers.get(str(tens), '')}十"return f"{chinese_numbers.get(str(tens), '')}{chinese_numbers.get(str(ones), '')}"return str(num)def generate_reminder_text(self, target_time):"""生成动态提醒文本"""now = datetime.datetime.now()current_hour = now.hourcurrent_minute = now.minute# 计算剩余时间(分钟)time_diff = target_time - nowremaining_minutes = int(time_diff.total_seconds() / 60)final_time = "2024-11-10 13:30:00"final_time = datetime.datetime.strptime(final_time, "%Y-%m-%d %H:%M:%S")time_diff = final_time - nowremaining_minutes = int(time_diff.total_seconds() / 60)# 生成提醒文本text = f"现在已经{self.num_to_chinese(current_hour)}{self.num_to_chinese(current_minute)}分,"text += f"距离{self.num_to_chinese(final_time.hour)}{self.num_to_chinese(final_time.minute)}{self.target_event}还剩{self.num_to_chinese(remaining_minutes)}分钟"return textdef speak_loop(self, target_time):"""循环播放动态语音"""while self.is_alarming:try:# 生成动态提醒文本reminder_text = self.generate_reminder_text(target_time)# 更新状态显示self.root.after(0, lambda: self.status_var.set(reminder_text))# 播放语音self.engine.say(reminder_text)self.engine.runAndWait()# 等待一段时间再播放下一次time.sleep(2)except Exception as e:print(f"语音播放出错:{str(e)}")time.sleep(1)def start_alarm_sound(self, target_time):"""开始循环播放警报声"""self.is_alarming = Trueself.voice_thread = threading.Thread(target=self.speak_loop, args=(target_time,),daemon=True)self.voice_thread.start()def stop_alarm_sound(self):"""停止警报声"""self.is_alarming = Falseif self.voice_thread:self.voice_thread.join(timeout=2)def load_custom_message(self):if os.path.exists(self.config_file):try:with open(self.config_file, 'r', encoding='utf-8') as f:config = json.load(f)return config.get('target_event', '上班')except:return '上班'return '上班'def save_custom_message(self):with open(self.config_file, 'w', encoding='utf-8') as f:json.dump({'target_event': self.target_event}, f, ensure_ascii=False)def setup_ui(self):# 时间设置框架time_frame = ttk.LabelFrame(self.root, text="目标时间设置", padding="10")time_frame.pack(fill="x", padx=10, pady=5)# 小时选择ttk.Label(time_frame, text="小时:").grid(row=0, column=0, padx=5)self.hour_var = tk.StringVar(value="9")self.hour_spinbox = ttk.Spinbox(time_frame, from_=0, to=23, width=5, textvariable=self.hour_var)self.hour_spinbox.grid(row=0, column=1, padx=5)# 分钟选择ttk.Label(time_frame, text="分钟:").grid(row=0, column=2, padx=5)self.minute_var = tk.StringVar(value="0")self.minute_spinbox = ttk.Spinbox(time_frame, from_=0, to=59, width=5,textvariable=self.minute_var)self.minute_spinbox.grid(row=0, column=3, padx=5)# 事件名称设置event_frame = ttk.LabelFrame(self.root, text="事件设置", padding="10")event_frame.pack(fill="x", padx=10, pady=5)ttk.Label(event_frame, text="事件名称:").pack(side="left", padx=5)self.event_var = tk.StringVar(value=self.target_event)self.event_entry = ttk.Entry(event_frame, textvariable=self.event_var)self.event_entry.pack(side="left", fill="x", expand=True, padx=5)# 测试按钮self.test_button = ttk.Button(self.root, text="测试提示音", command=self.test_voice)self.test_button.pack(pady=5)# 控制按钮button_frame = ttk.Frame(self.root)button_frame.pack(pady=10)self.start_button = ttk.Button(button_frame, text="开始", command=self.start_alarm)self.start_button.pack(side="left", padx=5)self.stop_button = ttk.Button(button_frame, text="停止", command=self.stop_alarm,state="disabled")self.stop_button.pack(side="left", padx=5)# 状态显示self.status_var = tk.StringVar(value="未启动")self.status_label = ttk.Label(self.root, textvariable=self.status_var,wraplength=400)  # 允许文本换行self.status_label.pack(pady=10)# 置顶按钮self.topmost_var = tk.BooleanVar(value=False)self.topmost_check = ttk.Checkbutton(self.root, text="窗口置顶", variable=self.topmost_var,command=self.toggle_topmost)self.topmost_check.pack(pady=5)def toggle_topmost(self):self.root.attributes('-topmost', self.topmost_var.get())def test_voice(self):"""测试语音按钮的回调函数"""try:hours = int(self.hour_var.get())minutes = int(self.minute_var.get())target_time = datetime.datetime.now().replace(hour=hours, minute=minutes)test_text = self.generate_reminder_text(target_time)# 在新线程中播放测试语音threading.Thread(target=lambda: self.engine.say(test_text) or self.engine.runAndWait(),daemon=True).start()except ValueError:messagebox.showerror("错误", "请输入有效的时间!")def start_alarm(self):try:hours = int(self.hour_var.get())minutes = int(self.minute_var.get())if hours < 0 or hours > 23 or minutes < 0 or minutes > 59:messagebox.showerror("错误", "请输入有效的时间!")return# 保存事件名称self.target_event = self.event_var.get()self.save_custom_message()# 计算目标时间target_time = datetime.datetime.now().replace(hour=hours, minute=minutes,second=0, microsecond=0)# 如果目标时间已过,设置为明天if target_time <= datetime.datetime.now():target_time += datetime.timedelta(days=1)self.is_running = Trueself.alarm_thread = threading.Thread(target=self.run_alarm, args=(target_time,))self.alarm_thread.daemon = Trueself.alarm_thread.start()self.start_button.config(state="disabled")self.stop_button.config(state="normal")self.status_var.set(f"闹钟将在 {target_time.strftime('%H:%M')} 响起")except ValueError:messagebox.showerror("错误", "请输入有效的数字!")def stop_alarm(self):self.is_running = Falseself.stop_alarm_sound()self.start_button.config(state="normal")self.stop_button.config(state="disabled")self.status_var.set("已停止")def run_alarm(self, target_time):while self.is_running:now = datetime.datetime.now()if now >= target_time:# 开始循环播放动态警报声self.start_alarm_sound(target_time)breaktime.sleep(1)def run(self):self.root.mainloop()if __name__ == "__main__":alarm = AlarmClock()alarm.run()

http://www.mrgr.cn/news/69651.html

相关文章:

  • Docker 基础命令介绍和常见报错解决
  • Spring框架之责任链模式 (Chain of Responsibility Pattern)
  • leetcode268 丢失的数字
  • 浅谈C#之内存管理
  • 百度富文本禁止编辑
  • 【Linux系统编程】第四十五弹---线程互斥:从问题到解决,深入探索互斥量的原理与实现
  • 丹摩征文活动 |丹摩智算平台:网络安全的守护与挑战
  • 胶囊网络、MobileNet、坐标注意力机制的应用
  • 【大语言模型】ACL2024论文-08 统一的时间知识图谱推理模型:插值与外推
  • 【51单片机输出50ms与200ms方波】
  • [CKS] K8S NetworkPolicy Set Up
  • AI做小红小绿书,自动配图+文案(Coze工作流)
  • 多元正态分布的参数估计1
  • C++ 越来越像函数式编程了!
  • ACL 2024亮点:RAG技术进展与论文解析
  • Js — 节流及底层实现
  • GNN - Transformer 新突破 —— 解锁全局与局部的完美融合!
  • 08_docker网络
  • LeetCode 第 423 场周赛个人题解
  • 全国智能网联招标项目一周速览(2024年11月10日)
  • 基于Spring Boot的计算机课程管理:工程认证的实践
  • WPS Office Excel 转 PDF 后图片丢失的解决方法
  • go桌面框架Fyne最全api文档
  • 释放创作潜力!Flux 模型现已集成至 ComfyUI,快来体验!
  • 2024程序员,转行还是不转行,必须严肃想一想?(一条120W+阅读的讨论)
  • SpringCloudalibaba 集成 Knife4j 的时候出现多余的 前缀