基于Python实现Windows桌面定时提醒休息程序

 更新时间:2024年11月26日 10:04:30   作者:正义之兔  
这篇文章为大家详细主要介绍了如何基于Python实现简单的Windows桌面定时提醒休息程序,文中的示例代码讲解详细,有需要的可以参考一下

当我们长期在电脑面前坐太久后,会产生一系列健康风险,包括干眼症,颈椎,腰椎,肌肉僵硬等等。解决方案是在一定的时间间隔内我们需要have a break, 远眺可以缓解干眼症等眼部症状,站起来走动两步,或者做一些舒展动作,可以让我们身体肌肉放松。Microsoft Store的一些第三方免费定时提醒程序,如BreakTimer, 常常难以在约定的时间内唤起。其他一些有着类似功能且有更丰富特性的第三方程序需要注册缴费才能使用很多功能。这触发了我自己写一个程序来实现该功能。

因为Python的功能强大,且开发程序的门槛低,所以我选择它,我电脑安装的版本是3.10. 第一步,开发一个可以显示在底部工具栏右边隐藏托盘的图标,当我们有鼠标放上去时,可以显示当前离下一次休息还剩下的时间,以分钟和秒计。点击鼠标右键时,可以弹出菜单显示当前剩余时间和退出按钮。

要实现以上功能,需要安装第三方库 pystray 和 pillow。代码如下:

import threading
from pystray import Icon, MenuItem, Menu
from PIL import Image, ImageDraw
 
def create_image():
    # Load an existing image for the tray icon
    icon_path = r"C:\technical learning\Python\take-break-icon.png"  # Path to your image file (e.g., .png or .ico)
    return Image.open(icon_path)
 
def stop_program(icon, item):
    # Stop the video playback and exit the program
    global keep_run
    icon.stop()
    keep_run=False
 
 
def start_tray_icon(icon):
    # Create the system tray icon with a menu
    icon.run()
 
myicon = Icon("VideoPlayer", create_image())
# Start the tray icon in a separate thread
tray_thread = threading.Thread(target=start_tray_icon, args=[myicon],daemon=True)
tray_thread.start()
 
def update_tray_menu(icon):
    # Update the menu with the remaining time
    global time_left
    #the tray menu has three items, time left, set timer, and stop
    menu = Menu(
        MenuItem(f"Time left: {time_left[0]} minutes {time_left[1]} seconds", lambda icon,item:None),
        MenuItem('Set Timer', set_timer),  # Add the new menu option here
        MenuItem('Stop', action=stop_program)
    )
    icon.menu = menu
    
    #the title will show when you mouse over the icon
    icon.title = f"{time_left}"

首先通过已有的图片创建一个Icon object,并创建一个线程来运行该object。因为要实时显示剩余时间,所以有一个update函数来对Menu内容进行更新。

第二步,实现每隔预设的时间, 启动VLC播放器,播放一段指定的视频。同时计时器重新开始倒计时。

import subprocess
import time
 
# Path to VLC and your video file
vlc_path = r"D:\Program Files (x86)\VideoLAN\VLC\vlc.exe"  # Update if needed
video_path = r"C:\technical learning\Python\Health_song_Fxx.mp4"
 
#the minutes and seconds to pass to have a break periodically,default is 60 minutes  
time_set = (59,60)
 
# Global variable to track time left
time_left = list(time_set)
keep_run = True
 
def start_play_video():
     subprocess.run([vlc_path, video_path])
 
while keep_run:
        update_tray_menu(myicon) #you can see the update of time_left instantly
        if time_left[0]==-1: #it's the time for a break
        video_play_thread = threading.Thread(target=start_play_video)
        video_play_thread.start()
        time_left = list(time_set)  # Reset time left
        time.sleep(1)
        if time_left[1]==0:
            time_left[1]=60
            time_left[0]-=1
        time_left[1] -= 1 

主线程是一个while loop,每隔1s更新time_left,当time out,启动一个线程来通过subprocess来调用VLC播放器来播放视频,之所以用subprocess是这样一般可以带来前台窗体播放的效果,更好的提醒作用。当Icon点击了stop后,keep_run为False,循环退出,程序结束。

