【Python】2026动态文字壁纸,一键让你的桌面加上烟花效果和今日任务事项
🌹欢迎来到《小5讲堂》🌹
🌹这是《Python》系列文章,每篇文章将以博主理解的角度展开讲解。🌹
🌹温馨提示:博主能力有限,理解水平有限,若有不对之处望指正!🌹

目录
前言
在上篇python文章中,实现了如何在windows当前桌面壁纸情况下加上动态效果。
本篇文章来升级下,优化为显示烟花效果,以及可动态添加今日需要完成的任务事项信息。
效果


实现过程
将动态烟花效果与任务管理功能相结合,在桌面背景上展示绚丽的烟花动画和任务信息。
一、技术架构概览
1.1 核心技术栈
- 界面框架: tkinter (GUI控制面板) - 系统交互: pywin32 (Windows API调用) - 图像处理: Pillow (图像生成与处理) - 粒子系统: 自定义烟花粒子引擎 - 数据持久化: JSON文件存储 - 动画引擎: 基于时间的粒子系统 1.2 程序结构
FireworkWallpaper类 ├── 核心组件 │ ├── FireworkParticle (烟花粒子类) │ ├── Firework (烟花类) │ └── TaskItem (任务项类) ├── 初始化模块 (__init__) ├── 用户界面模块 (setup_ui) ├── 任务管理模块 │ ├── load_tasks / save_tasks │ ├── add_task / delete_task │ └── update_task_listbox ├── 壁纸控制模块 │ ├── start_firework_wallpaper │ ├── stop_wallpaper │ └── start_animation_loop ├── 动画渲染模块 │ ├── animate (主循环) │ ├── update_fireworks (烟花系统) │ ├── draw_tasks (任务绘制) │ └── draw_date_info (日期绘制) └── 工具函数模块 ├── launch_firework └── start_preview_animation 二、详细实现步骤分析
2.1 核心类设计
步骤1:烟花粒子系统设计
classFireworkParticle:"""基础粒子单元,实现物理运动效果"""def__init__(self, x, y, color, velocity_x, velocity_y, life_time, gravity=0.1): self.x = x # X坐标 self.y = y # Y坐标 self.color = color # 粒子颜色(RGB) self.velocity_x = velocity_x # X轴速度 self.velocity_y = velocity_y # Y轴速度 self.life_time = life_time # 生命周期 self.age =0# 已存活时间 self.gravity = gravity # 重力加速度 self.size = random.uniform(1.5,3.0)# 随机大小 self.alpha =255# 透明度(0-255)粒子物理系统实现:
defupdate(self, delta_time):"""更新粒子状态 - 模拟物理运动""" self.age += delta_time self.velocity_y += self.gravity # 重力影响 self.x += self.velocity_x self.y += self.velocity_y # 透明度衰减:生命周期越接近结束越透明 progress = self.age / self.life_time self.alpha =int(255*(1- progress))return self.age < self.life_time # 返回是否存活步骤2:烟花类设计
classFirework:"""完整烟花对象,包含上升、爆炸、消散三个阶段"""def__init__(self, x, y, color, explosion_height, particle_count=80): self.state ="rising"# 状态机:rising, exploding, done self.velocity_y =-random.uniform(8,12)# 上升速度 self.particles =[]# 爆炸后的粒子集合 self.creation_time = time.time()# 创建时间戳烟花状态机实现:
defupdate(self, delta_time):"""烟花状态机更新"""if self.state =="rising":# 上升阶段 self.y += self.velocity_y if self.y <= self.explosion_height:# 到达爆炸高度 self.explode()# 触发爆炸 self.state ="exploding"elif self.state =="exploding":# 爆炸阶段# 更新所有粒子 alive_particles =[]for particle in self.particles:if particle.update(delta_time): alive_particles.append(particle) self.particles = alive_particles # 检查结束条件ifnot self.particles and time.time()- self.creation_time >3: self.state ="done"# 进入完成状态return self.state !="done"# 返回是否活跃步骤3:爆炸效果算法
defexplode(self):"""烟花爆炸效果 - 生成放射状粒子"""for _ inrange(self.particle_count): angle = random.uniform(0,2* math.pi)# 随机角度 speed = random.uniform(3,8)# 随机速度 velocity_x = math.cos(angle)* speed # X方向分量 velocity_y = math.sin(angle)* speed # Y方向分量 life_time = random.uniform(1.5,3.0)# 随机生命周期# 颜色微调,增加视觉效果 color_variation = random.randint(-30,30) r =max(0,min(255, self.color[0]+ color_variation)) g =max(0,min(255, self.color[1]+ color_variation)) b =max(0,min(255, self.color[2]+ color_variation)) particle = FireworkParticle( self.x, self.y,(r, g, b), velocity_x, velocity_y, life_time ) self.particles.append(particle)步骤4:任务项设计
classTaskItem:"""任务数据模型,支持JSON序列化"""def__init__(self, text, completed=False, created_time=None): self.text = text self.completed = completed self.created_time = created_time or datetime.now()defto_dict(self):"""转换为字典,用于JSON序列化"""return{"text": self.text,"completed": self.completed,"created_time": self.created_time.isoformat()}@classmethoddeffrom_dict(cls, data):"""从字典重建对象,用于JSON反序列化"""return cls( text=data["text"], completed=data["completed"], created_time=datetime.fromisoformat(data["created_time"]))2.2 系统初始化
步骤5:主程序初始化
classFireworkWallpaper:def__init__(self):# 1. 创建主窗口 self.root = tk.Tk() self.root.title("烟花任务壁纸") self.root.geometry("800x600")# 2. 获取屏幕分辨率 self.screen_width = self.root.winfo_screenwidth() self.screen_height = self.root.winfo_screenheight()# 3. 烟花系统初始化 self.fireworks =[]# 活跃烟花列表 self.last_firework_time =0 self.firework_interval =2.0# 发射间隔(秒)# 4. 颜色预设 self.firework_colors =[(255,107,107),# 红色(78,205,196),# 青色(255,234,167),# 黄色# ... 更多颜色]# 5. 数据持久化设置 self.tasks_file = os.path.join(os.path.dirname(__file__),"tasks.json") self.load_tasks()# 加载已有任务2.3 用户界面设计
步骤6:界面布局
defsetup_ui(self):"""创建双栏式布局界面"""# 深色主题设计 self.root.configure(bg='#1a1a2e')# 深蓝色背景# 左侧:控制面板 left_frame = tk.Frame(main_frame, bg="#16213e") left_frame.pack(side="left", fill="both", expand=True)# 右侧:预览和控制面板 right_frame = tk.Frame(main_frame, bg="#16213e") right_frame.pack(side="right", fill="both", expand=True)任务管理系统界面:
# 任务输入系统 self.task_entry = tk.Entry(...) self.task_entry.bind("<Return>",lambda e: self.add_task())# 回车键绑定# 任务列表显示 self.task_listbox = tk.Listbox(...) self.update_task_listbox()# 更新显示# 任务操作按钮组 task_buttons_frame = tk.Frame(...) tk.Button(..., text="标记完成", command=self.mark_task_completed) tk.Button(..., text="删除", command=self.delete_task) tk.Button(..., text="清空", command=self.clear_tasks)步骤7:数据持久化
defload_tasks(self):"""从JSON文件加载任务数据"""try:if os.path.exists(self.tasks_file):withopen(self.tasks_file,'r', encoding='utf-8')as f: data = json.load(f) self.tasks =[TaskItem.from_dict(item)for item in data]except Exception as e:print(f"加载任务失败: {e}") self.tasks =[]defsave_tasks(self):"""保存任务数据到JSON文件"""try: data =[task.to_dict()for task in self.tasks]withopen(self.tasks_file,'w', encoding='utf-8')as f: json.dump(data, f, ensure_ascii=False, indent=2)except Exception as e:print(f"保存任务失败: {e}")步骤8:任务管理功能
defadd_task(self):"""添加新任务""" text = self.task_entry.get().strip()if text: task = TaskItem(text)# 创建任务对象 self.tasks.append(task) self.task_entry.delete(0, tk.END)# 清空输入框 self.update_task_listbox() self.save_tasks()# 自动保存defmark_task_completed(self):"""切换任务完成状态""" selection = self.task_listbox.curselection()if selection: index = selection[0] self.tasks[index].completed =not self.tasks[index].completed self.update_task_listbox() self.save_tasks()2.4 壁纸渲染系统
步骤9:壁纸启动流程
defstart_firework_wallpaper(self):"""启动壁纸渲染"""# 1. 防止重复启动if self.is_running:return# 2. 加载背景壁纸 self.wallpaper_image = Image.open(wallpaper_path).convert('RGBA') self.wallpaper_image = self.wallpaper_image.resize((self.screen_width, self.screen_height), Image.Resampling.LANCZOS # 高质量缩放)# 3. 预加载字体(性能优化) self.title_font = ImageFont.truetype("msyh.ttc",80)# 标题字体 self.task_font = ImageFont.truetype("msyh.ttc",24)# 任务字体 self.date_font = ImageFont.truetype("msyh.ttc",36)# 日期字体# 4. 启动动画循环 self.is_running =True self.root.after(100, self.start_animation_loop)步骤10:动画主循环
defanimate(self):"""动画渲染主循环"""ifnot self.is_running:returntry: current_time = time.time() delta_time = current_time - self.last_update_time # 帧率控制:约15FPSif current_time - self.last_update_time <0.066: self.root.after(10, self.animate)return self.last_update_time = current_time self.frame_count +=1# 创建新图像画布 composite_image = self.wallpaper_image.copy() draw = ImageDraw.Draw(composite_image)# 分层渲染if self.effects['fireworks']: self.update_fireworks(draw, current_time, delta_time)if self.effects['tasks_display']: self.draw_tasks(draw, current_time)if self.effects['date_display']: self.draw_date_info(draw, current_time)# 性能优化:选择性更新壁纸 update_wallpaper =Falseifnothasattr(self,'last_wallpaper_time'): update_wallpaper =Trueelif current_time - self.last_wallpaper_time >0.3: update_wallpaper =Trueelif self.frame_count %3==0: update_wallpaper =Trueif update_wallpaper:# 保存并设置壁纸 composite_image.convert('RGB').save("temp_wallpaper.bmp",'BMP') ctypes.windll.user32.SystemParametersInfoW(20,0, temp_path,0) self.last_wallpaper_time = current_time finally:# 安排下一帧 self.root.after(10, self.animate)2.5 烟花系统实现
步骤11:烟花发射控制
deflaunch_firework(self):"""发射新烟花"""# 随机发射位置 x = random.randint(100, self.screen_width -100) y = self.screen_height +50# 从屏幕底部开始# 随机参数 color = random.choice(self.firework_colors) explosion_height = random.randint(100, self.screen_height //2)# 创建烟花对象 firework = Firework(x, y, color, explosion_height) self.fireworks.append(firework)步骤12:烟花系统更新
defupdate_fireworks(self, draw, current_time, delta_time):"""更新所有烟花状态"""# 发射新烟花(概率控制)if current_time - self.last_firework_time > self.firework_interval:if random.random()<0.7:# 70%概率发射 self.launch_firework() self.last_firework_time = current_time # 更新现有烟花 alive_fireworks =[]for firework in self.fireworks:if firework.update(delta_time):# 更新状态 alive_fireworks.append(firework) firework.draw(draw)# 绘制烟花 self.fireworks = alive_fireworks 2.6 信息显示系统
步骤13:任务信息渲染
defdraw_tasks(self, draw, current_time):"""在壁纸上渲染任务列表"""ifnot self.tasks:return# 定位到右上角 start_x = self.screen_width -400 start_y =150# 绘制标题 draw.text((start_x, start_y),"今日任务", fill=(233,69,96,255),# 红色系 font=self.title_font )# 绘制每个任务for i, task inenumerate(self.tasks): y_pos = start_y +100+ i *40# 状态图标和颜色 status_icon ="✓"if task.completed else"○" status_color =(149,165,166,255)if task.completed else(233,69,96,255) draw.text((start_x, y_pos), status_icon, fill=status_color, font=self.task_font)# 任务文本(已完成变灰色) text_color =(149,165,166,255)if task.completed else(255,255,255,255) draw.text((start_x +40, y_pos), task.text, fill=text_color, font=self.task_font)步骤14:日期时间渲染
defdraw_date_info(self, draw, current_time):"""渲染日期和时间信息""" now = datetime.now()# 左上角:日期和星期 draw.text((50,100), now.strftime("%Y年%m月%d日"), fill=(233,69,96,255), font=self.date_font) draw.text((50,150), now.strftime("星期%w").replace("星期0","星期日"), fill=(255,255,255,255), font=self.date_font)# 右下角:实时时间 time_text = now.strftime("%H:%M:%S")# 计算文字尺寸进行精确定位 bbox = draw.textbbox((0,0), time_text, font=self.date_font) text_width = bbox[2]- bbox[0] text_height = bbox[3]- bbox[1] time_x = self.screen_width - text_width -50# 距离右边50像素 time_y = self.screen_height - text_height -50# 距离底部50像素 draw.text((time_x, time_y), time_text, fill=(78,205,196,255), font=self.date_font)2.7 性能优化策略
优化1:动态烟花数量控制
# 通过发射间隔和概率控制烟花密度 self.firework_interval =2.0# 每2秒考虑发射一次if random.random()<0.7:# 70%发射概率 self.launch_firework()优化2:选择性壁纸更新
# 降低壁纸文件写入频率,避免系统负载过高 update_wallpaper =Falseif current_time - self.last_wallpaper_time >0.3:# 至少间隔0.3秒 update_wallpaper =Trueelif self.frame_count %3==0:# 每3帧强制更新一次 update_wallpaper =True优化3:字体对象缓存
# 预加载字体,避免每次渲染重新加载try: self.title_font = ImageFont.truetype("msyh.ttc",80) self.task_font = ImageFont.truetype("msyh.ttc",24) self.date_font = ImageFont.truetype("msyh.ttc",36)except:# 备用方案 self.title_font = ImageFont.load_default()2.8 用户体验特性
特性1:实时预览功能
defstart_preview_animation(self):"""在控制面板中显示动画预览"""defanimate(): self.preview_canvas.delete("all")# 绘制示例烟花效果 self.preview_canvas.create_oval(140,150,160,170, fill="#e94560")# 绘制爆炸粒子for i inrange(8): angle = i * math.pi /4 x =150+30* math.cos(angle) y =100+30* math.sin(angle) self.preview_canvas.create_oval(x-3, y-3, x+3, y+3, fill="#ffd700") self.root.after(2000, animate)# 2秒循环 animate()特性2:键盘快捷键
# 回车键快速添加任务 self.task_entry.bind("<Return>",lambda e: self.add_task())特性3:数据自动保存
# 每次任务操作后自动保存defadd_task(self):# ... 添加任务逻辑 self.save_tasks()# 自动保存到文件defmark_task_completed(self):# ... 标记完成逻辑 self.save_tasks()# 自动保存到文件三、关键技术要点总结
3.1 粒子系统核心算法
- 物理模拟:重力、速度、生命周期
- 状态管理:烟花三阶段状态机
- 随机化:位置、颜色、速度、生命周期的随机变化
- 透明度衰减:基于生命周期的平滑渐变
3.2 渲染优化策略
- 分层渲染:背景、烟花、任务、日期分层处理
- 选择性更新:智能控制壁纸更新频率
- 资源缓存:字体、图像的预加载和重用
- 性能监控:根据帧率动态调整效果
3.3 用户体验设计
- 视觉层次:深色主题配合鲜艳烟花颜色
- 交互反馈:任务状态的视觉区分
- 数据持久化:自动保存和恢复用户任务
- 实时预览:控制面板中的效果预览
四、系统特色功能
- 烟花与任务结合:完成任务时观看烟花,增加成就感
- 完全自定义:所有效果均可单独开关
- 智能性能调节:根据系统负载动态调整效果
- 离线工作:不需要网络连接,所有数据本地存储
- 多信息显示:日期、时间、任务一体化的信息展示
完整代码
启动前,可以先按钮相关库,创建 requirements.txt 文件:
pywin32>=305 Pillow>=10.0.0 安装依赖:
pip install -r requirements.txt 完整python代码
import tkinter as tk from tkinter import messagebox, simpledialog, font import win32api import win32con import win32gui import sys import os import time import math import json from datetime import datetime, timedelta from threading import Thread from PIL import Image, ImageDraw, ImageFont, ImageTk import ctypes import random classFireworkParticle:"""烟花粒子类"""def__init__(self, x, y, color, velocity_x, velocity_y, life_time, gravity=0.1): self.x = x self.y = y self.color = color self.velocity_x = velocity_x self.velocity_y = velocity_y self.life_time = life_time self.age =0 self.gravity = gravity self.size = random.uniform(1.5,3.0) self.alpha =255defupdate(self, delta_time):"""更新粒子状态""" self.age += delta_time self.velocity_y += self.gravity self.x += self.velocity_x self.y += self.velocity_y # 计算透明度衰减 progress = self.age / self.life_time self.alpha =int(255*(1- progress))return self.age < self.life_time defdraw(self, draw):"""绘制粒子"""if self.alpha >0: r, g, b = self.color draw.ellipse([self.x - self.size, self.y - self.size, self.x + self.size, self.y + self.size], fill=(r, g, b, self.alpha))classFirework:"""烟花类"""def__init__(self, x, y, color, explosion_height, particle_count=80): self.x = x self.y = y self.color = color self.explosion_height = explosion_height self.particle_count = particle_count self.state ="rising"# rising, exploding, done self.velocity_y =-random.uniform(8,12) self.particles =[] self.creation_time = time.time()defupdate(self, delta_time):"""更新烟花状态"""if self.state =="rising": self.y += self.velocity_y if self.y <= self.explosion_height: self.explode() self.state ="exploding"elif self.state =="exploding":# 更新所有粒子 alive_particles =[]for particle in self.particles:if particle.update(delta_time): alive_particles.append(particle) self.particles = alive_particles # 检查是否所有粒子都消失了ifnot self.particles and time.time()- self.creation_time >3: self.state ="done"return self.state !="done"defexplode(self):"""烟花爆炸"""# 生成爆炸粒子for _ inrange(self.particle_count): angle = random.uniform(0,2* math.pi) speed = random.uniform(3,8) velocity_x = math.cos(angle)* speed velocity_y = math.sin(angle)* speed life_time = random.uniform(1.5,3.0)# 添加一些颜色变化 color_variation = random.randint(-30,30) r =max(0,min(255, self.color[0]+ color_variation)) g =max(0,min(255, self.color[1]+ color_variation)) b =max(0,min(255, self.color[2]+ color_variation)) particle = FireworkParticle( self.x, self.y,(r, g, b), velocity_x, velocity_y, life_time ) self.particles.append(particle)defdraw(self, draw):"""绘制烟花"""if self.state =="rising":# 绘制上升的烟花轨迹 trail_length =20for i inrange(trail_length): alpha =int(255*(1- i / trail_length)) size =max(1,3- i *0.1) draw.ellipse([self.x - size, self.y + i *2- size, self.x + size, self.y + i *2+ size], fill=(*self.color, alpha))elif self.state =="exploding":# 绘制所有粒子for particle in self.particles: particle.draw(draw)classTaskItem:"""任务事项类"""def__init__(self, text, completed=False, created_time=None): self.text = text self.completed = completed self.created_time = created_time or datetime.now()defto_dict(self):"""转换为字典"""return{"text": self.text,"completed": self.completed,"created_time": self.created_time.isoformat()}@classmethoddeffrom_dict(cls, data):"""从字典创建"""return cls( text=data["text"], completed=data["completed"], created_time=datetime.fromisoformat(data["created_time"]))classFireworkWallpaper:def__init__(self): self.root = tk.Tk() self.root.title("烟花任务壁纸") self.root.geometry("800x600")# 获取屏幕尺寸 self.screen_width = self.root.winfo_screenwidth() self.screen_height = self.root.winfo_screenheight()# 壁纸句柄和状态控制 self.wallpaper_hwnd =None self.is_running =False# 烟花系统 self.fireworks =[] self.last_firework_time =0 self.firework_interval =2.0# 烟花发射间隔(秒)# 任务系统 self.tasks =[] self.tasks_file = os.path.join(os.path.dirname(__file__),"tasks.json") self.load_tasks()# 效果设置 self.effects ={'fireworks':True,'tasks_display':True,'date_display':True,'glow_effects':True}# 烟花颜色预设 self.firework_colors =[(255,107,107),# 红色(78,205,196),# 青色(255,234,167),# 黄色(198,108,132),# 粉色(86,98,246),# 蓝色(255,159,28),# 橙色(156,39,176),# 紫色] self.setup_ui()defsetup_ui(self):"""设置用户界面"""# 设置窗口样式 self.root.configure(bg='#1a1a2e')# 标题 title = tk.Label( self.root, text="🎆 烟花任务壁纸系统", font=("微软雅黑",24,"bold"), fg="#e94560", bg="#1a1a2e") title.pack(pady=20)# 主容器 main_frame = tk.Frame(self.root, bg="#16213e") main_frame.pack(fill="both", expand=True, padx=20, pady=10)# 左侧:效果控制 left_frame = tk.Frame(main_frame, bg="#16213e") left_frame.pack(side="left", fill="both", expand=True, padx=(0,10))# 效果设置 effects_frame = tk.LabelFrame( left_frame, text="🎨 效果设置", font=("微软雅黑",12,"bold"), fg="#0f3460", bg="#16213e", padx=10, pady=10) effects_frame.pack(fill="x", pady=5) self.effect_vars ={}for effect, enabled in self.effects.items(): var = tk.BooleanVar(value=enabled) self.effect_vars[effect]= var effect_name ={'fireworks':'烟花效果','tasks_display':'任务显示','date_display':'日期显示','glow_effects':'发光效果'}[effect] cb = tk.Checkbutton( effects_frame, text=effect_name, variable=var, font=("微软雅黑",10), fg="#e94560", bg="#16213e", selectcolor="#1a1a2e", activebackground="#16213e", activeforeground="#e94560") cb.pack(anchor="w", pady=2)# 任务管理 tasks_frame = tk.LabelFrame( left_frame, text="📝 任务管理", font=("微软雅黑",12,"bold"), fg="#0f3460", bg="#16213e", padx=10, pady=10) tasks_frame.pack(fill="both", expand=True, pady=5)# 任务输入框 task_input_frame = tk.Frame(tasks_frame, bg="#16213e") task_input_frame.pack(fill="x", pady=5) self.task_entry = tk.Entry( task_input_frame, font=("微软雅黑",10), bg="#0f3460", fg="white", insertbackground="white") self.task_entry.pack(side="left", fill="x", expand=True, padx=(0,5)) self.task_entry.bind("<Return>",lambda e: self.add_task()) tk.Button( task_input_frame, text="添加", command=self.add_task, font=("微软雅黑",9), bg="#e94560", fg="white", relief="flat").pack(side="right")# 任务列表 self.task_listbox = tk.Listbox( tasks_frame, font=("微软雅黑",10), bg="#0f3460", fg="white", selectbackground="#e94560", selectforeground="white", height=8) self.task_listbox.pack(fill="both", expand=True, pady=5) self.update_task_listbox()# 任务操作按钮 task_buttons_frame = tk.Frame(tasks_frame, bg="#16213e") task_buttons_frame.pack(fill="x") tk.Button( task_buttons_frame, text="标记完成", command=self.mark_task_completed, font=("微软雅黑",9), bg="#27ae60", fg="white", relief="flat").pack(side="left", padx=2) tk.Button( task_buttons_frame, text="删除", command=self.delete_task, font=("微软雅黑",9), bg="#e74c3c", fg="white", relief="flat").pack(side="left", padx=2) tk.Button( task_buttons_frame, text="清空", command=self.clear_tasks, font=("微软雅黑",9), bg="#f39c12", fg="white", relief="flat").pack(side="left", padx=2)# 右侧:预览和控制 right_frame = tk.Frame(main_frame, bg="#16213e") right_frame.pack(side="right", fill="both", expand=True, padx=(10,0))# 预览区域 preview_frame = tk.LabelFrame( right_frame, text="👁️ 效果预览", font=("微软雅黑",12,"bold"), fg="#0f3460", bg="#16213e", padx=10, pady=10) preview_frame.pack(fill="both", expand=True, pady=5)# 预览画布 self.preview_canvas = tk.Canvas( preview_frame, width=300, height=200, bg="#0f3460", highlightthickness=0) self.preview_canvas.pack(fill="both", expand=True)# 控制按钮 control_frame = tk.Frame(right_frame, bg="#16213e") control_frame.pack(fill="x", pady=10) tk.Button( control_frame, text="🎆 启动烟花壁纸", command=self.start_firework_wallpaper, font=("微软雅黑",12,"bold"), bg="#e94560", fg="white", padx=20, pady=10, relief="flat", cursor="hand2").pack(fill="x", pady=5) tk.Button( control_frame, text="停止壁纸", command=self.stop_wallpaper, font=("微软雅黑",11), bg="#e74c3c", fg="white", padx=20, pady=8, relief="flat", cursor="hand2").pack(fill="x", pady=2)# 状态显示 self.status_label = tk.Label( control_frame, text="就绪", font=("微软雅黑",10), fg="#95a5a6", bg="#16213e") self.status_label.pack(pady=5)# 说明文字 info_text ="""使用说明: • 添加今日任务事项,壁纸上会显示 • 烟花效果会自动随机发射 • 启动后可以最小化此窗口 • 任务数据会自动保存""" info = tk.Label( control_frame, text=info_text, font=("微软雅黑",9), fg="#bdc3c7", bg="#16213e", justify="left") info.pack(pady=10)# 绑定关闭事件 self.root.protocol("WM_DELETE_WINDOW", self.on_closing)# 启动预览动画 self.start_preview_animation()defstart_preview_animation(self):"""启动预览动画"""defanimate(): self.preview_canvas.delete("all")# 绘制背景 self.preview_canvas.create_rectangle(0,0,300,200, fill="#0f3460", outline="")# 绘制示例烟花 current_time = time.time()# 绘制上升的烟花 self.preview_canvas.create_oval(140,150,160,170, fill="#e94560", outline="")# 绘制爆炸效果for i inrange(8): angle = i * math.pi /4 x =150+30* math.cos(angle) y =100+30* math.sin(angle) self.preview_canvas.create_oval(x-3, y-3, x+3, y+3, fill="#ffd700", outline="")# 绘制示例任务 self.preview_canvas.create_text(150,50, text="今日任务预览", fill="white", font=("微软雅黑",10)) self.root.after(2000, animate) animate()defload_tasks(self):"""加载任务数据"""try:if os.path.exists(self.tasks_file):withopen(self.tasks_file,'r', encoding='utf-8')as f: data = json.load(f) self.tasks =[TaskItem.from_dict(item)for item in data]except Exception as e:print(f"加载任务失败: {e}") self.tasks =[]defsave_tasks(self):"""保存任务数据"""try: data =[task.to_dict()for task in self.tasks]withopen(self.tasks_file,'w', encoding='utf-8')as f: json.dump(data, f, ensure_ascii=False, indent=2)except Exception as e:print(f"保存任务失败: {e}")defadd_task(self):"""添加任务""" text = self.task_entry.get().strip()if text: task = TaskItem(text) self.tasks.append(task) self.task_entry.delete(0, tk.END) self.update_task_listbox() self.save_tasks()defmark_task_completed(self):"""标记任务为完成""" selection = self.task_listbox.curselection()if selection: index = selection[0] self.tasks[index].completed =not self.tasks[index].completed self.update_task_listbox() self.save_tasks()defdelete_task(self):"""删除任务""" selection = self.task_listbox.curselection()if selection: index = selection[0] self.tasks.pop(index) self.update_task_listbox() self.save_tasks()defclear_tasks(self):"""清空所有任务"""if messagebox.askyesno("确认","确定要清空所有任务吗?"): self.tasks =[] self.update_task_listbox() self.save_tasks()defupdate_task_listbox(self):"""更新任务列表显示""" self.task_listbox.delete(0, tk.END)for task in self.tasks: status ="✓"if task.completed else"○" display_text =f"{status}{task.text}" self.task_listbox.insert(tk.END, display_text)# 设置完成任务的样式if task.completed: self.task_listbox.itemconfig(tk.END,{'fg':'#95a5a6'})defstart_firework_wallpaper(self):"""启动烟花壁纸"""if self.is_running: self.status_label.config(text="壁纸已在运行", fg="#f39c12")return# 更新效果设置for effect, var in self.effect_vars.items(): self.effects[effect]= var.get()# 预加载和初始化 self.status_label.config(text="正在初始化...", fg="#f39c12") self.root.update()# 加载壁纸图片 wallpaper_path =r"C:\Users\Administrator\Pictures\bing_wallpapers\bing_wallpaper_20251224_130106.jpg"try: self.wallpaper_image = Image.open(wallpaper_path).convert('RGBA') self.wallpaper_image = self.wallpaper_image.resize((self.screen_width, self.screen_height), Image.Resampling.LANCZOS)except Exception as e: self.status_label.config(text=f"加载壁纸失败: {str(e)}", fg="#e74c3c")return# 预加载字体try: self.title_font = ImageFont.truetype("C:\\Windows\\Fonts\\msyh.ttc",80) self.task_font = ImageFont.truetype("C:\\Windows\\Fonts\\msyh.ttc",24) self.date_font = ImageFont.truetype("C:\\Windows\\Fonts\\msyh.ttc",36)except:# 备用字体 self.title_font = ImageFont.load_default() self.task_font = ImageFont.load_default() self.date_font = ImageFont.load_default()# 初始化动画状态 self.animation_start_time = time.time() self.last_update_time =0 self.frame_count =0 self.fireworks =[] self.last_firework_time =0# 设置运行状态 self.is_running =True# 延迟启动动画循环 self.root.after(100, self.start_animation_loop) self.status_label.config(text="烟花壁纸已启动", fg="#2ecc71")defstart_animation_loop(self):"""启动动画循环"""if self.is_running: self.animate()defanimate(self):"""执行动画循环"""ifnot self.is_running ornothasattr(self,'wallpaper_image'):returntry: current_time = time.time() delta_time = current_time - self.last_update_time ifhasattr(self,'last_update_time')else0.016# 限制更新频率(约15FPS)ifhasattr(self,'last_update_time')and current_time - self.last_update_time <0.066: self.root.after(10, self.animate)return self.last_update_time = current_time self.frame_count +=1# 复制壁纸图像作为基础 composite_image = self.wallpaper_image.copy() draw = ImageDraw.Draw(composite_image)# 更新和绘制烟花if self.effects['fireworks']: self.update_fireworks(draw, current_time, delta_time)# 绘制任务信息if self.effects['tasks_display']: self.draw_tasks(draw, current_time)# 绘制日期信息if self.effects['date_display']: self.draw_date_info(draw, current_time)# 保存并设置壁纸 temp_wallpaper_path = os.path.join(os.path.dirname(__file__),"temp_wallpaper.bmp")# 性能优化:降低壁纸更新频率 update_wallpaper =Falseifnothasattr(self,'last_wallpaper_time'): update_wallpaper =Trueelif current_time - self.last_wallpaper_time >0.3: update_wallpaper =Trueelif self.frame_count %3==0: update_wallpaper =Trueif update_wallpaper: composite_image.convert('RGB').save(temp_wallpaper_path,'BMP') ctypes.windll.user32.SystemParametersInfoW(20,0, temp_wallpaper_path,0) self.last_wallpaper_time = current_time except Exception as e:print(f"设置壁纸时出错: {e}")# 安排下一次更新 self.root.after(10, self.animate)defupdate_fireworks(self, draw, current_time, delta_time):"""更新烟花系统"""# 发射新烟花if current_time - self.last_firework_time > self.firework_interval:if random.random()<0.7:# 70%概率发射烟花 self.launch_firework() self.last_firework_time = current_time # 更新现有烟花 alive_fireworks =[]for firework in self.fireworks:if firework.update(delta_time): alive_fireworks.append(firework) firework.draw(draw) self.fireworks = alive_fireworks deflaunch_firework(self):"""发射新烟花"""# 随机选择发射位置(屏幕上半部分) x = random.randint(100, self.screen_width -100) y = self.screen_height +50# 从屏幕底部发射# 随机选择颜色 color = random.choice(self.firework_colors)# 随机爆炸高度 explosion_height = random.randint(100, self.screen_height //2)# 创建新烟花 firework = Firework(x, y, color, explosion_height) self.fireworks.append(firework)defdraw_tasks(self, draw, current_time):"""绘制任务信息"""ifnot self.tasks:return# 任务显示区域(右上角) start_x = self.screen_width -400 start_y =150# 绘制标题(无背景) title_text ="今日任务" draw.text((start_x, start_y), title_text, fill=(233,69,96,255), font=self.title_font )# 绘制任务列表for i, task inenumerate(self.tasks): y_pos = start_y +100+ i *40# 任务状态图标 status_icon ="✓"if task.completed else"○" status_color =(149,165,166,255)if task.completed else(233,69,96,255) draw.text((start_x, y_pos), status_icon, fill=status_color, font=self.task_font )# 任务文本 text_color =(149,165,166,255)if task.completed else(255,255,255,255) draw.text((start_x +40, y_pos), task.text, fill=text_color, font=self.task_font )defdraw_date_info(self, draw, current_time):"""绘制日期信息""" now = datetime.now()# 日期显示区域(右下角) date_text = now.strftime("%Y年%m月%d日") week_text = now.strftime("星期%w").replace("星期0","星期日") time_text = now.strftime("%H:%M:%S")# 计算所有文字的尺寸 date_bbox = draw.textbbox((0,0), date_text, font=self.date_font) week_bbox = draw.textbbox((0,0), week_text, font=self.date_font) time_bbox = draw.textbbox((0,0), time_text, font=self.date_font) date_width = date_bbox[2]- date_bbox[0] date_height = date_bbox[3]- date_bbox[1] week_width = week_bbox[2]- week_bbox[0] week_height = week_bbox[3]- week_bbox[1] time_width = time_bbox[2]- time_bbox[0] time_height = time_bbox[3]- time_bbox[1]# 计算右下角位置,避免被任务列表遮挡 base_x = self.screen_width -max(date_width, week_width, time_width)-80# 距离右边80像素# 垂直排列,从下往上 time_y = self.screen_height - time_height -80# 时间在最下面 week_y = time_y - week_height -15# 星期在时间上面 date_y = week_y - date_height -15# 日期在最上面# 绘制日期(右下角,无背景) draw.text((base_x, date_y), date_text, fill=(233,69,96,255), font=self.date_font )# 绘制星期(右下角,无背景) draw.text((base_x, week_y), week_text, fill=(255,255,255,255), font=self.date_font )# 绘制时间(右下角,无背景) draw.text((base_x, time_y), time_text, fill=(78,205,196,255), font=self.date_font )defstop_wallpaper(self):"""停止壁纸""" self.is_running =False# 清理临时文件try: temp_wallpaper_path = os.path.join(os.path.dirname(__file__),"temp_wallpaper.bmp")if os.path.exists(temp_wallpaper_path): os.remove(temp_wallpaper_path)except:pass# 清理相关属性ifhasattr(self,'wallpaper_image'):delattr(self,'wallpaper_image') self.status_label.config(text="壁纸已停止", fg="#e74c3c")defon_closing(self):"""关闭程序""" self.stop_wallpaper() self.save_tasks() self.root.quit() self.root.destroy()defmain():"""主函数"""try:# 检查管理员权限ifnot ctypes.windll.shell32.IsUserAnAdmin(): ctypes.windll.shell32.ShellExecuteW(None,"runas", sys.executable," ".join(sys.argv),None,1) sys.exit() app = FireworkWallpaper() app.root.mainloop()except Exception as e: messagebox.showerror("错误",f"程序运行时发生错误:{str(e)}")if __name__ =="__main__": main()文章推荐
【Python】2026动态文字壁纸,一键让你的桌面加上烟花效果和今日任务事项
【Python】2026动态文字壁纸,一键让你的桌面加上动态效果
【Python】用于发送电子邮件的标准库smtplib和构建邮件主体、添加附件、设置收件人的email
【Python】selenium爬虫常见用法和配置,以及常见错误和解决方法
【Python】尝试使用一个不可哈希的数据类型作为哈希表的键,错误提示builtins.TypeError,unhashable type
【Python】AES加解密代码,文章还有加密串等你来解密,等你来挑战
【Python】简单使用C/C++和Python嵌套for循环生成一个小爱心
【Python】Python3 使用selenium模块实现简单爬虫系列一