当前位置:首页>python>Python GUI 工作日自动唤醒、眠工具(tkinter 可视化界面)

Python GUI 工作日自动唤醒、眠工具(tkinter 可视化界面)

  • 2026-10-11 07:15:22
Python GUI 工作日自动唤醒、眠工具(tkinter 可视化界面)

功能:工作日自动唤醒和睡眠


- 唤醒任务:到点判断是否工作日,是则唤醒睡眠电脑


- 睡眠任务:到点判断是否工作日,是则执行自动睡眠


3. 一键安装/卸载两套任务,日志统一输出


4. 自动调用Windows睡眠指令,仅工作日生效,节假日/周末跳过



完整代码 workday_auto_gui.py



python




import ctypes


import sys


import os


import datetime


import holidays


import win32com.client


import tkinter as tk


from tkinter import ttk, messagebox, scrolledtext



# ===================== 全局配置 =====================


TASK_WAKE_NAME = "真实工作日自动唤醒"


TASK_SLEEP_NAME = "真实工作日自动睡眠"


LOG_TEXT = None


# ====================================================



def is_admin():


    try:


        return ctypes.windll.shell32.IsUserAnAdmin()


    except:


        return False



def run_as_admin():


    if not is_admin():


        ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)


        sys.exit(0)



def log(msg):


    global LOG_TEXT


    time_str = datetime.datetime.now().strftime("%H:%M:%S")


    line = f"[{time_str}] {msg}\n"


    LOG_TEXT.insert(tk.END, line)


    LOG_TEXT.see(tk.END)


    LOG_TEXT.update_idletasks()



def is_real_workday(check_date: datetime.date) -> bool:


    """判断真实工作日:区分节假日、调休、周末"""


    cn_holiday = holidays.China(years=check_date.year)


    desc = cn_holiday.get(check_date, "")


    wd = check_date.weekday()


    if desc == "节假日":


        return False


    if desc == "调休":


        return True


    if 0 <= wd <= 4:


        return True


    return False



def create_single_task(task_name, hour, minute, wake_flag: bool):


    """


    创建单个定时任务


    wake_flag=True:唤醒任务,开启WakeToRun


    wake_flag=False:睡眠任务,不需要唤醒


    """


    run_as_admin()


    scheduler = win32com.client.Dispatch("Schedule.Service")


    scheduler.Connect()


    folder = scheduler.GetFolder("\\")


    try:


        folder.DeleteTask(task_name, 0)


        log(f"已清理旧任务:{task_name}")


    except Exception:


        log(f"无旧任务:{task_name}")



    task_def = scheduler.NewTask(0)


    if wake_flag:


        task_def.RegistrationInfo.Description = "工作日唤醒:节假日/周末跳过唤醒"


        task_def.Settings.WakeToRun = True


    else:


        task_def.RegistrationInfo.Description = "工作日睡眠:节假日/周末不执行睡眠"


        task_def.Settings.WakeToRun = False



    task_def.Settings.Enabled = True


    task_def.Settings.AllowStartIfMissed = True



    # 每周一至周五触发


    trigger = task_def.Triggers.Create(12)


    now = datetime.datetime.now()


    trigger.StartBoundary = f"{now.year}-{now.month:02d}-{now.day:02d} {hour:02d}:{minute:02d}:00"


    trigger.DaysOfWeek = 0b11111


    trigger.WeeksInterval = 1


    trigger.Enabled = True



    # 运行本脚本


    action = task_def.Actions.Create(0)


    py_path = sys.executable


    script_path = os.path.abspath(__file__)


    if wake_flag:


        action.Arguments = f'"{script_path}" wake'


    else:


        action.Arguments = f'"{script_path}" sleep'


    action.Path = py_path


    action.WorkingDirectory = os.path.dirname(script_path)



    folder.RegisterTaskDefinition(task_name, task_def, 6, "", "", 0)


    log(f"创建成功 [{task_name}] 时间:{hour:02d}:{minute:02d}")



def delete_all_task():


    """卸载唤醒+睡眠两套任务"""


    run_as_admin()


    scheduler = win32com.client.Dispatch("Schedule.Service")


    scheduler.Connect()


    folder = scheduler.GetFolder("\\")


    del_list = [TASK_WAKE_NAME, TASK_SLEEP_NAME]


    for name in del_list:


        try:


            folder.DeleteTask(name, 0)


            log(f"已删除任务:{name}")


        except Exception:


            log(f"未找到任务:{name}")


    messagebox.showinfo("完成", "所有定时任务已卸载")



def execute_wake_logic():


    """唤醒分支逻辑"""


    today = datetime.date.today()


    if is_real_workday(today):


        return


    else:


        sys.exit(0)



def execute_sleep_logic():


    """睡眠分支逻辑:今日工作日则执行睡眠"""


    today = datetime.date.today()


    if is_real_workday(today):


        log(f"今日{today}为工作日,执行自动睡眠")


        # Windows睡眠命令


        os.system("rundll32.exe powrprof.dll,SetSuspendState 0,1,0")


    else:


        log(f"今日{today}休息日,跳过睡眠操作")


        sys.exit(0)



def check_today_status():


    today = datetime.date.today()


    res = is_real_workday(today)


    if res:


        log(f"今日 {today} → 法定工作日,唤醒、睡眠任务都会正常执行")


    else:


        log(f"今日 {today} → 休息日,到点不会唤醒、也不会自动睡眠")



