Python To-Do List Project Source Code

How to Create To Do List Project In Python Tkinter


How to Create To Do List Project In Python Tkinter



In this Python Tutorial we will see How To Create a To Do List Project in Python using Tkinter.
This application provides a modern interface for managing tasks, allowing users to add, view, delete tasks, and Complete/Completed toggle button .

What We Are Gonna Use In This Project:

- Python Tkinter: GUI framework.
- Visual Studio Editor.





Project Source Code:



     - Build the user interface

Calculates screen dimensions and positions the application window at the center of the user's display.


def center_window(self):
"""Center the window on the screen."""
# Get screen dimensions
screen_width = self.root.winfo_screenwidth()
screen_height = self.root.winfo_screenheight()

# Calculate position
x = (screen_width - 900) // 2
y = (screen_height - 600) // 2

# Set window position
self.root.geometry(f"900x600+{x}+{y}")



     - Custom Window

Creates a custom title bar with application branding and window controls, replacing the default system title bar.


def setup_title_bar(self):
"""Create custom title bar with controls."""
self.title_bar = tk.Frame(self.root, bg=self.special_color, height=40)
self.title_bar.pack(fill=tk.X)

# Application title
title = tk.Label(self.title_bar, text="Tasks Manager",
font=self.title_font,
bg=self.special_color, fg="white")
title.pack(side=tk.LEFT, padx=15)

# Window controls container
controls = tk.Frame(self.title_bar, bg=self.special_color)
controls.pack(side=tk.RIGHT, padx=5)

# Control buttons
buttons = [
("□", lambda: self.toggle_maximize(), "#64748b"),
("x", lambda: self.root.destroy(), "#ef4444")
]

for symbol, command, hover_color, in buttons:
btn = tk.Label(controls, text=symbol, bg=self.special_color,
fg="white", font=self.title_font, padx=10)
btn.pack(side=tk.LEFT)
# Hover effects
btn.bind("<Enter>", lambda e,
color=hover_color: e.widget.configure(bg=color))
btn.bind("<Leave>", lambda e: e.widget.configure(bg=self.special_color))
btn.bind("<Button-1>", lambda e, cmd=command: cmd())



     - Window State Management

Toggles between maximized and normal window states when users click the maximize button.


def toggle_maximize(self):
"""Toggle between maximized and normal window state."""
if self.root.state() == 'zoomed':
self.root.state('normal')

else:
self.root.state('zoomed')



     - Bottom Control Panel

Creates the bottom action bar containing the primary "Add New Task" button with hover animations.


def setup_action_bar(self):
"""Create the bottom action bar with controls."""
action_bar = tk.Frame(self.root, bg=self.bg_color, height=60)
action_bar.pack(fill=tk.X, padx=20, pady=(0, 20))

# Add task button
add_btn = tk.Button(action_bar, text="+ Add New Task",
font=self.button_font, bg=self.special_color,
fg="white", border=0, padx=20, pady=10,
command=self.add_task, cursor="hand2")
add_btn.pack(side=tk.LEFT)

# Hover effect
add_btn.bind("<Enter>", lambda e: e.widget.configure(bg="#1d4ed8"))
add_btn.bind("<Leave>", lambda e: e.widget.configure(bg=self.special_color))



     - Drag Functionality Setup

Configures mouse event bindings to enable window dragging from the title bar.


def setup_window_drag(self):
"""Configure window dragging functionality."""
self.title_bar.bind("<Button-1>", self.on_drag_start)
self.title_bar.bind("<B1-Motion>", self.on_drag_motion)



     - Drag Initialization

Captures initial mouse coordinates when the user starts dragging the window.


def on_drag_start(self, event):
"""Store initial coordinates when starting drag."""
self.drag_data = (event.x_root - self.root.winfo_x(),
event.y_root - self.root.winfo_y())



     - Drag Position Updates

Continuously updates window position as the user drags the mouse across the screen.


