Python
构建Desktop Time Clock【支持秒显示】
起因
由于部分电脑只能显示时间的时分,不支持显示秒,利用Python
的tkinter
库做了一个桌面时钟,该时钟能够获取系统实时时钟,并精确到秒显示
附注:本程序每1s
才会更新一次时间变量,所占用系统资源极少,可长时间运行
设置自启动
- 创建 DesktopTimeClock.bat 文件,文件里写入如下内容:
1.1 假设你的文件存放在C:\\Desktop\\DesktopTimeClock.py
1.2 以下文件路劲和文件名需要根据个人实际情况进行替换
cd C:\\Desktop
python DesktopTimeClock.py
-
运行DesktopTimeClock.bat: 双击运行 DesktopTimeClock.bat 文件,桌面时钟将会出现在您的屏幕上。
-
创建快捷方式:右键点击 DesktopTimeClock.bat 文件,选择“创建快捷方式”。
-
添加到启动文件夹: 将快捷方式移动到启动文件夹(
C:\Users<用户名>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
)中。 -
完成: 现在,每次启动电脑时,桌面时钟都会自动显示。
-
关闭程序: 点击桌面时钟窗口,并按住
Esc
键1s
即可关闭程序。
代码实现
- 时钟的位置和字体大小可根据个人需要自行调节
from tkinter import *
import time, datetime
from time import gmtime, strftime
root = Tk()
# Window Attributes
root.overrideredirect(1) # 隐藏窗口边框
root.wm_attributes("-transparentcolor", "gray99") # 设置透明背景色
running = True # 运行状态
# 关闭窗口函数
def close(event):
global running
running = False
root.bind('<Escape>', close) # 绑定Esc键关闭窗口
screen_width = root.winfo_screenwidth() # 获取屏幕宽度
screen_height = root.winfo_screenheight() # 获取屏幕高度
timeframe = Frame(root, width=screen_width, height=screen_height, bg="gray99") # 创建主框架
timeframe.grid(row=0,column=0)
tkintertime = StringVar() # 创建时间变量
timelabel = Label(timeframe, textvariable=tkintertime, fg="white", bg="gray99", font=("NovaMono", 40)) # 创建时间标签
# timelabel.place(y=screen_height/2 - 30, x=screen_width/2, anchor="center") # 设置时间标签位置(屏幕中心)
timelabel.place(y=screen_height/4 - 30, x=screen_width-screen_width/4, anchor="center") # 设置时间标签位置(右上角)
tkinterdate = StringVar() # 创建日期变量
datelabel = Label(timeframe, textvariable=tkinterdate, fg="white", bg="gray99", font=("Bahnschrift", 15)) # 创建日期标签
# datelabel.place(y=screen_height/2 + 30, x=screen_width/2, anchor="center") # 设置日期标签位置(屏幕中心)
datelabel.place(y=screen_height/4 + 30, x=screen_width-screen_width/4, anchor="center") # 设置日期标签位置(右上角)
while running:
tkintertime.set(value=strftime("%H:%M:%S")) # 更新时间
tkinterdate.set(value=strftime("%A, %e %B")) # 更新日期
root.update_idletasks() # 更新窗口
root.update() # 更新窗口
time.sleep(1) # 延迟1秒
3. 逐步分解
代码解释:
- 导入模块:
from tkinter import * import time, datetime from time import gmtime, strftime
tkinter
是Python的标准GUI库。time
和datetime
是用于处理时间和日期的模块。gmtime
和strftime
是time
模块中的函数,用于将当前时间转换为UTC时间并格式化输出。
- 创建主窗口:
root = Tk()
- 创建一个Tkinter主窗口实例。
- 窗口属性:
root.overrideredirect(1) # 隐藏窗口边框 root.wm_attributes("-transparentcolor", "gray99") # 设置透明背景色
overrideredirect(1)
隐藏了窗口的边框,使窗口无边框。wm_attributes
设置了窗口的透明背景色为 “gray99”。
- 运行状态变量:
running = True # 运行状态
running
变量用于控制主循环的运行。
- 关闭窗口函数:
def close(event): global running running = False
close
函数将running
设置为False
以关闭窗口。
- 绑定关闭事件:
root.bind('<Escape>', close) # 绑定Esc键关闭窗口
- 将
Escape
键绑定到close
函数,按Esc
键将关闭窗口。
- 将
- 获取屏幕尺寸:
screen_width = root.winfo_screenwidth() # 获取屏幕宽度 screen_height = root.winfo_screenheight() # 获取屏幕高度
- 获取当前屏幕的宽度和高度。
- 创建主框架:
timeframe = Frame(root, width=screen_width, height=screen_height, bg="gray99") # 创建主框架 timeframe.grid(row=0,column=0)
- 创建一个与屏幕大小相同的框架,并设置背景色为 “gray99”。
- 创建时间标签:
tkintertime = StringVar() # 创建时间变量 timelabel = Label(timeframe, textvariable=tkintertime, fg="white", bg="gray99", font=("NovaMono", 40)) # 创建时间标签 timelabel.place(y=screen_height/4 - 30, x=screen_width-screen_width/4, anchor="center") # 设置时间标签位置(右上角)
- 创建一个
StringVar
对象用于存储时间。 - 创建一个标签用于显示时间,并设置字体、前景色和背景色。
- 将时间标签放置在屏幕右上角。
- 创建一个
- 创建日期标签:
tkinterdate = StringVar() # 创建日期变量 datelabel = Label(timeframe, textvariable=tkinterdate, fg="white", bg="gray99", font=("Bahnschrift", 15)) # 创建日期标签 datelabel.place(y=screen_height/4 + 30, x=screen_width-screen_width/4, anchor="center") # 设置日期标签位置(右上角)
- 创建一个
StringVar
对象用于存储日期。 - 创建一个标签用于显示日期,并设置字体、前景色和背景色。
- 将日期标签放置在屏幕右上角。
- 创建一个
- 主循环:
while running: tkintertime.set(value=strftime("%H:%M:%S")) # 更新时间 tkinterdate.set(value=strftime("%A, %e %B")) # 更新日期 root.update_idletasks() # 更新窗口 root.update() # 更新窗口 time.sleep(1) # 延迟1秒
- 主循环不断更新时间和日期,并重新绘制窗口。
strftime
用于格式化当前时间和日期。update_idletasks()
和update()
用于刷新窗口。time.sleep(1)
使循环每秒运行一次。
代码分析:
- 性能问题:使用
while
循环和time.sleep(1)
来更新时间不是最佳实践。更好的做法是使用root.after()
方法来安排函数周期性调用,这样可以避免阻塞主线程,并提高应用程序的响应性。
4. 代码改进
以下是改进后的完整代码,使用 root.after()
方法代替了 while
循环来更新时间:
from tkinter import *
import time
from time import strftime
# 创建主窗口
root = Tk()
# 隐藏窗口边框
root.overrideredirect(1)
# 设置透明背景色
root.wm_attributes("-transparentcolor", "gray99")
# 运行状态
running = True
# 关闭窗口函数
def close(event):
global running
running = False
root.destroy() # 销毁窗口
# 绑定Esc键关闭窗口
root.bind('<Escape>', close)
# 获取屏幕尺寸
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
# 创建主框架
timeframe = Frame(root, width=screen_width, height=screen_height, bg="gray99")
timeframe.grid(row=0, column=0)
# 创建时间变量
tkintertime = StringVar()
# 创建时间标签
timelabel = Label(timeframe, textvariable=tkintertime, fg="white", bg="gray99", font=("NovaMono", 40))
# 设置时间标签位置(右上角)
timelabel.place(y=screen_height/4 - 30, x=screen_width-screen_width/4, anchor="center")
# 创建日期变量
tkinterdate = StringVar()
# 创建日期标签
datelabel = Label(timeframe, textvariable=tkinterdate, fg="white", bg="gray99", font=("Bahnschrift", 15))
# 设置日期标签位置(右上角)
datelabel.place(y=screen_height/4 + 30, x=screen_width-screen_width/4, anchor="center")
# 更新时间的函数
def update_time():
tkintertime.set(value=strftime("%H:%M:%S")) # 更新时间
tkinterdate.set(value=strftime("%A, %e %B")) # 更新日期
if running:
root.after(1000, update_time) # 安排函数在1000毫秒后再次调用
# 开始时钟
update_time()
# 启动Tkinter事件循环
root.mainloop()
改进后的代码使用了 root.after()
来安排 update_time
函数每1000毫秒(即1秒)调用一次,而不是使用 while
循环和 time.sleep()
。这样做可以避免阻塞主线程,并且使窗口能够更加流畅地响应用户操作。此外,在 close
函数中添加了 root.destroy()
来确保窗口在按下 Esc
键时完全关闭。