def gui_main():


    global LOG_TEXT


    # 区分定时任务自动运行模式


    if len(sys.argv) > 1:


        if sys.argv[1] == "wake":


            execute_wake_logic()


        elif sys.argv[1] == "sleep":


            execute_sleep_logic()


        return



    root = tk.Tk()


    root.title("工作日自动唤醒&睡眠工具 v2.0")


    root.geometry("560x440")


    root.resizable(False, False)



    # 唤醒设置区


    frame_wake = ttk.LabelFrame(root, text="早上唤醒时间")


    frame_wake.pack(pady=8, padx=10, fill="x")


    ttk.Label(frame_wake, text="小时:").grid(row=0, column=0, padx=8, pady=8)


    spin_wake_h = ttk.Spinbox(frame_wake, from_=0, to=23, width=6)


    spin_wake_h.grid(row=0, column=1)


    spin_wake_h.insert(0, "8")


    ttk.Label(frame_wake, text="分钟:").grid(row=0, column=2, padx=12, pady=8)


    spin_wake_m = ttk.Spinbox(frame_wake, from_=0, to=59, width=6)


    spin_wake_m.grid(row=0, column=3)


    spin_wake_m.insert(0, "30")



    # 睡眠设置区


    frame_sleep = ttk.LabelFrame(root, text="晚间自动睡眠时间")


    frame_sleep.pack(pady=8, padx=10, fill="x")


    ttk.Label(frame_sleep, text="小时:").grid(row=0, column=0, padx=8, pady=8)


    spin_sleep_h = ttk.Spinbox(frame_sleep, from_=0, to=23, width=6)


    spin_sleep_h.grid(row=0, column=1)


    spin_sleep_h.insert(0, "22")


    ttk.Label(frame_sleep, text="分钟:").grid(row=0, column=2, padx=12, pady=8)


    spin_sleep_m = ttk.Spinbox(frame_sleep, from_=0, to=59, width=6)


    spin_sleep_m.grid(row=0, column=3)


    spin_sleep_m.insert(0, "00")



    # 按钮区


    frame_btn = ttk.Frame(root)


    frame_btn.pack(pady=6)


    def btn_install_all():


        try:


            wh = int(spin_wake_h.get())


            wm = int(spin_wake_m.get())


            sh = int(spin_sleep_h.get())


            sm = int(spin_sleep_m.get())


            if not (0<=wh<=23 and 0<=wm<=59 and 0<=sh<=23 and 0<=sm<=59):


                messagebox.showerror("错误", "时分必须0~23/0~59")


                return


            create_single_task(TASK_WAKE_NAME, wh, wm, wake_flag=True)


            create_single_task(TASK_SLEEP_NAME, sh, sm, wake_flag=False)


            messagebox.showinfo("安装完成", f"唤醒:{wh:02d}:{wm:02d}\n睡眠:{sh:02d}:{sm:02d}\n仅法定工作日生效")


        except ValueError:


            messagebox.showerror("输入错误", "请输入纯数字时间")



    ttk.Button(frame_btn, text="一键安装两套任务", command=btn_install_all).grid(row=0, column=0, padx=4)


    ttk.Button(frame_btn, text="卸载全部任务", command=delete_all_task).grid(row=0, column=1, padx=4)


    ttk.Button(frame_btn, text="检测今日是否工作日", command=check_today_status).grid(row=0, column=2, padx=4)



    # 日志框


    frame_log = ttk.LabelFrame(root, text="运行日志")


    frame_log.pack(pady=10, padx=10, fill="both", expand=True)


    LOG_TEXT = scrolledtext.ScrolledText(frame_log, height=12)


    LOG_TEXT.pack(padx=5, pady=5, fill="both", expand=True)



    root.mainloop()



if __name__ == "__main__":


    gui_main()




一、依赖安装(管理员CMD)



bash




pip install holidays pywin32




二、使用说明



1. 双击运行脚本打开GUI


2. 设置两个时间:


- 唤醒时间:早上自动唤醒睡眠电脑(仅工作日)


- 睡眠时间:晚上自动让电脑进入睡眠(仅工作日,周末/节假日不执行)


3. 一键安装两套定时任务;卸载可一次性清除唤醒+睡眠任务


4. 检测今日按钮可预览当天是否会执行唤醒、睡眠



三、自动睡眠原理



脚本被定时触发后:



1. 判断今日是否真实工作日(调班上班算工作日,放假/周末不算)


2. 是工作日:执行Windows系统睡眠命令,电脑立刻休眠


3. 休息日:直接退出,不做任何操作



睡眠命令说明:


 rundll32.exe powrprof.dll,SetSuspendState 0,1,0 



- 0 = 睡眠(1代表休眠)


- 1 = 忽略弹窗、强制睡眠


- 0 = 不创建休眠文件(普通睡眠)



四、前置必要设置



1. 允许唤醒定时器(唤醒功能必备)


Win+R →  powercfg.cpl  → 更改高级电源设置 → 睡眠 → 允许唤醒定时器=启用


2. 关闭快速启动(睡眠异常时)


电源选项 → 选择电源按钮功能 → 更改当前不可用设置 → 取消勾选「启用快速启动」



五、关键限制



1. 自动唤醒:仅电脑处于睡眠/休眠有效;完全断电关机无法唤醒(受BIOS硬件限制)


2. 自动睡眠:无论电脑是开机状态,到点只要是工作日都会睡眠,不受断电影响


3. 节假日数据:每年执行  pip install --upgrade holidays  更新放假调休数据



六、补充:区分睡眠/关机



如果你想要定时关机而不是睡眠,把代码里睡眠那行替换成关机命令:



python




# 替换睡眠语句,强制关机


os.system("shutdown /s /f /t 0")

最新文章

随机文章