def on_drag_motion(self, event):
"""Update window position during drag."""
x = event.x_root - self.drag_data[0]
y = event.y_root - self.drag_data[1]
self.root.geometry(f"+{x}+{y}")



     - Scrollable Content Area

Creates a scrollable canvas system for displaying task cards when content exceeds window height.


def setup_scrollable_canvas(self):
"""Create a scrollable canvas for task cards."""
# Create canvas with scrollbar
self.canvas =tk.Canvas(self.content_frame, bg=self.bg_color,
highlightthickness=0)
scrollbar = ttk.Scrollbar(self.content_frame, orient="vertical",
command=self.canvas.yview)
# Configure canvas scroll region
self.canvas.configure(yscrollcommand=scrollbar.set)
# Create frame for task cards
self.dashboard_panel = tk.Frame(self.canvas, bg=self.bg_color)

# Pack elements
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

# Create window in canvas for dashboard
self.canvas_window = self.canvas.create_window((0,0),
window=self.dashboard_panel, anchor="nw")

# Configure canvas scrolling
self.canvas.bind("<Configure>", self.on_canvas_configure)
self.dashboard_panel.bind("<Configure>", self.on_frame_configure)
self.canvas.bind_all("<MouseWheel>", self.on_mousewheel)



     - Canvas Resize Handler

Updates the canvas scroll region and content width when the canvas is resized.


def on_canvas_configure(self, event):
"""Update canvas scroll region when canvas is configured."""
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
width = event.width
self.canvas.itemconfig(self.canvas_window, width=width)



     - Frame Resize Handler

Recalculates scroll boundaries when the inner frame content changes size.


def on_frame_configure(self, event):
"""Update canvas scroll region when frame is configured."""
self.canvas.configure(scrollregion=self.canvas.bbox("all"))



     - Mouse Wheel Scrolling

Enables mouse wheel scrolling through the task list.


def on_mousewheel(self, event):
"""Handle mouse wheel scrolling."""
self.canvas.yview_scroll(int(-1 * (event.delta / 120)), "units")



     - Task Creation

Handles new task creation with validation, modal dialog presentation, and task limit enforcement (12-task maximum limit).


def add_task(self):
"""Add a new task with modern dialog."""
if len(self.tasks) >= 12:
self.show_error("Maximum Tasks Reached",
                            "Please Complete Tasks Before Adding New Ones")
return
dialog = ModernInputDialog(self.root, "Add New Task", "Enter task details")
self.root.wait_window(dialog)

if dialog.result:
task = {
'text': dialog.result,
'date': datetime.now().strftime("%b %d, %Y"),
'status':'pending'
}
self.tasks.append(task)
self.update_task_panel()


     - UI Refresh

Rebuilds the entire task display panel, organizing tasks into horizontal tiers with proper spacing.


def update_task_panel(self):
"""Refresh the task display with styling."""
for widget in self.dashboard_panel.winfo_children():
widget.destroy()

for i, task in enumerate(self.tasks):
if i % self.tasks_per_tier == 0:
tier_frame = tk.Frame(self.dashboard_panel, bg = self.bg_color)
tier_frame.pack(fill = tk.X, pady = (10, 0))
self.create_task_card(tier_frame, task)



     - Individual Task UI

Generates individual task cards with completion status, action buttons, and custom styling.


def create_task_card(self, parent, task):
"""Create a task card with completion status."""
card = tk.Frame(parent, bg=self.card_bg, padx = 15, pady = 15,
highlightthickness = 1,
highlightbackground = "#e2eff0")
card.pack(side=tk.LEFT, padx = 10, pady = 10,
fill=tk.BOTH, expand=True)

header = tk.Frame(card, bg = self.card_bg)
header.pack(fill=tk.X, pady=(0, 10))

# Use completed font if task is marked as completed
task_font = self.completed_font if task.get('completed', False)
else self.text_font
task_label = tk.Label(header, text = task['text'],
font = task_font, bg = self.card_bg,
fg = self.text_color, wraplength = 200,
justify = tk.LEFT)
task_label.pack(side = tk.LEFT, anchor = "w")