最简单功能的桌面定时提醒程序这时候可以告一段落了,但是在你使用电脑的过程中,你可能本身会中途离开,比方说中午午餐,去开会,或者去做运动了。这时候电脑进入休眠状态。当你回来后,计时器还是会按照计算机休眠前剩余的时间继续计时,这个不太合理。因为这个时候你其实已经眼睛和身体已经得到了一些放松,起码没有一直盯着屏幕。所以应该重新开始计时。

要实现Windows计算机从休眠中醒来重新计数,需要安装第三方库pywin32,别被名字糊弄,因为历史原因,它后续的版本也包括了64 bit windows. 

import win32api
import win32gui
import win32con
 
#the class used to handle event of computer waking up from hibernation
class PowerEventHandler:
    def __init__(self):
        self.internal_variable = 0
    
    def handle_event(self, hwnd, msg, wparam, lparam):
        global time_left
        if msg == win32con.WM_POWERBROADCAST and wparam == win32con.PBT_APMRESUMEAUTOMATIC:
            #print("Laptop woke up from hibernation!")
            time_left = [59,60]
            list(time_set)
        return True
    
'''creates a custom Windows Message Handling Window'''
handler = PowerEventHandler()
wc = win32gui.WNDCLASS()
wc.lpszClassName = 'PowerHandler'
wc.hInstance = win32api.GetModuleHandle(None)
wc.lpfnWndProc = handler.handle_event
 
class_atom = win32gui.RegisterClass(wc)
#create a window of the registered class with no size and invisible
hwnd = win32gui.CreateWindow(class_atom, 'PowerHandler', 0, 0, 0, 0, 0, 0, 0, wc.hInstance, None)

创建一个不可见窗体来接受Windows系统的消息,当接收到从休眠中醒来的消息时,重置剩下的时间为预设值。同时你需要在while loop里不断地处理pending的Windows系统消息。

win32gui.PumpWaitingMessages()

第四步,目前为止,隔多少时间休息的时间段是在程序里写死的,默认是60分钟。用户可能需要根据自己的偏好进行修改。那么需要在Icon的Menu里增加一个选项,点击后弹框进行时间段设置。 

这里就要用到tkinter lib,这个默认在Pythond的安装包里,无需另外安装。

import tkinter as tk
from tkinter import simpledialog
 
