当前位置:   article > 正文

基于Tkinter的桌面倒计时,打工人必备!_在桌面上实现时间倒计时的代码

在桌面上实现时间倒计时的代码

一、效果展示

        这是一个基于Tkinter的桌面倒计时,双击第一行弹出修改窗口,可以修改标题、目标时间、超时标题。该工具会自动倒计时,若超时,会自动显示超时标题,并显示超时多长时间。可自由拖动窗口,小巧,很适合期待下班的打工人使用!想拿来就用的朋友可以直接下载打包文件,想进一步了解的同学,请往下看~~

二、代码详情

1、初始化

从config.txt中读取标题、目标时间、超时标题。将目标时间转化为时间戳,方便计算。

利用Tk的相关方法设置窗口宽高、标题、位置、图标,绘制窗口等。图标可以更替,要求ico格式

-----------config.txt-----------

下班 还有
2023-11-17 11:53:00
加班 已经

  1. def __init__(self):
  2. with open('config.txt','r',encoding='utf8') as f:
  3. self.Target = f.readline().strip()
  4. self.t = f.readline().strip()
  5. self.overTarget = f.readline().strip()
  6. s_t = time.strptime(self.t, "%Y-%m-%d %H:%M:%S") # 返回元祖
  7. self.endtime = int(time.mktime(s_t))
  8. self.window = tk.Tk()
  9. self.x, self.y = 0, 0
  10. self.window_size = '150x150'
  11. # 窗口标题
  12. self.window.title('桌面倒计时')
  13. # 窗口的宽与高,单位是像素。以及位置坐标
  14. self.window.geometry(f"{self.window_size}+1000+100")
  15. # 窗口左上角图标
  16. self.window.iconbitmap('favicon.ico')
  17. self.set_Line()
  18. self.set_text()
  19. self.set_layout()
  20. self.set_others()
2、set_Line函数

绘制两条白色分割线

self.CanvasBg.create_line(0, 73, 405, 73, fill=‘white’)
是指画一条从(0,73)到(405,73)的白色线段

  1. def set_Line(self):
  2. self.CanvasBg = tk.Canvas(self.window, bg='#f9aea8', width=150, height=150)
  3. self.CanvasBg.place(x=0, y=0)
  4. self.CanvasBg.create_line(0, 50, 150, 50, fill='white')
  5. self.CanvasBg.create_line(0, 100, 150, 100, fill='white')
3、set_text函数

创建Label控件,设置字体、颜色、大小等。需要根据是否超时,判断显示哪个标题

  1. def set_text(self):
  2. s = self.endtime - int(time.time())
  3. if s>0 :
  4. t=self.Target
  5. else :
  6. t=self.overTarget
  7. self.LabelTitle = tk.Label(self.window, text=f'距离 {t} ', bg='#f9aea8',fg='white', font=('方正青铜体简体', 10))
  8. self.LabelDays = tk.Label(self.window, text='00 天', bg='#f9aea8', fg='white', font=('方正青铜体简体', 10))
  9. self.LabelHours = tk.Label(self.window, text='00 时', bg='#f9aea8', fg='white', font=('方正青铜体简体', 10))
  10. self.LabelMins = tk.Label(self.window, text='00 分', bg='#f9aea8', fg='white', font=('方正青铜体简体', 10))
  11. self.LabelS = tk.Label(self.window, text='共计 000,000 秒', bg='#f9aea8', fg='white', font=('方正青铜体简体', 10))
4、set_layout函数

使用pack控件布局

  1. def set_layout(self):
  2. tk.Label(self.window, bg='#f9aea8').pack(expand=True)# 仅用来占地方,避免其它控件位置过于靠上
  3. self.LabelTitle.pack(expand=True)
  4. self.LabelDays.pack(expand=True)
  5. self.LabelHours.pack(expand=True)
  6. self.LabelMins.pack(expand=True)
  7. self.LabelS.pack(expand=True)
  8. tk.Label(self.window, bg='#f9aea8').pack()# 仅用来占地方,避免其它控件位置过于靠下
5、set_others函数

设置窗口固定宽高,以及绑定事件

# 给窗口绑定事件

移动事件:可拖动窗口移动;单击事件:获取窗体坐标并保存。

# 给Label控件绑定事件

