灌水成绩
等级头衔
ID :
694
用户组 :
注册会员
积分成就
测量币 : 78 个
违规 : 0 次
在线时间 : 0 小时
注册时间 : 2026-4-6
最后登录 : 2026-4-23
勋章
联系方式
任务条可以拖拽,看得到进度,
可以透明
https://wwbvp.lanzouu.com/iXP483ngisnc
密码:buon
代码如下:
import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
import threading
import time
import json
import os
import sys
import winsound
# --- 解决打包后资源路径问题 ---
def resource_path(relative_path):
"""获取打包后资源的绝对路径"""
base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
return os.path.join(base_path, relative_path)
# --- 配置文件路径 (隐藏到系统AppData目录) ---
APP_DATA_DIR = os.path.join(os.environ['APPDATA'], "涂涂牌倒计时闹钟")
os.makedirs(APP_DATA_DIR, exist_ok=True)
CONFIG_FILE = os.path.join(APP_DATA_DIR, "countdown_tasks.json")
WINDOW_CONFIG_FILE = os.path.join(APP_DATA_DIR, "window_config.json")
ALARM_SOUND = resource_path("alarm.wav") # 闹钟声音文件路径
class CountdownTask:
def __init__(self, name, total_seconds, remind_before=0):
self.name = name
self.total_seconds = total_seconds
self.remaining = total_seconds
self.remind_before = remind_before
self.is_running = False
self.is_finished = False
self.reminded = False
self.is_alarming = False
def to_dict(self):
return {
"name": self.name,
"total_seconds": self.total_seconds,
"remaining": self.remaining,
"remind_before": self.remind_before,
"is_finished": self.is_finished
}
@staticmethod
def from_dict(data):
task = CountdownTask(data["name"], data["total_seconds"], data.get("remind_before", 0))
task.remaining = data["remaining"]
task.is_finished = data["is_finished"]
return task
class App:
def __init__(self, root):
self.root = root
self.root.title("涂涂牌倒计时闹钟")
self.load_window_config()
self.root.minsize(380, 300)
self.tasks = []
self.task_widgets = []
self.breathing_state = 0
self.breathing_colors = ["#ff3333", "#ff9999"]
self.dragging_index = None
self.load_data()
self.setup_ui()
self.running = True
self.update_thread = threading.Thread(target=self.tick_loop, daemon=True)
self.update_thread.start()
self.breathing_loop()
self.update_clock()
self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
def setup_ui(self):
frame_top = tk.Frame(self.root, pady=8, bg="#f0f0f0")
frame_top.pack(fill='x', side='top')
frame_top.grid_columnconfigure(2, weight=1)
btn_group = tk.Frame(frame_top, bg="#f0f0f0")
btn_group.grid(row=0, column=0, sticky='w', padx=10)
btn_add = tk.Button(btn_group, text="➕ 新建", command=self.add_task_dialog,
bg="#4CAF50", fg="white", font=("Arial", 9, "bold"))
btn_add.pack(side='left', padx=2)
btn_pause_all = tk.Button(btn_group, text="⏸️ 全停", command=self.pause_all)
btn_pause_all.pack(side='left', padx=2)
btn_reset_all = tk.Button(btn_group, text="🔄 全重置", command=self.reset_all)
btn_reset_all.pack(side='left', padx=2)
btn_stop_all_alarm = tk.Button(btn_group, text="🔇 全静音", bg="red", fg="white",
command=self.stop_all_alarm)
btn_stop_all_alarm.pack(side='left', padx=2)
setting_group = tk.Frame(frame_top, bg="#f0f0f0")
setting_group.grid(row=0, column=3, sticky='e', padx=10)
tk.Label(setting_group, text="透:", bg="#f0f0f0", font=("Arial", 9)).pack(side='left')
self.alpha_slider = tk.Scale(setting_group, from_=20, to=100, orient='horizontal',
length=60, showvalue=0, command=self.change_alpha)
self.alpha_slider.set(100)
self.alpha_slider.pack(side='left', padx=3)
self.clock_label = tk.Label(setting_group, text="00:00:00",
font=("Arial", 12, "bold"), fg="#2196F3", bg="#f0f0f0")
self.clock_label.pack(side='left', padx=8)
self.canvas = tk.Canvas(self.root, bg="white")
self.scrollbar = ttk.Scrollbar(self.root, orient="vertical", command=self.canvas.yview)
self.scrollable_frame = ttk.Frame(self.canvas)
self.scrollable_frame.bind(
"",
lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all"))
)
self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw", tags="frame")
self.canvas.configure(yscrollcommand=self.scrollbar.set)
self.canvas.bind("", self.on_canvas_configure)
self.canvas.bind_all("", self.on_mousewheel)
self.canvas.pack(side="left", fill="both", expand=True)
self.scrollbar.pack(side="right", fill="y")
self.refresh_task_list()
def on_mousewheel(self, event):
self.canvas.yview_scroll(int(-1*(event.delta/120)), "units")
def on_canvas_configure(self, event):
self.canvas.itemconfig("frame", width=event.width)
def change_alpha(self, value):
alpha_val = int(value) / 100.0
self.root.attributes("-alpha", alpha_val)
def update_clock(self):
current_time = time.strftime("%H:%M:%S")
self.clock_label.config(text=current_time)
self.root.after(1000, self.update_clock)
def add_task_dialog(self):
win = tk.Toplevel(self.root)
win.title("新建任务")
win.geometry("350x300")
win.resizable(False, False)
win.transient(self.root)
tk.Label(win, text="任务名称:", font=("Arial", 10)).pack(pady=5)
name_entry = tk.Entry(win, font=("Arial", 12), width=25)
name_entry.pack()
name_entry.insert(0, "新任务")
name_entry.focus_set()
time_frame = tk.Frame(win)
time_frame.pack(pady=10)
tk.Label(time_frame, text="时:").grid(row=0, column=0)
hour_entry = tk.Entry(time_frame, width=5)
hour_entry.grid(row=0, column=1, padx=5)
hour_entry.insert(0, "0")
tk.Label(time_frame, text="分:").grid(row=0, column=2)
min_entry = tk.Entry(time_frame, width=5)
min_entry.grid(row=0, column=3, padx=5)
min_entry.insert(0, "5")
tk.Label(time_frame, text="秒:").grid(row=0, column=4)
sec_entry = tk.Entry(time_frame, width=5)
sec_entry.grid(row=0, column=5, padx=5)
sec_entry.insert(0, "0")
tk.Label(win, text="提前多少秒提醒:", font=("Arial", 10)).pack(pady=5)
remind_entry = tk.Entry(win, font=("Arial", 12), width=10)
remind_entry.pack()
remind_entry.insert(0, "10")
def confirm(event=None):
try:
name = name_entry.get()
h = int(hour_entry.get() or 0)
m = int(min_entry.get() or 0)
s = int(sec_entry.get() or 0)
remind_s = int(remind_entry.get() or 0)
total_secs = h * 3600 + m * 60 + s
if total_secs
重要声明:以上内容仅代表作者梦里的青蛙 观点,不代表本站测量协会 立场。如有涉及侵权请尽快告知,我们将会在第一时间处理。作者原创内容未经允许不得转载!
站长联系邮箱:1339305021@qq.com
站长联系微信:dddnnbbb