tk.Label(card, text = task['date'], font = ("Helvatica", 9),
bg = self.card_bg, fg = "#64748b").pack(anchor="w")

btn_frame = tk.Frame(card, bg = self.card_bg)
btn_frame.pack(fill = tk.X, pady = (10, 0))

# Change complete button text based on completion status
complete_text = "✓ Completed" if task.get('completed', False)
else "✓ Complete"

complete_btn = tk.Button(btn_frame, text = complete_text,
font = self.button_font,
bg = "#22c55e" if not task.get('completed', False)
else "#64748b",
fg="white", border = 0, padx = 10, pady = 5,
command = lambda: self.toggle_complete_task(
task, task_label, complete_btn))

complete_btn.pack(side = tk.LEFT, padx = (0, 5))

delete_btn = tk.Button(btn_frame, text = "Delete",
font = self.button_font, bg = "#ef4444",
fg="white", border= 0, padx = 10, pady = 5,
command = lambda: self.delete_task(task))

delete_btn.pack(side = tk.LEFT)

for btn, hover_color in [(complete_btn, "#16a34a"), (delete_btn, "#dc2626")]:
btn.bind("<Enter>", lambda e,
color = hover_color: e.widget.configure(bg=color))
btn.bind("<Leave>", lambda e, btn = btn: self.reset_button_color(e, btn))



     - Task Status Management

Handles task completion toggling with success notifications.


def toggle_complete_task(self, task, label, button):
"""Toggle task completion status."""
task['completed'] = not task.get('completed', False)

if task['completed']:
label.configure(font = self.completed_font)
button.configure(text = "✓ Completed", bg="#64748b")
self.show_success("Task Completed", "Grate job completing your task !")
else:
label.configure(font = self.text_font)
button.configure(text = "✓ Complete", bg="#22c55e")



     - Hover State Management

Manages button color states after hover events end.


def reset_button_color(self, event, button):
"""Reset button color after hover."""
if "Complete" in button['text']:
if "Completed" in button['text']:
button.configure(bg = "#64748b")
else:
button.configure(bg = "#22c55e")
else:
button.configure(bg = "#ef4444")



     - Task Removal

Removes tasks from the data structure and triggers UI refresh.


def delete_task(self, task):
"""Remove a task and update display."""
self.tasks.remove(task)
self.update_task_panel()



     - User Notifications

Display system notifications for errors and successful actions using standard message boxes.


def show_error(self, title, message):
"""Display error message"""
messagebox.showerror(title, message)

def show_success(self, title, message):
"""Display error message"""
messagebox.showinfo(title, message)


     - ModernInputDialog Class - Custom Modal Dialog

Display system notifications for errors and successful actions using standard message boxes.


class ModernInputDialog(tk.Toplevel):
"""Custom modern dialog for task input."""
def __init__(self, parent, title, prompt):
super().__init__(parent)

self.result = None

# Configure dialog window
self.title(title)
self.geometry("400x250")
self.configure(bg="#ffffff")
self.resizable(False, False)
self.overrideredirect(True)
self.attributes('-alpha', 0.0)

self.center_on_parent(parent)

self.container = tk.Frame(self, bg="#ffffff",
highlightthickness=1,
highlightbackground="#e2e8f0",
padx=20, pady=20)
self.container.pack(fill=tk.BOTH, expand=True)

title_bar = tk.Frame(self.container, bg="#ffffff")
title_bar.pack(fill=tk.X, pady=(0, 15))

tk.Label(title_bar, text = title, font=("Helvatica", 14, "bold"),
bg="#ffffff",
fg="#1e293b").pack(side=tk.LEFT)

close_btn = tk.Label(title_bar, text = "×", font=("Helvetica", 14),
bg="#ffffff", fg="#64748b", cursor="hand2")
close_btn.pack(side=tk.RIGHT)
close_btn.bind("<Button-1>", lambda e: self.cancel())