双击事件:弹出编辑窗口

  1. def set_others(self):
  2. # 第一个参数是宽,第二个参数是高,如果要固定窗口宽与高,可以使用resizeable(0,0)。
  3. self.window.resizable(False, False)
  4. # 窗体控件——显示控件
  5. # 在Windows平台下,这个函数的作用,视觉上窗体整个边框消失(没有最小化最大化关闭这几个按钮,也无法拖动这个窗体),
  6. # 程序的窗体在Windows系统任务栏上也消失(看不到有这么一个程序在运行),但是Alt+F4关闭窗体的功能还存在。
  7. # self.window.overrideredirect(True)
  8. # 窗口移动事件
  9. self.window.bind("<B1-Motion>", self.move)
  10. # 单击事件
  11. self.window.bind("<Button-1>", self.get_point)
  12. # 双击事件
  13. self.LabelTitle.bind("<Double-Button-1>", self.update_window)
  14. Thread(target=get_time,args=(self,)).start()
6、update_window函数

绘制编辑窗口,自动显示当前标题、时间、超时标题。使用grid布局

row是第几行,column是第几列
padx 是单元格左右间距
pady 是单元格上下间距
ipadx是单元格内部元素与单元格左右的间距
ipady是单元格内部元素与单元格上下的间距

  1. def update_window(self,event):
  2. self.UpdateWindow = tk.Toplevel()
  3. self.UpdateWindow['bg'] = '#f6ccb4'
  4. self.UpdateWindow.title('修 改')
  5. self.UpdateWindow.geometry('240x180+600+100')
  6. self.UpdateWindow.iconbitmap('favicon.ico')
  7. self.EntryTarget = tk.Entry(self.UpdateWindow)#目标输入框
  8. self.EntryEndtime = tk.Entry(self.UpdateWindow)#目标时间输入框
  9. self.EntryOverTarget = tk.Entry(self.UpdateWindow)#目标超时输入框
  10. # 写入当前的目标和时间
  11. self.EntryTarget.insert(0,self.Target)
  12. self.EntryEndtime.insert(0,self.t)
  13. self.EntryOverTarget.insert(0,self.overTarget)
  14. # 控件布局
  15. tk.Label(self.UpdateWindow,bg='#f6ccb4', text='目 标').grid(row=1, column=1,pady=10,padx=5)
  16. self.EntryTarget.grid(row=1,column=2)
  17. tk.Label(self.UpdateWindow,bg='#f6ccb4', text='时间').grid(row=2,column=1,pady=10,padx=5)
  18. self.EntryEndtime.grid(row=2,column=2)
  19. tk.Label(self.UpdateWindow,bg='#f6ccb4', text='超时标题').grid(row=3,column=1,pady=10,padx=5)
  20. self.EntryOverTarget.grid(row=3,column=2)
  21. tk.Button(self.UpdateWindow, bg='#f9aea8', fg='white',width='19', text='修改',command=self.update).grid(row=4,column=2)
7、update函数

  将修改的内容更新到父窗口,并将时间戳转为日期格式后,更新config.txt

  1. def update(self):# 用于将修改更新到父窗口
  2. if self.EntryEndtime.get():
  3. self.Target = self.EntryTarget.get()
  4. self.overTarget = self.EntryOverTarget.get()
  5. self.t = self.EntryEndtime.get()
  6. s_t = time.strptime(self.t, "%Y-%m-%d %H:%M:%S")
  7. self.endtime = int(time.mktime(s_t))
  8. self.UpdateWindow.destroy()
  9. with open('config.txt', 'w', encoding='utf8') as f:
  10. f.write(f'{self.Target}\n{self.t}\n{self.overTarget}')
8、事件函数

重新计算并设置窗口的位置

event.x :鼠标当前位置横坐标,相对于组件左上角

event.y :鼠标当前位置纵坐标,相对于组件左上角

self.x :窗口之前位置横坐标,相对于组件左上角

self.y :窗口之前位置纵坐标,相对于组件左上角

winfo_x() :获取当前窗口左上角相对于显示器左上角的横坐标

winfo_y() :获取当前窗口左上角相对于显示器左上角的纵坐标

  1. def move(self, event):
  2. """窗口移动事件"""
  3. new_x = (event.x - self.x) + self.window.winfo_x()
  4. new_y = (event.y - self.y) + self.window.winfo_y()
  5. s = f"{self.window_size}+{new_x}+{new_y}"
  6. self.window.geometry(s)
  7. def get_point(self, event):
  8. """获取当前窗口位置并保存"""
  9. self.x, self.y = event.x, event.y
9、get_time函数