#a pop up dialog to set the time_set
def set_timer(icon, item):
    #after the user clicking the set button
    def validate_and_set_time():
        nonlocal root, error_label
        try:
            minutes = int(minute_input.get())
            seconds = int(second_input.get())
            #print(minutes,seconds)
            # Validate range [0, 60]
            if 0 <= minutes <= 60 and 0 <= seconds <= 60:
                with time_left_lock:
                    global time_set,time_left
                    time_set=(minutes,seconds)
                    time_left=list(time_set)  #each time_set is set, time_let needs to update accordingly
                    #print(time_left)
                root.destroy()  # Close dialog if input is valid
            else:
                error_label.config(text="Minutes and seconds must be between 0 and 60!")
        except ValueError:
            error_label.config(text="Please enter valid integers!")
 
    #create the dialog
    root = tk.Tk()
    root.title("Set Timer")
    root.geometry("300x200")
    # Get screen width and height
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()
 
    # Calculate position x and y to center the window
    window_width = 300
    window_height = 200
    position_x = (screen_width // 2) - (window_width // 2)
    position_y = (screen_height // 2) - (window_height // 2)
 
    # Set the geometry to center the window
    root.geometry(f"{window_width}x{window_height}+{position_x}+{position_y}")
 
    tk.Label(root, text="Set Timer").pack(pady=5)
 
    tk.Label(root, text="Minutes (0-60):").pack()
    minute_input = tk.Entry(root)
    minute_input.pack()
 
    tk.Label(root, text="Seconds (0-60):").pack()
    second_input = tk.Entry(root)
    second_input.pack()
 
    error_label = tk.Label(root, text="", fg="red")  # Label for error messages
    error_label.pack(pady=5)
    #set the button call-back method to validate_and_set_time
    tk.Button(root, text="Set", command=validate_and_set_time).pack(pady=10)
 
    root.mainloop()

上面的代码就包括了弹窗设计,用户输入数据校验,间隔时间段设置,以及剩余时间重置等。

另外,在Icon的Menu里需增加一栏,用于设置间隔时间段。

MenuItem('Set Timer', set_timer),  # Add the new menu option here

最后一步,为了让用户设置的时间段间隔永久生效,需要用一个文件来存储。 启动这个程序的时候,从这个文件读数据,退出程序的时候,把数据存入到该文件。

这是鼠标移到Icon上,点击右键出现的Menu:

下面是点击Set Timer后的弹框。

到此这篇关于基于Python实现Windows桌面定时提醒休息程序的文章就介绍到这了,更多相关Python定时提醒内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python 协程中的迭代器,生成器原理及应用实例详解

    python 协程中的迭代器,生成器原理及应用实例详解

    这篇文章主要介绍了python 协程中的迭代器,生成器原理及应用,结合具体实例形式详细分析了Python协程中的迭代器,生成器概念、原理及应用操作技巧,需要的朋友可以参考下
    2019-10-10
  • django+tornado实现实时查看远程日志的方法

    django+tornado实现实时查看远程日志的方法

    今天小编就为大家分享一篇django+tornado实现实时查看远程日志的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-08-08
  • Python实现删除某列中含有空值的行的示例代码

    Python实现删除某列中含有空值的行的示例代码

    这篇文章主要介绍了Python实现删除某列中含有空值的行的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • Python箱型图处理离群点的例子

    Python箱型图处理离群点的例子

    今天小编就为大家分享一篇Python箱型图处理离群点的例子,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • Python3利用Dlib19.7实现摄像头人脸识别的方法

    Python3利用Dlib19.7实现摄像头人脸识别的方法

    这篇文章主要介绍了Python 3 利用 Dlib 19.7 实现摄像头人脸识别 ,利用python开发,借助Dlib库捕获摄像头中的人脸,提取人脸特征,通过计算欧氏距离来和预存的人脸特征进行对比,达到人脸识别的目的,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • python网络爬虫实现个性化音乐播放器示例解析

    python网络爬虫实现个性化音乐播放器示例解析

    这篇文章主要为大家介绍了使用python网络爬虫实现个性化音乐播放器的详细示例代码以及内容解析,有需要的朋友 可以借鉴参考下希望能够有所帮助
    2022-03-03
  • Python中使用matplotlib绘制mqtt数据实时图像功能

    Python中使用matplotlib绘制mqtt数据实时图像功能

    这篇文章主要介绍了Python中使用matplotlib绘制mqtt数据实时图像,本代码中publish是一个死循环,数据一直往外发送,详细代码跟随小编一起通过本文学习下吧
    2021-09-09
  • 基于Python+Flask实现一个简易网页验证码登录系统案例

    基于Python+Flask实现一个简易网页验证码登录系统案例

    当今的互联网世界中,为了防止恶意访问,许多网站在登录和注册表单中都采用了验证码技术,验证码可以防止机器人自动提交表单,确保提交行为背后有一个真实的人类用户,本文将向您展示如何使用Python的Flask框架来创建一个简单的验证码登录系统
    2023-09-09
  • 深入分析Python中Lambda函数的用法

    深入分析Python中Lambda函数的用法

    lambda函数是Python中常用的内置函数,又称为匿名函数。和普通函数相比,它只有函数体,省略了def和return,使得结构看起来更精简。本文将详细说说Lambda函数的用法,需要的可以参考一下
    2022-12-12
  • Django中使用SMTP实现邮件发送功能

    Django中使用SMTP实现邮件发送功能

    在 Django 中使用 SMTP 发送邮件是一个常见的需求,通常用于发送用户注册确认邮件、密码重置邮件等,下面我们来看看如何在 Django 中配置 SMTP 发送邮件吧
    2025-01-01

最新评论