事情是这样的,我们班主任想委托我做一个程序,能显示还有几天考试。我立即理解了这个意思,接下了这个项目。
话不多说,来看看这个项目吧——
项目简介
仓库地址:https://gitee.com/yaoqx/desktop-countdown-day
这是 gitee 上这个项目的地址,项目的详细介绍以及使用说明都在上面,欢迎来参观!😝
语言:Python
作者:我,还有我的同学 @a瓦达啃瓜瓜
实现思路
参考这张思维导图,应该能明白大概思路了吧!
完整代码
import tkinter as tk
from tkinter import messagebox as msg
import datetime as dt
from PIL import Image, ImageTk
import sys, osname, date = "暂无", ""
size = 50# 打包exe后的文件路径
def resource_path(relative_path):try:base_path = sys._MEIPASSexcept Exception:base_path = os.path.abspath(".")return os.path.join(base_path, relative_path)# 读取文件中日期
with open(resource_path("data.txt"), "r", encoding="utf-8") as file:data = file.read()data = data.split()# 处理if len(data) != 0:name = data[0]date = data[1]# 窗口初始化
win = tk.Tk()
win.attributes("-transparentcolor", "#F0F0F0") # 透明
win.overrideredirect(True) # 无边框
win.geometry("350x200+1500+30") # 位置:屏幕右上角# 背景图片
def get_img(filename):pic = Image.open(filename).resize((345, 200))return ImageTk.PhotoImage(pic)bg = tk.Canvas(win, width=350, height=200)
img = get_img(resource_path("bg.png"))
bg.create_image(175, 100, image=img)
bg.place(x=175, y=100, anchor="center")day_frm = None
# 更新内容
def update():global day_frm, date, nameif day_frm != None:day_frm.destroy()day_frm = tk.Frame(win, bg="lightyellow")day_frm.pack(anchor="center", fill="both", padx=15, pady=10)# 有日期if not date == "":# 计算剩余天数now = dt.datetime.today()tar = dt.datetime.strptime(date, "%Y.%m.%d")ans = (tar - now).days + 1if ans < 0:ans = "已过"elif ans == 0:ans = "今天!"else:ans = str(ans)if ans == "已过" or ans == "今天!":size = 40elif len(ans) <= 2:size = 60elif len(ans) <= 3:size = 50else:size = 40tk.Label(day_frm, text=ans, bg="lightyellow", font=("黑体", size), justify="right").pack(side="right", padx=15)tk.Label(day_frm, text='\n'+name+'\n\n\n'+date, bg="lightyellow", font=("黑体", 18), justify="left").pack(side="left", padx=20, pady=5)update()# 编辑
def edit():global name, date, day_frmedit_win = tk.Frame(win, bg="lightyellow")edit_win.place(anchor="center", x=175, y=100, width=320, height=170)day_frm.destroy()# 取消def cancel():edit_win.destroy()update()# 文字tk.Label(edit_win, text="名称:", bg="lightyellow", font=("微软雅黑", 12)).grid(row=0, column=0, padx=15, pady=15)tk.Label(edit_win, text="日期:", bg="lightyellow", font=("微软雅黑", 12)).grid(row=1, column=0, padx=12, pady=8)# 输入框entry1 = tk.Entry(edit_win, width="22", font=("等线", 13), highlightcolor="blue")entry1.grid(row=0, column=1, columnspan=2, padx=15, pady=15)entry2 = tk.Entry(edit_win, width="22", font=("等线", 13))entry2.grid(row=1, column=1, columnspan=2, padx=12, pady=8)# 输入提示tk.Label(edit_win, text="如:2024.10.1", bg="lightyellow", fg="darkgrey", font=("微软雅黑", 10)).grid(row=2, column=1)# 确定def ok():global name, datename = entry1.get()date = entry2.get()# 名称为空if name == "":msg.showerror(title="错误", message="名称不能为空!")return# 判断日期是否合法nums = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]tmp = date.split('.')error = Falseif len(tmp) != 3:error = Truefor j, i in enumerate(tmp):# 是否数字if not i.isdigit():error = Truebreaki = int(i)if j == 0: # 年份if i < 2000:error = Trueelif j == 1: # 月份if i <= 0 or i > 12:error = Trueelif j == 2: # 天if (int(tmp[0]) % 4 == 0 and int(tmp[0]) % 100 != 0) or int(tmp[0]) % 400 == 0:nums[2] += 1if i <= 0 or i > nums[int(tmp[1])]:error = Trueif (int(tmp[0]) % 4 == 0 and int(tmp[0]) % 100 != 0) or int(tmp[0]) % 400 == 0:nums[2] -= 1if error:msg.showerror(title="错误", message="请输入正确日期!")return# 更新文件with open(resource_path("data.txt"), "w", encoding="utf-8") as file:file.write(name + " " + date)edit_win.destroy()update()# 按钮tk.Button(edit_win, text="确定", bd=0, bg="lightyellow", activebackground="lightyellow", command=ok, font=("微软雅黑", 12), cursor="hand2", activeforeground="grey").grid(row=3, column=1, padx=10, pady=17)tk.Button(edit_win, text="取消", bd=0, bg="lightyellow", activebackground="lightyellow", command=cancel, font=("微软雅黑", 12), cursor="hand2", activeforeground="grey").grid(row=3, column=2, padx=10, pady=17)# 按钮
btn_frm = tk.Frame(win, bg="lightyellow")
btn_frm.pack(side="bottom", anchor="e", after=day_frm, padx=25, pady=10)# 编辑按钮
add_btn = tk.Button(btn_frm, text="编辑", font=("微软雅黑", 12), command=edit, bd=0, bg="lightyellow", activebackground="lightyellow", cursor="hand2", activeforeground="grey")
add_btn.pack(side="right", anchor="s")# 关闭按钮
def quit():win.destroy()
quit_btn = tk.Button(btn_frm, text="关闭", font=("微软雅黑", 12), command=quit, bd=0, bg="lightyellow", activebackground="lightyellow", cursor="hand2", activeforeground="grey")
quit_btn.pack(side="right", anchor="s")# 置顶按钮
def top():win.wm_attributes("-topmost", True)top_btn["command"] = no_toptop_btn["text"] = "取消置顶"
def no_top():win.wm_attributes("-topmost", False)top_btn["command"] = toptop_btn["text"] = "置顶"top_btn = tk.Button(btn_frm, text="置顶", font=("微软雅黑", 12), command=top, bd=0, bg="lightyellow", activebackground="lightyellow", cursor="hand2", activeforeground="grey")
top_btn.pack(side="right", anchor="s")win.mainloop()
不过有个问题,就是 auto-py-to-exe 库打包成单独的 exe 后会把附加文件放在 appdata 里的一个地方,如果要调用就需要管理员权限才能读取,有时候还会被杀毒软件误以为病毒并删掉文件,不知道有什么办法?
最后,如果有任何 bug 或建议,可以在这里评论或在 gitee 上反馈,如果想要出教程的话,可以评论或私信我,感谢支持!
如果觉得这个项目还不错的话,请点赞收藏,顺便在 gitee 上 star 一下,求求了!