自己写了个python的项目日期管理工具,有么有师傅有兴趣来一起写加一些功能,用代码回复我,或者私信我
import tkinter as tk
from tkinter import ttk, messagebox
from datetime import datetime, timedelta
import json
import os
import sys
class ProjectManager:
def __init__(self, master):
self.master = master
# 设置窗口的背景色
self.master.config(bg="#f5f5f5")
self.master.title("备忘录")
self.master.geometry("800x500")
# 创建一个 Label,用于显示标题
title_label = tk.Label(self.master, text="小王的备忘录", font=("Arial", 20), bg="#f5f5f5")
title_label.pack(pady=5)
#禁止窗口变大变小
self.master.resizable(width=False, height=False)
# 获取用户文档文件夹路径
#self.documents_folder = os.path.dirname(os.path.abspath(__file__))
if getattr(sys, 'frozen', False):
# 如果程序是被pyinstaller打包成exe文件运行的
self.documents_folder = os.path.dirname(sys.executable)
else:
# 如果程序是通过Python直接运行的
self.documents_folder = os.path.dirname(os.path.abspath(__file__))
self.selected_project_index = None
self.load_projects()
self.create_widgets()
self.update_reminder()
self.project_listbox.bind('<<ListboxSelect>>', self.show_project_details)
def load_projects(self):
# 获取项目文件的路径
projects_file = os.path.join(self.documents_folder, 'projects.txt')
# 如果文件不存在,创建一个空文件
if not os.path.exists(projects_file):
with open(projects_file, 'w', encoding='UTF-8') as f:
f.write('[]')
# 加载项目文件
with open(projects_file, 'r', encoding='UTF-8') as f:
self.projects = json.load(f)
self.save_projects()
def save_projects(self):
# 获取项目文件的路径
projects_file = os.path.join(self.documents_folder, 'projects.txt')
# 保存项目文件
with open(projects_file, 'w', encoding='UTF-8') as f:
json.dump(self.projects, f, ensure_ascii=False)
def create_widgets(self):
self.left_frame = tk.Frame(self.master, bg="#F9F9F9", borderwidth=2, relief='groove')
self.left_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=10, pady=10)
self.right_frame = tk.Frame(self.master, bg="#EEEEEE", borderwidth=2, relief='groove')
self.right_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=10, pady=10)
self.master.grid_columnconfigure(0, weight=1)
self.master.grid_columnconfigure(1, weight=3)
style = ttk.Style()
style.theme_use('clam')
style.configure('TFrame', background='#f0f0f0', borderwidth=5, relief='raised')
style.configure('TButton', font=('TkDefaultFont', 12), background='#4c4c4c', foreground='white', borderwidth=1, padx=10, pady=5, relief='flat', anchor='center')
style.map('TButton', background=[('active', '#3E8E41')], foreground=[('active', 'white')])
style.configure('TLabel', font=('TkDefaultFont', 12), background='#f0f0f0', foreground='#333333')
style.configure('TEntry', font=('TkDefaultFont', 12), background='#F5F5F5', foreground='#333333', borderwidth=1, relief='solid', highlightcolor='#4d90fe')
style.map('TEntry', relief=[('focus', 'solid'), ('!focus', 'groove')])
style.configure('TCombobox', font=('TkDefaultFont', 12), background='#F5F5F5', foreground='#333333', borderwidth=1, relief='solid', arrowcolor='#333333', highlightcolor='#4d90fe')
style.map('TCombobox', relief=[('focus', 'solid'), ('!focus', 'groove')])
style.configure('TCheckbutton', font=('TkDefaultFont', 12), background='#EEEEEE', foreground='#333333')
style.map('TListbox', background=[('active', '#c0c0c0')]) # 鼠标悬浮时的颜色
self.project_listbox = tk.Listbox(self.left_frame, font=('TkDefaultFont', 12), background='#EEEEEE', selectbackground='#4CAF50', selectforeground='white')
self.project_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5, pady=5)
self.project_listbox_scrollbar = tk.Scrollbar(self.left_frame, orient=tk.VERTICAL, command=self.project_listbox.yview)
self.project_listbox_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
self.project_listbox.config(yscrollcommand=self.project_listbox_scrollbar.set)
self.project_listbox.bind("<<ListboxSelect>>", self.show_project_details)
self.left_frame.bind("<Configure>", lambda e: self.left_frame.configure(background="#f8f8f8"))
self.right_frame.bind("<Configure>", lambda e: self.right_frame.configure(background="#f8f8f8"))
self.project_listbox.config(yscrollcommand=self.project_listbox_scrollbar.set)
self.project_listbox_scrollbar.config(command=self.project_listbox.yview)
for project in self.projects:
self.project_listbox.insert(tk.END, project["name"])
self.project_name_label = tk.Label(self.right_frame, text="项目名称", font=('TkDefaultFont', 12, 'bold'))
self.project_name_label.grid(row=0, column=0, padx=5, pady=5, sticky='w')
self.project_name_entry = ttk.Entry(self.right_frame, width=40, style="TEntry")
self.project_name_entry.grid(row=0, column=1, padx=5, pady=5, sticky='w')
self.project_created_date_label = tk.Label(self.right_frame, text="创建日期", font=('TkDefaultFont', 12, 'bold'))
self.project_created_date_label.grid(row=1, column=0, padx=5, pady=5, sticky='w')
self.project_created_date_entry = ttk.Entry(self.right_frame, width=40, style="TEntry")
self.project_created_date_entry.grid(row=1, column=1, padx=5, pady=5, sticky='w')
self.project_due_date_label = tk.Label(self.right_frame, text="截止日期", font=('TkDefaultFont', 12, 'bold'))
self.project_due_date_label.grid(row=2, column=0, padx=5, pady=5, sticky='w')
self.project_due_date_entry = ttk.Entry(self.right_frame, width=40)
self.project_due_date_entry.grid(row=2, column=1, padx=5, pady=5, sticky='w')
self.project_content_label = tk.Label(self.right_frame, text="项目内容", font=('TkDefaultFont', 12, 'bold'))
self.project_content_label.grid(row=3, column=0, padx=5, pady=5, sticky='w')
self.project_content_text = tk.Text(self.right_frame, wrap=tk.WORD, width=40, height=10)
self.project_content_text.grid(row=3, column=1, padx=5, pady=5, sticky='w')
self.reminder_var = tk.BooleanVar()
self.reminder_checkbutton = ttk.Checkbutton(self.right_frame, text="提醒", variable=self.reminder_var, style='TCheckbutton')
self.reminder_checkbutton.grid(row=4, column=1, padx=5, pady=5, sticky='w')
self.project_category_label = tk.Label(self.right_frame, text="备注", font=('TkDefaultFont', 12, 'bold'))
self.project_category_label.grid(row=5, column=0, padx=5, pady=5, sticky='w')
self.project_category_entry = ttk.Entry(self.right_frame, width=40)
self.project_category_entry.grid(row=5, column=1, padx=5, pady=5, sticky='w')
self.project_priority_label = tk.Label(self.right_frame, text="优先级", font=('TkDefaultFont', 12, 'bold'))
self.project_priority_label.grid(row=6, column=0, padx=5, pady=5, sticky='w')
self.priority_var = tk.StringVar()
self.priority_combobox = ttk.Combobox(self.right_frame, textvariable=self.priority_var, width=38, values=("低", "中", "高"))
self.priority_combobox.grid(row=6, column=1, padx=5, pady=5, sticky='w')
self.save_project_button = ttk.Button(self.right_frame, text="更改", command=self.save_edits)
self.save_project_button.grid(row=7, column=1, padx=5, pady=5, sticky='w')
self.delete_project_button = ttk.Button(self.right_frame, text="删除", command=self.delete_project)
self.delete_project_button.grid(row=7, column=1, padx=100, pady=5, sticky='w')
self.days_left_label = tk.Label(self.right_frame, text="剩余天数", font=('TkDefaultFont', 12, 'bold'))
self.days_left_label.grid(row=9, column=0, padx=5, pady=5, sticky='w')
self.days_left_var = tk.StringVar()
self.days_left_entry = ttk.Entry(self.right_frame, textvariable=self.days_left_var, width=40, state="readonly")
self.days_left_entry.grid(row=9, column=1, padx=5, pady=5, sticky='w')
# 在左侧面板中添加添加项目和保存项目按钮
self.add_project_button = ttk.Button(self.left_frame, text="添加项目", command=self.add_project)
self.add_project_button.pack(side=tk.TOP, pady=5)
self.save_all_projects_button = ttk.Button(self.left_frame, text="保存所有项目", command=self.save_projects)
self.save_all_projects_button.pack(side=tk.TOP, pady=5)
def show_project_details(self, event):
selected_project = self.project_listbox.curselection()
if selected_project:
self.selected_project_index = selected_project[0]
project = self.projects[self.selected_project_index]
self.project_name_entry.delete(0, tk.END)
self.project_name_entry.insert(0, project["name"])
self.project_created_date_entry.delete(0, tk.END)
self.project_created_date_entry.insert(0, project["created_date"])
self.project_due_date_entry.delete(0, tk.END)
self.project_due_date_entry.insert(0, project["due_date"])
self.project_content_text.delete(1.0, tk.END)
self.project_content_text.insert(1.0, project["content"])
#self.project_content_text.replace(1.0, tk.END, project["content"])
self.project_category_entry.delete(0, tk.END)
self.project_category_entry.insert(0, project["category"])
self.priority_var.set(project["priority"])
self.reminder_var.set(project["reminder"])
self.project_listbox.selection_clear(0, tk.END)
self.project_listbox.selection_set(selected_project) # 重新设置选中项
self.project_listbox.activate(selected_project)
self.update_days_left()
def add_project(self):
new_project = {
"name": "新项目",
"created_date": datetime.now().strftime("%Y-%m-%d"),
"due_date": datetime.now().strftime("%Y-%m-%d"),
"content": "请填写项目内容",
"category": "",
"priority": "低",
"reminder": False
}
self.projects.append(new_project)
self.project_listbox.insert(tk.END, new_project["name"])
def delete_project(self):
selected_project = self.project_listbox.curselection()
if selected_project:
self.project_listbox.delete(selected_project)
self.projects.pop(selected_project[0])
self.save_projects()
def save_edits(self):
try:
if self.selected_project_index is not None:
project = self.projects[self.selected_project_index]
project["name"] = self.project_name_entry.get()
project["created_date"] = datetime.strptime(self.project_created_date_entry.get(), "%Y-%m-%d").date()
project["due_date"] = datetime.strptime(self.project_due_date_entry.get(), "%Y-%m-%d").date()
# 将日期转换为字符串类型
project["created_date"] = project["created_date"].strftime("%Y-%m-%d")
project["due_date"] = project["due_date"].strftime("%Y-%m-%d")
project["content"] = self.project_content_text.get(1.0, tk.END).strip()
project["category"] = self.project_category_entry.get()
project["priority"] = self.priority_var.get()
project["reminder"] = self.reminder_var.get()
self.project_listbox.delete(self.selected_project_index)
self.project_listbox.insert(self.selected_project_index, project["name"])
self.save_projects()
self.update_days_left()
else:
raise ValueError("未选中任何项目")
except ValueError as ve:
print("Error in save_edits:", ve)
messagebox.showerror("错误", "保存更改时发生错误,请确保所有字段都正确填写。")
except Exception as e:
print("Error in save_edits:", e)
messagebox.showerror("错误", "保存更改时发生错误,请检查控制台以获取详细信息。")
def update_reminder(self):
for project in self.projects:
if project["reminder"]:
due_date = datetime.strptime(project["due_date"], "%Y-%m-%d")
days_left = (due_date - datetime.now()).days
if days_left <= 0:
messagebox.showwarning("提醒", f"项目 {project['name']} 已经过期!")
elif days_left <= 1:
messagebox.showinfo("提醒", f"项目 {project['name']} 将在 {days_left} 天后到期!")
def update_days_left(self):
selected_project = self.project_listbox.curselection()
if selected_project:
project = self.projects[selected_project[0]]
due_date = project.get("due_date")
if due_date:
days_left = (datetime.strptime(str(due_date), "%Y-%m-%d") - datetime.now()).days
self.days_left_var.set(str(days_left))
else:
self.days_left_var.set("未设置")
else:
self.days_left_var.set("")
def priority_color(self):
for i, project in enumerate(self.projects):
if project["priority"] == "低":
self.project_listbox.itemconfig(i, {'bg': 'light green'})
elif project["priority"] == "中":
self.project_listbox.itemconfig(i, {'bg': 'yellow'})
elif project["priority"] == "高":
self.project_listbox.itemconfig(i, {'bg': 'red'})
if __name__ == "__main__":
root = tk.Tk()
app = ProjectManager(root)
app.priority_color()
root.mainloop()