In this tutorial, we will learn how to create a to-do list app with a pie chart in Tkinter to check the number of completed tasks. I hope you will find this helpful.
let’s understand the code with some simple steps:
Step 1: Importing some useful libraries
import tkinter as tk from tkinter import messagebox from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg import matplotlib.pyplot as plt
- Tkinter is used here to create GUI and provide various tools for windows, buttons, and other interface components.
- We use the matplotlib library for creating charts and graphs.
Step 2: Creating the main window
newWindow = tk.Tk()
newWindow.title("To-Do List")
newWindow.geometry("590x800+270+200")
newWindow.configure(bg="#0d1525")
- Tk() creates the main window.
- title() sets the window’s title.
- geometry() sets the window size and position.
- configure() sets the background color to a dark shade.
Step 3: For task completion
def mark_as_done(task_label, done_button):
task_label.config(fg="gray", font=("Helvetica", 18, "overstrike"))
done_button.config(state=tk.DISABLED, disabledforeground="green")
update_task_count()
- mark_as_done() function updates the task label by crossing it out.
Step 4: To delete a task
def delete_task(task_frame):
task_frame.destroy()
update_serial_numbers()
update_task_count()
- task_frame.destroy() removes the task’s frame from the window
- update_serial_numbers() renumbers the tasks after deletion.
- update_task_count() updates the task statistics.
Step 5: To Add a task
def add_task(task=None):
task = task_entry.get().strip() if not task else task
if not task:
messagebox.showwarning("Empty Task", "Task cannot be empty.")
return
task_frame = tk.Frame(task_container, bg="#1d2332", pady=5)
task_number = len(task_container.winfo_children()) + 1
task_label = tk.Label(task_frame, text=f"{task_number}. {task}", bg="#1d2332", fg="#ffffff", font=("Helvetica", 18))
done_button = tk.Button(task_frame, text="Done", command=lambda: mark_as_done(task_label, done_button), bg="#add8e6", fg="#000000", font=("Helvetica", 12))
delete_button = tk.Button(task_frame, text="Delete", command=lambda: delete_task(task_frame), bg="#ff6347", fg="#000000", font=("Helvetica", 12))
task_label.pack(side=tk.LEFT, padx=10)
done_button.pack(side=tk.RIGHT, padx=5)
delete_button.pack(side=tk.RIGHT, padx=5)
task_frame.pack(fill=tk.X, pady=5)
task_entry.delete(0, tk.END)
update_serial_numbers()
update_task_count()
- task_entry.get() fetches the task text that the user has typed.
- add_task() function lets a user add a new task.
Step 6: To update task numbers
def update_serial_numbers():
for index, task_frame in enumerate(task_container.winfo_children()):
task_label = task_frame.winfo_children()[0]
task_text = task_label.cget("text").split(". ", 1)[1]
task_label.config(text=f"{index + 1}. {task_text}")
- This function updates the number in sequence.
Step 7: to remove all tasks
def delete_all_tasks():
for widget in task_container.winfo_children():
widget.destroy()
update_task_count()
- This function deletes all tasks at once.
Step 8: to update task statistics
def update_task_count():
total_tasks = len(task_container.winfo_children())
done_tasks = sum(1 for task_frame in task_container.winfo_children() if "overstrike" in task_frame.winfo_children()[0].cget("font"))
remaining_tasks = total_tasks - done_tasks
total_tasks_label.config(text=f"Total Tasks: {total_tasks}")
remaining_tasks_label.config(text=f"Remaining Tasks: {remaining_tasks}")
done_tasks_label.config(text=f"Completed Tasks: {done_tasks}")
update_pie_chart(total_tasks, remaining_tasks, done_tasks)
- This function calculates the total completed and remaining tasks by analyzing the task frames.
Step 9: to create a pie chart
def update_pie_chart(total_tasks, remaining_tasks, done_tasks):
for widget in pie_chart_frame.winfo_children():
widget.destroy()
if total_tasks == 0:
return
labels = ['Completed Tasks', 'Remaining Tasks']
sizes = [done_tasks, remaining_tasks]
colors = ['#4caf50', '#ffeb3b']
fig, ax = plt.subplots(figsize=(5, 3), dpi=100)
fig.patch.set_facecolor('#0d1525')
ax.pie(sizes, colors=colors, autopct='%1.1f%%', startangle=140)
ax.axis('equal')
canvas_chart = FigureCanvasTkAgg(fig, master=pie_chart_frame)
canvas_chart.draw()
canvas_chart.get_tk_widget().pack()
plt.close(fig)
- This function represents the number of completed and remaining tasks through a pie chart.
Step 10: Saving tasks
def save_tasks():
with open("tasks.txt", "w") as file:
for task_frame in task_container.winfo_children():
task_label = task_frame.winfo_children()[0]
task_text = task_label.cget("text").split(". ", 1)[1]
task_done = "1" if "overstrike" in task_label.cget("font") else "0"
file.write(f"{task_text}|{task_done}\n")
messagebox.showinfo("Save Tasks", "Tasks have been saved successfully.")
- This function saves the tasks to a text file to reload when the app starts.
Step 11: Loading tasks
def load_tasks():
try:
with open("tasks.txt", "r") as file:
for line in file:
task_text, task_done = line.strip().split("|")
add_task(task_text)
if task_done == "1":
task_frame = task_container.winfo_children()[-1]
task_label = task_frame.winfo_children()[0]
done_button = task_frame.winfo_children()[1]
mark_as_done(task_label, done_button)
except FileNotFoundError:
pass
- By using this function, the saved tasks are loaded back into the app when they start.
Step 12: To structure the interface
canvas = tk.Canvas(newWindow, bg="#0d1525")
scrollbar = tk.Scrollbar(newWindow, orient="vertical", command=canvas.yview)
canvas.configure(yscrollcommand=scrollbar.set)
task_container = tk.Frame(canvas, bg="#0d1525")
canvas.create_window((0, 0), window=task_container, anchor="nw")
task_entry = tk.Entry(newWindow, width=35, bg="#1d2332", fg="#ffffff", font=("Helvetica", 22))
task_entry.pack(pady=10)
add_task_button = tk.Button(newWindow, text="Add Task", command=add_task, bg="#add8e6", fg="#000000", font=("Helvetica", 12))
delete_all_button = tk.Button(newWindow, text="Delete All Tasks", command=delete_all_tasks, bg="#ff6347", fg="#000000", font=("Helvetica", 12))
total_tasks_label = tk.Label(newWindow, text="Total Tasks: 0", bg="#0d1525", fg="#ffffff", font=("Helvetica", 14))
remaining_tasks_label = tk.Label(newWindow, text="Remaining Tasks: 0", bg="#0d1525", fg="#ffffff", font=("Helvetica", 14))
done_tasks_label = tk.Label(newWindow, text="Completed Tasks: 0", bg="#0d1525", fg="#ffffff", font=("Helvetica", 14))
pie_chart_frame = tk.Frame(newWindow, bg="#0d1525")
- Here, we are building the user interface.
Step 13: To run the final application
newWindow.mainloop()
- This loop keeps the window open and responsive, waiting for events.
Output:
- Here is our final output:
- ( For more details refer to http://codespeedy.com )
