eshansendo/todosnake-python-task-tamer
0
1```python2import tkinter as tk3from tkinter import messagebox, ttk4import json5import os6 7class TodoApp:8 def __init__(self, root):9 self.root = root10 self.root.title("ToDoSnake ๐")11 self.root.geometry("500x500")12 self.root.resizable(False, False)13 14 # Load or create tasks file15 self.tasks_file = "tasks.json"16 self.tasks = []17 self.load_tasks()18 19 # UI Setup20 self.setup_ui()21 22 def setup_ui(self):23 # Main frame24 main_frame = tk.Frame(self.root, padx=20, pady=20)25 main_frame.pack(fill=tk.BOTH, expand=True)26 27 # Header28 header = tk.Label(main_frame, text="ToDoSnake", font=("Helvetica", 24, "bold"))29 header.pack(pady=(0, 20))30 31 # Input frame32 input_frame = tk.Frame(main_frame)33 input_frame.pack(fill=tk.X, pady=(0, 15))34 35 self.task_entry = tk.Entry(input_frame, font=("Helvetica", 12), width=30)36 self.task_entry.pack(side=tk.LEFT, fill=tk.X, expand=True)37 38 add_btn = tk.Button(input_frame, text="Add", command=self.add_task, bg="#4CAF50", fg="white")39 add_btn.pack(side=tk.RIGHT, padx=(10, 0))40 41 # Task list42 self.task_list = ttk.Treeview(main_frame, columns=("status", "task"), show="headings", height=15)43 self.task_list.heading("status", text="Status")44 self.task_list.heading("task", text="Task")45 self.task_list.column("status", width=80, anchor="center")46 self.task_list.column("task", width=380, anchor="w")47 self.task_list.pack(fill=tk.BOTH, expand=True)48 49 # Button frame50 button_frame = tk.Frame(main_frame)51 button_frame.pack(fill=tk.X, pady=(15, 0))52 53 complete_btn = tk.Button(button_frame, text="Complete", command=self.complete_task, bg="#2196F3", fg="white")54 complete_btn.pack(side=tk.LEFT, padx=(0, 10))55 56 delete_btn = tk.Button(button_frame, text="Delete", command=self.delete_task, bg="#F44336", fg="white")57 delete_btn.pack(side=tk.LEFT)58 59 # Populate tasks60 self.update_task_list()61 62 # Bind double click to edit63 self.task_list.bind("<Double-1>", self.edit_task)64 65 def add_task(self):66 task_text = self.task_entry.get().strip()67 if task_text:68 self.tasks.append({"text": task_text, "completed": False})69 self.save_tasks()70 self.update_task_list()71 self.task_entry.delete(0, tk.END)72 else:73 messagebox.showwarning("Warning", "Please enter a task!")74 75 def complete_task(self):76 selected = self.task_list.selection()77 if selected:78 index = int(selected[0][1:]) - 179 self.tasks[index]["completed"] = not self.tasks[index]["completed"]80 self.save_tasks()81 self.update_task_list()82 83 def delete_task(self):84 selected = self.task_list.selection()85 if selected:86 index = int(selected[0][1:]) - 187 del self.tasks[index]88 self.save_tasks()89 self.update_task_list()90 91 def edit_task(self, event):92 selected = self.task_list.selection()93 if selected:94 index = int(selected[0][1:]) - 195 new_text = simpledialog.askstring("Edit Task", "Edit your task:", initialvalue=self.tasks[index]["text"])96 if new_text and new_text.strip():97 self.tasks[index]["text"] = new_text.strip()98 self.save_tasks()99 self.update_task_list()100 101 def update_task_list(self):102 self.task_list.delete(*self.task_list.get_children())103 for i, task in enumerate(self.tasks):104 status = "โ" if task["completed"] else "โ"105 item = self.task_list.insert("", tk.END, values=(status, task["text"]), iid=f"t{i+1}")106 if task["completed"]:107 self.task_list.item(item, tags=("completed",))108 109 self.task_list.tag_configure("completed", foreground="gray")110 111 def load_tasks(self):112 if os.path.exists(self.tasks_file):113 with open(self.tasks_file, "r") as f:114 self.tasks = json.load(f)115 116 def save_tasks(self):117 with open(self.tasks_file, "w") as f:118 json.dump(self.tasks, f)119 120if __name__ == "__main__":121 root = tk.Tk()122 app = TodoApp(root)123 root.mainloop()124```