基于Tkinter的桌面倒计时,打工人必备!

一、效果展示

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

二、代码详情

1、初始化

从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()
2、set_Line函数

绘制两条白色分割线

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')
3、set_text函数

创建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))
4、set_layout函数

使用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()# 仅用来占地方,避免其它控件位置过于靠下
5、set_others函数

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

# 给窗口绑定事件

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

# 给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()
6、update_window函数

绘制编辑窗口,自动显示当前标题、时间、超时标题。使用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)
7、update函数

  将修改的内容更新到父窗口,并将时间戳转为日期格式后,更新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}')
8、事件函数

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

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
9、get_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)

三、完整代码

# 打包:在当前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()

参考:桌面美化 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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
引用\[1\]中的代码是一个使用tkinter实现倒计时器。代码中创建了一个继承自Tk的类MyApp,其中初始化了窗口的标题、大小和图标,并创建了一个IntVar变量用于保存倒计时数。通过Label显示倒计时数,并通过Button触发倒计时的逻辑。当按钮被点击时,倒计时数减1,直到倒计时结束。\[1\] 引用\[2\]中的代码也是使用tkinter实现倒计时器。代码中创建了一个窗口,并定义了一个全局变量allSeconds用于保存倒计时的总秒数。通过Button触发倒计时的逻辑,每秒更新倒计时的显示。当倒计时结束时,弹出提示框显示倒计时结束的消息。\[2\] 如果你想要显示倒计时,可以使用上述代码中的任意一段。你可以根据自己的需求选择使用哪一段代码,并根据需要进行适当的修改。 #### 引用[.reference_title] - *1* *3* [python,根据tkinter计数器案例,写了个倒计时器](https://blog.csdn.net/qq_29061315/article/details/125400316)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [tkinter 实现倒计时(1小时)](https://blog.csdn.net/qq_52722885/article/details/128642899)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DytLisa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值