主要根据时间截之差,计算相差的天数、小时数、分钟数、秒数。在计算之前,判断是否超时,确定标题和时间

  1. def get_time(handle):
  2. while True:
  3. s = handle.endtime - int(time.time())
  4. if s<0 :
  5. # 若已超时
  6. s = int(time.time()) - handle.endtime
  7. t = handle.overTarget
  8. else :
  9. t = handle.Target
  10. days = int(s / 86400)
  11. hours = int((s % 86400) / 3600)
  12. mins = int((s % 3600) / 60)
  13. handle.LabelTitle.config(text=f'距离 {t} ')
  14. handle.LabelDays.config(text=f'{days} 天')
  15. handle.LabelHours.config(text=f'{hours} 时')
  16. handle.LabelMins.config(text=f'{mins} 分')
  17. handle.LabelS.config(text=f'共计 {format(s,",")} 秒')
  18. time.sleep(1)

三、完整代码

# 打包:在当前py文件的目录下打开cmd,输入命令

pyinstaller -F -w -i favicon.ico de_desktop.py

### -i favicon.ico 指定应用图标  de_desktop.py 需要打包的文件名

# 命令行运行代码: python de_desktop.py

  1. import tkinter as tk
  2. from threading import Thread
  3. import time
  4. def get_time(handle):
  5. while True:
  6. s = handle.endtime - int(time.time())
  7. if s<0 :
  8. # 若已超时
  9. s = int(time.time()) - handle.endtime
  10. t = handle.overTarget
  11. else :
  12. t = handle.Target
  13. days = int(s / 86400)
  14. hours = int((s % 86400) / 3600)
  15. mins = int((s % 3600) / 60)
  16. handle.LabelTitle.config(text=f'距离 {t} ')
  17. handle.LabelDays.config(text=f'{days} 天')
  18. handle.LabelHours.config(text=f'{hours} 时')
  19. handle.LabelMins.config(text=f'{mins} 分')
  20. handle.LabelS.config(text=f'共计 {format(s,",")} 秒')
  21. time.sleep(1)
  22. class APP():
  23. def __init__(self):
  24. with open('config.txt','r',encoding='utf8') as f:
  25. self.Target = f.readline().strip()
  26. self.t = f.readline().strip()
  27. self.overTarget = f.readline().strip()
  28. s_t = time.strptime(self.t, "%Y-%m-%d %H:%M:%S") # 返回元祖
  29. self.endtime = int(time.mktime(s_t))
  30. self.window = tk.Tk()
  31. self.x, self.y = 0, 0
  32. self.window_size = '150x150'
  33. # 窗口标题
  34. self.window.title('桌面倒计时')
  35. # 窗口的宽与高,单位是像素。以及位置坐标
  36. self.window.geometry(f"{self.window_size}+1000+100")
  37. # 窗口左上角图标
  38. self.window.iconbitmap('favicon.ico')
  39. self.set_Line()
  40. self.set_text()
  41. self.set_layout()
  42. self.set_others()
  43. def set_Line(self):
  44. self.CanvasBg = tk.Canvas(self.window, bg='#f9aea8', width=150, height=150)
  45. self.CanvasBg.place(x=0, y=0)
  46. self.CanvasBg.create_line(0, 50, 150, 50, fill='white')
  47. self.CanvasBg.create_line(0, 100, 150, 100, fill='white')
  48. def set_text(self):
  49. s = self.endtime - int(time.time())
  50. if s>0 :
  51. t=self.Target
  52. else :
  53. t=self.overTarget
  54. self.LabelTitle = tk.Label(self.window, text=f'距离 {t} ', bg='#f9aea8',fg='white', font=('方正青铜体简体', 10))
  55. self.LabelDays = tk.Label(self.window, text='00 天', bg='#f9aea8', fg='white', font=('方正青铜体简体', 10))
  56. self.LabelHours = tk.Label(self.window, text='00 时', bg='#f9aea8', fg='white', font=('方正青铜体简体', 10))
  57. self.LabelMins = tk.Label(self.window, text='00 分', bg='#f9aea8', fg='white', font=('方正青铜体简体', 10))
  58. self.LabelS = tk.Label(self.window, text='共计 000,000 秒', bg='#f9aea8', fg='white', font=('方正青铜体简体', 10))
  59. def set_layout(self):
  60. tk.Label(self.window, bg='#f9aea8').pack(expand=True)# 仅用来占地方,避免其它控件位置过于靠上
  61. self.LabelTitle.pack(expand=True)
  62. self.LabelDays.pack(expand=True)
  63. self.LabelHours.pack(expand=True)
  64. self.LabelMins.pack(expand=True)
  65. self.LabelS.pack(expand=True)
  66. tk.Label(self.window, bg='#f9aea8').pack()# 仅用来占地方,避免其它控件位置过于靠下
  67. def set_others(self):
  68. # 第一个参数是宽,第二个参数是高,如果要固定窗口宽与高,可以使用resizeable(0,0)。
  69. self.window.resizable(False, False)
  70. # 窗体控件——显示控件
  71. # 在Windows平台下,这个函数的作用,视觉上窗体整个边框消失(没有最小化最大化关闭这几个按钮,也无法拖动这个窗体),
  72. # 程序的窗体在Windows系统任务栏上也消失(看不到有这么一个程序在运行),但是Alt+F4关闭窗体的功能还存在。
  73. # self.window.overrideredirect(True)
  74. # 窗口移动事件
  75. self.window.bind("<B1-Motion>", self.move)
  76. # 单击事件
  77. self.window.bind("<Button-1>", self.get_point)
  78. # 双击事件
  79. self.LabelTitle.bind("<Double-Button-1>", self.update_window)
  80. Thread(target=get_time,args=(self,)).start()
  81. def update_window(self,event):
  82. self.UpdateWindow = tk.Toplevel()
  83. self.UpdateWindow['bg'] = '#f6ccb4'
  84. self.UpdateWindow.title('修 改')
  85. self.UpdateWindow.geometry('240x180+600+100')
  86. self.UpdateWindow.iconbitmap('favicon.ico')
  87. self.EntryTarget = tk.Entry(self.UpdateWindow)#目标输入框
  88. self.EntryEndtime = tk.Entry(self.UpdateWindow)#目标时间输入框
  89. self.EntryOverTarget = tk.Entry(self.UpdateWindow)#目标超时输入框
  90. # 写入当前的目标和时间
  91. self.EntryTarget.insert(0,self.Target)
  92. self.EntryEndtime.insert(0,self.t)
  93. self.EntryOverTarget.insert(0,self.overTarget)
  94. # 控件布局
  95. tk.Label(self.UpdateWindow,bg='#f6ccb4', text='目 标').grid(row=1, column=1,pady=10,padx=5)
  96. self.EntryTarget.grid(row=1,column=2)
  97. tk.Label(self.UpdateWindow,bg='#f6ccb4', text='时间').grid(row=2,column=1,pady=10,padx=5)
  98. self.EntryEndtime.grid(row=2,column=2)
  99. tk.Label(self.UpdateWindow,bg='#f6ccb4', text='超时标题').grid(row=3,column=1,pady=10,padx=5)
  100. self.EntryOverTarget.grid(row=3,column=2)
  101. tk.Button(self.UpdateWindow, bg='#f9aea8', fg='white',width='19', text='修改',command=self.update).grid(row=4,column=2)
  102. def update(self):# 用于将修改更新到父窗口
  103. if self.EntryEndtime.get():
  104. self.Target = self.EntryTarget.get()
  105. self.overTarget = self.EntryOverTarget.get()
  106. self.t = self.EntryEndtime.get()
  107. s_t = time.strptime(self.t, "%Y-%m-%d %H:%M:%S")
  108. self.endtime = int(time.mktime(s_t))
  109. self.UpdateWindow.destroy()
  110. with open('config.txt', 'w', encoding='utf8') as f:
  111. f.write(f'{self.Target}\n{self.t}\n{self.overTarget}')
  112. def move(self, event):
  113. """窗口移动事件"""
  114. new_x = (event.x - self.x) + self.window.winfo_x()
  115. new_y = (event.y - self.y) + self.window.winfo_y()
  116. s = f"{self.window_size}+{new_x}+{new_y}"
  117. self.window.geometry(s)
  118. def get_point(self, event):
  119. """获取当前窗口位置并保存"""
  120. self.x, self.y = event.x, event.y
  121. if __name__ == '__main__':
  122. myapp = APP()
  123. # mainloop( )方法可以让程序继续执行,同时进入等待与处理窗口事件,若是单击窗口右上方的“关闭”按钮,此程序才会结束。
  124. myapp.window.mainloop()

参考:桌面美化 Python tkinterhttps://img-home.csdnimg.cn/images/20230724024159.png?origin_url=%E5%80%92%E8%AE%A1%E6%97%B6&pos_id=K8OrFhaS工具_python桌面https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=%E5%80%92%E8%AE%A1%E6%97%B6&pos_id=K8OrFhaS-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/qq_43495412/article/details/113099677

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/498653
推荐阅读
相关标签
  

闽ICP备14008679号