tk.Label(self.container, text = prompt, font=("Helvetica", 11),
bg="#ffffff", fg="#1e293b").pack(fill=tk.X)
entry_frame = tk.Frame(self.container, bg="#f1f5f9",
highlightthickness=1,
highlightbackground="#e2e8f0")
entry_frame.pack(fill=tk.X, pady=(10, 20))

self.entry = tk.Entry(entry_frame, font=("Helvetica", 12),
bd=0, bg="#f1f5f9", fg="#1e2936",
insertbackground="#2563eb")
self.entry.pack(fill=tk.X, padx=10, pady=8)
self.entry.focus_set()

btn_frame = tk.Frame(self.container, bg="#ffffff")
btn_frame.pack(fill=tk.X, pady=(0, 10))

# Create modern styled buttons
buttons = [
("Cancel", "#f1f2f9", "#64748b", self.cancel),
("Add Task", "#2563eb", "#ffffff", self.submit)
]

for text, bg, fg, command in buttons:
btn = tk.Button(btn_frame, text=text, font=("Helvetica", 12),
bg=bg, fg=fg, bd=0, padx=20, pady=8, cursor="hand2",
command=command)
btn.pack(side=tk.RIGHT, padx=5)

# Add hover effects
if text == "cancel":
btn.bind("<Enter>", lambda e: e.widget.configure(bg="#e2e8f0"))
btn.bind("<Leave>", lambda e: e.widget.configure(bg="#f1f5f9"))
else:
btn.bind("<Enter>", lambda e: e.widget.configure(bg="#1d4ed8"))
btn.bind("<Leave>", lambda e: e.widget.configure(bg="#2563eb"))

# Add key bindings
self.bind("<Return>", lambda e: self.submit())
self.bind("<Escape>", lambda e: self.cancel())


# Make dialog draggable
title_bar.bind("<Button-1>", self.start_drag)
title_bar.bind("<B1-Motion>", self.drag)

# Fade in animation
self.fade_in()


def fade_in(self):
"""Animate the dialog fading in."""
alpha = self.attributes("-alpha")
if alpha < 1.0:
alpha += 0.1
self.attributes("-alpha", alpha)
self.after(20, self.fade_in)

def fade_out(self):
"""Animate the dialog fading out."""
alpha = self.attributes("-alpha")
if alpha > 0:
alpha -= 0.1
self.attributes("-alpha", alpha)
self.after(20, self.fade_out)
else:
self.destroy()

def submit(self):
"""Handle dialog submission with fade out animation."""
self.result = self.entry.get()
self.fade_out()

def cancel(self):
"""Handle dialog cancellation with fade out animation."""
self.fade_out()

def center_on_parent(self, parent):
"""Center the dialog window on its parent."""
# Get parent window position and size
parent_x = parent.winfo_x()
parent_y = parent.winfo_y()
parent_width = parent.winfo_width()
parent_height = parent.winfo_height()

# Calculate center position
x = parent_x + (parent_width - 400) // 2
y = parent_y + (parent_height - 250) // 2

# Set dialog position
self.geometry(f"400x250+{x}+{y}")


def start_drag(self, event):
"""Store initial coordinates for window dragging."""
self.drag_data = (event.x_root - self.winfo_x(), event.y_root - self.winfo_y())

def drag(self, event):
"""Update window position during drag."""
x = event.x_root - self.drag_data[0]
y = event.y_root - self.drag_data[1]
self.geometry(f"+{x}+{y}")






The Final Result:

Python To-Do List Project Source Code

Python To-Do List Project

Python To-Do List Project In Tkinter

To-Do List Project In Python Tkinter

To-Do List App In Python Tkinter

Tasks Project In Python Tkinter



if you want the source code click on the download button below











Share this

Related Posts

Latest
Previous
Next Post »