赞
踩
这是一个基于Tkinter的桌面倒计时,双击第一行弹出修改窗口,可以修改标题、目标时间、超时标题。该工具会自动倒计时,若超时,会自动显示超时标题,并显示超时多长时间。可自由拖动窗口,小巧,很适合期待下班的打工人使用!想拿来就用的朋友可以直接下载打包文件,想进一步了解的同学,请往下看~~
从config.txt中读取标题、目标时间、超时标题。将目标时间转化为时间戳,方便计算。
利用Tk的相关方法设置窗口宽高、标题、位置、图标,绘制窗口等。图标可以更替,要求ico格式
-----------config.txt-----------
下班 还有
2023-11-17 11:53:00
加班 已经
- def __init__(self):
- with open('config.txt','r',encoding='utf8') as f:
- self.Target = f.readline().strip()
- self.t = f.readline().strip()
- self.overTarget = f.readline().strip()
- s_t = time.strptime(self.t, "%Y-%m-%d %H:%M:%S") # 返回元祖
- self.endtime = int(time.mktime(s_t))
- self.window = tk.Tk()
-
- self.x, self.y = 0, 0
- self.window_size = '150x150'
- # 窗口标题
- self.window.title('桌面倒计时')
- # 窗口的宽与高,单位是像素。以及位置坐标
- self.window.geometry(f"{self.window_size}+1000+100")
- # 窗口左上角图标
- self.window.iconbitmap('favicon.ico')
-
- self.set_Line()
- self.set_text()
- self.set_layout()
- self.set_others()
绘制两条白色分割线
self.CanvasBg.create_line(0, 73, 405, 73, fill=‘white’)
是指画一条从(0,73)到(405,73)的白色线段
- def set_Line(self):
- self.CanvasBg = tk.Canvas(self.window, bg='#f9aea8', width=150, height=150)
- self.CanvasBg.place(x=0, y=0)
- self.CanvasBg.create_line(0, 50, 150, 50, fill='white')
- self.CanvasBg.create_line(0, 100, 150, 100, fill='white')
创建Label控件,设置字体、颜色、大小等。需要根据是否超时,判断显示哪个标题
- def set_text(self):
- s = self.endtime - int(time.time())
- if s>0 :
- t=self.Target
- else :
- t=self.overTarget
-
- self.LabelTitle = tk.Label(self.window, text=f'距离 {t} ', bg='#f9aea8',fg='white', font=('方正青铜体简体', 10))
- self.LabelDays = tk.Label(self.window, text='00 天', bg='#f9aea8', fg='white', font=('方正青铜体简体', 10))
- self.LabelHours = tk.Label(self.window, text='00 时', bg='#f9aea8', fg='white', font=('方正青铜体简体', 10))
- self.LabelMins = tk.Label(self.window, text='00 分', bg='#f9aea8', fg='white', font=('方正青铜体简体', 10))
- self.LabelS = tk.Label(self.window, text='共计 000,000 秒', bg='#f9aea8', fg='white', font=('方正青铜体简体', 10))
使用pack控件布局
- def set_layout(self):
- tk.Label(self.window, bg='#f9aea8').pack(expand=True)# 仅用来占地方,避免其它控件位置过于靠上
- self.LabelTitle.pack(expand=True)
- self.LabelDays.pack(expand=True)
- self.LabelHours.pack(expand=True)
- self.LabelMins.pack(expand=True)
- self.LabelS.pack(expand=True)
- tk.Label(self.window, bg='#f9aea8').pack()# 仅用来占地方,避免其它控件位置过于靠下
设置窗口固定宽高,以及绑定事件
# 给窗口绑定事件
移动事件:可拖动窗口移动;单击事件:获取窗体坐标并保存。
# 给Label控件绑定事件
双击事件:弹出编辑窗口
- def set_others(self):
- # 第一个参数是宽,第二个参数是高,如果要固定窗口宽与高,可以使用resizeable(0,0)。
- self.window.resizable(False, False)
- # 窗体控件——显示控件
- # 在Windows平台下,这个函数的作用,视觉上窗体整个边框消失(没有最小化最大化关闭这几个按钮,也无法拖动这个窗体),
- # 程序的窗体在Windows系统任务栏上也消失(看不到有这么一个程序在运行),但是Alt+F4关闭窗体的功能还存在。
- # self.window.overrideredirect(True)
- # 窗口移动事件
- self.window.bind("<B1-Motion>", self.move)
- # 单击事件
- self.window.bind("<Button-1>", self.get_point)
- # 双击事件
- self.LabelTitle.bind("<Double-Button-1>", self.update_window)
- Thread(target=get_time,args=(self,)).start()
绘制编辑窗口,自动显示当前标题、时间、超时标题。使用grid布局
row是第几行,column是第几列
padx 是单元格左右间距
pady 是单元格上下间距
ipadx是单元格内部元素与单元格左右的间距
ipady是单元格内部元素与单元格上下的间距
- def update_window(self,event):
- self.UpdateWindow = tk.Toplevel()
- self.UpdateWindow['bg'] = '#f6ccb4'
- self.UpdateWindow.title('修 改')
- self.UpdateWindow.geometry('240x180+600+100')
- self.UpdateWindow.iconbitmap('favicon.ico')
-
-
- self.EntryTarget = tk.Entry(self.UpdateWindow)#目标输入框
- self.EntryEndtime = tk.Entry(self.UpdateWindow)#目标时间输入框
- self.EntryOverTarget = tk.Entry(self.UpdateWindow)#目标超时输入框
- # 写入当前的目标和时间
- self.EntryTarget.insert(0,self.Target)
- self.EntryEndtime.insert(0,self.t)
- self.EntryOverTarget.insert(0,self.overTarget)
- # 控件布局
- tk.Label(self.UpdateWindow,bg='#f6ccb4', text='目 标').grid(row=1, column=1,pady=10,padx=5)
- self.EntryTarget.grid(row=1,column=2)
- tk.Label(self.UpdateWindow,bg='#f6ccb4', text='时间').grid(row=2,column=1,pady=10,padx=5)
- self.EntryEndtime.grid(row=2,column=2)
- tk.Label(self.UpdateWindow,bg='#f6ccb4', text='超时标题').grid(row=3,column=1,pady=10,padx=5)
- self.EntryOverTarget.grid(row=3,column=2)
- tk.Button(self.UpdateWindow, bg='#f9aea8', fg='white',width='19', text='修改',command=self.update).grid(row=4,column=2)
将修改的内容更新到父窗口,并将时间戳转为日期格式后,更新config.txt
- def update(self):# 用于将修改更新到父窗口
- if self.EntryEndtime.get():
- self.Target = self.EntryTarget.get()
- self.overTarget = self.EntryOverTarget.get()
- self.t = self.EntryEndtime.get()
- s_t = time.strptime(self.t, "%Y-%m-%d %H:%M:%S")
- self.endtime = int(time.mktime(s_t))
-
- self.UpdateWindow.destroy()
- with open('config.txt', 'w', encoding='utf8') as f:
- f.write(f'{self.Target}\n{self.t}\n{self.overTarget}')
重新计算并设置窗口的位置
event.x :鼠标当前位置横坐标,相对于组件左上角
event.y :鼠标当前位置纵坐标,相对于组件左上角
self.x :窗口之前位置横坐标,相对于组件左上角
self.y :窗口之前位置纵坐标,相对于组件左上角
winfo_x() :获取当前窗口左上角相对于显示器左上角的横坐标
winfo_y() :获取当前窗口左上角相对于显示器左上角的纵坐标
- def move(self, event):
- """窗口移动事件"""
- new_x = (event.x - self.x) + self.window.winfo_x()
- new_y = (event.y - self.y) + self.window.winfo_y()
- s = f"{self.window_size}+{new_x}+{new_y}"
- self.window.geometry(s)
-
- def get_point(self, event):
- """获取当前窗口位置并保存"""
- self.x, self.y = event.x, event.y
主要根据时间截之差,计算相差的天数、小时数、分钟数、秒数。在计算之前,判断是否超时,确定标题和时间
- def get_time(handle):
- while True:
- s = handle.endtime - int(time.time())
- if s<0 :
- # 若已超时
- s = int(time.time()) - handle.endtime
- t = handle.overTarget
- else :
- t = handle.Target
-
- days = int(s / 86400)
- hours = int((s % 86400) / 3600)
- mins = int((s % 3600) / 60)
- handle.LabelTitle.config(text=f'距离 {t} ')
- handle.LabelDays.config(text=f'{days} 天')
- handle.LabelHours.config(text=f'{hours} 时')
- handle.LabelMins.config(text=f'{mins} 分')
- handle.LabelS.config(text=f'共计 {format(s,",")} 秒')
-
- time.sleep(1)
# 打包:在当前py文件的目录下打开cmd,输入命令
pyinstaller -F -w -i favicon.ico de_desktop.py
### -i favicon.ico 指定应用图标 de_desktop.py 需要打包的文件名
# 命令行运行代码: python de_desktop.py
- import tkinter as tk
- from threading import Thread
- import time
-
-
- def get_time(handle):
- while True:
- s = handle.endtime - int(time.time())
- if s<0 :
- # 若已超时
- s = int(time.time()) - handle.endtime
- t = handle.overTarget
- else :
- t = handle.Target
-
- days = int(s / 86400)
- hours = int((s % 86400) / 3600)
- mins = int((s % 3600) / 60)
- handle.LabelTitle.config(text=f'距离 {t} ')
- handle.LabelDays.config(text=f'{days} 天')
- handle.LabelHours.config(text=f'{hours} 时')
- handle.LabelMins.config(text=f'{mins} 分')
- handle.LabelS.config(text=f'共计 {format(s,",")} 秒')
-
- time.sleep(1)
-
-
- class APP():
- def __init__(self):
- with open('config.txt','r',encoding='utf8') as f:
- self.Target = f.readline().strip()
- self.t = f.readline().strip()
- self.overTarget = f.readline().strip()
- s_t = time.strptime(self.t, "%Y-%m-%d %H:%M:%S") # 返回元祖
- self.endtime = int(time.mktime(s_t))
- self.window = tk.Tk()
-
- self.x, self.y = 0, 0
- self.window_size = '150x150'
- # 窗口标题
- self.window.title('桌面倒计时')
- # 窗口的宽与高,单位是像素。以及位置坐标
- self.window.geometry(f"{self.window_size}+1000+100")
- # 窗口左上角图标
- self.window.iconbitmap('favicon.ico')
-
- self.set_Line()
- self.set_text()
- self.set_layout()
- self.set_others()
-
- def set_Line(self):
- self.CanvasBg = tk.Canvas(self.window, bg='#f9aea8', width=150, height=150)
- self.CanvasBg.place(x=0, y=0)
- self.CanvasBg.create_line(0, 50, 150, 50, fill='white')
- self.CanvasBg.create_line(0, 100, 150, 100, fill='white')
-
- def set_text(self):
- s = self.endtime - int(time.time())
- if s>0 :
- t=self.Target
- else :
- t=self.overTarget
-
- self.LabelTitle = tk.Label(self.window, text=f'距离 {t} ', bg='#f9aea8',fg='white', font=('方正青铜体简体', 10))
- self.LabelDays = tk.Label(self.window, text='00 天', bg='#f9aea8', fg='white', font=('方正青铜体简体', 10))
- self.LabelHours = tk.Label(self.window, text='00 时', bg='#f9aea8', fg='white', font=('方正青铜体简体', 10))
- self.LabelMins = tk.Label(self.window, text='00 分', bg='#f9aea8', fg='white', font=('方正青铜体简体', 10))
- self.LabelS = tk.Label(self.window, text='共计 000,000 秒', bg='#f9aea8', fg='white', font=('方正青铜体简体', 10))
-
- def set_layout(self):
- tk.Label(self.window, bg='#f9aea8').pack(expand=True)# 仅用来占地方,避免其它控件位置过于靠上
- self.LabelTitle.pack(expand=True)
- self.LabelDays.pack(expand=True)
- self.LabelHours.pack(expand=True)
- self.LabelMins.pack(expand=True)
- self.LabelS.pack(expand=True)
- tk.Label(self.window, bg='#f9aea8').pack()# 仅用来占地方,避免其它控件位置过于靠下
-
- def set_others(self):
- # 第一个参数是宽,第二个参数是高,如果要固定窗口宽与高,可以使用resizeable(0,0)。
- self.window.resizable(False, False)
- # 窗体控件——显示控件
- # 在Windows平台下,这个函数的作用,视觉上窗体整个边框消失(没有最小化最大化关闭这几个按钮,也无法拖动这个窗体),
- # 程序的窗体在Windows系统任务栏上也消失(看不到有这么一个程序在运行),但是Alt+F4关闭窗体的功能还存在。
- # self.window.overrideredirect(True)
- # 窗口移动事件
- self.window.bind("<B1-Motion>", self.move)
- # 单击事件
- self.window.bind("<Button-1>", self.get_point)
- # 双击事件
- self.LabelTitle.bind("<Double-Button-1>", self.update_window)
- Thread(target=get_time,args=(self,)).start()
-
- def update_window(self,event):
- self.UpdateWindow = tk.Toplevel()
- self.UpdateWindow['bg'] = '#f6ccb4'
- self.UpdateWindow.title('修 改')
- self.UpdateWindow.geometry('240x180+600+100')
- self.UpdateWindow.iconbitmap('favicon.ico')
-
-
- self.EntryTarget = tk.Entry(self.UpdateWindow)#目标输入框
- self.EntryEndtime = tk.Entry(self.UpdateWindow)#目标时间输入框
- self.EntryOverTarget = tk.Entry(self.UpdateWindow)#目标超时输入框
- # 写入当前的目标和时间
- self.EntryTarget.insert(0,self.Target)
- self.EntryEndtime.insert(0,self.t)
- self.EntryOverTarget.insert(0,self.overTarget)
- # 控件布局
- tk.Label(self.UpdateWindow,bg='#f6ccb4', text='目 标').grid(row=1, column=1,pady=10,padx=5)
- self.EntryTarget.grid(row=1,column=2)
- tk.Label(self.UpdateWindow,bg='#f6ccb4', text='时间').grid(row=2,column=1,pady=10,padx=5)
- self.EntryEndtime.grid(row=2,column=2)
- tk.Label(self.UpdateWindow,bg='#f6ccb4', text='超时标题').grid(row=3,column=1,pady=10,padx=5)
- self.EntryOverTarget.grid(row=3,column=2)
- tk.Button(self.UpdateWindow, bg='#f9aea8', fg='white',width='19', text='修改',command=self.update).grid(row=4,column=2)
-
- def update(self):# 用于将修改更新到父窗口
- if self.EntryEndtime.get():
- self.Target = self.EntryTarget.get()
- self.overTarget = self.EntryOverTarget.get()
- self.t = self.EntryEndtime.get()
- s_t = time.strptime(self.t, "%Y-%m-%d %H:%M:%S")
- self.endtime = int(time.mktime(s_t))
-
- self.UpdateWindow.destroy()
- with open('config.txt', 'w', encoding='utf8') as f:
- f.write(f'{self.Target}\n{self.t}\n{self.overTarget}')
-
- def move(self, event):
- """窗口移动事件"""
- new_x = (event.x - self.x) + self.window.winfo_x()
- new_y = (event.y - self.y) + self.window.winfo_y()
- s = f"{self.window_size}+{new_x}+{new_y}"
- self.window.geometry(s)
-
- def get_point(self, event):
- """获取当前窗口位置并保存"""
- self.x, self.y = event.x, event.y
-
-
- if __name__ == '__main__':
- myapp = APP()
- # mainloop( )方法可以让程序继续执行,同时进入等待与处理窗口事件,若是单击窗口右上方的“关闭”按钮,此程序才会结束。
- myapp.window.mainloop()
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。