Skip to content

Commit 2717d1d

Browse files
authored
Merge pull request #72 from harshgsharma1501/harsh
I have made all the requested changes. Please merge.
2 parents 93ae641 + 972c406 commit 2717d1d

File tree

5 files changed

+314
-0
lines changed

5 files changed

+314
-0
lines changed

To Do App/README.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
**#To-Do List Application**
2+
A simple and intuitive To-Do List application built with Python's Tkinter library for the GUI and SQLite for persistent task storage. This application helps you manage tasks with categories, due dates, and priority levels, allowing easy organization of daily activities.
3+
4+
**Features**
5+
6+
Add Tasks: Add tasks with a description, category, due date, and priority level (High, Medium, Low).
7+
8+
View Tasks: View all tasks, or filter tasks to see only completed or pending ones.
9+
10+
Search Tasks: Quickly search tasks by their name or category using the search bar.
11+
12+
Toggle Theme: Switch between dark and light themes to match your preference.
13+
14+
Mark Tasks as Complete: Mark tasks as completed to keep track of what’s done.
15+
16+
Persistent Storage: All tasks are saved in an SQLite database, ensuring data is saved even after closing the app.
17+
18+
19+
**Prerequisites**
20+
21+
Python 3.6+
22+
Tkinter (Usually included with Python)
23+
SQLite (Included in Python’s standard library)
24+
tkcalendar: Install using pip install tkcalendar
25+
26+
**Usage Instructions**
27+
28+
1. Add a Task
29+
Enter a task description in the Task field.
30+
Specify the Category for better organization.
31+
Select a Due Date from the date picker.
32+
Choose a Priority from the drop-down menu (High, Medium, Low).
33+
Click Add Task to save it.
34+
35+
2. View All Tasks
36+
Click on View All Tasks in the sidebar to display a list of all tasks.
37+
Tasks are displayed with their description, category, due date, and priority level.
38+
39+
3. View Completed Tasks
40+
Click View Completed Tasks in the sidebar to see tasks that have been marked as complete.
41+
42+
4. View Pending Tasks
43+
Click View Pending Tasks in the sidebar to view tasks that are yet to be completed.
44+
45+
5. Search Tasks
46+
Use the Search bar in the sidebar to find tasks by their description or category.
47+
The list of tasks will update as you type, showing only those that match the search term.
48+
49+
6. Mark Tasks as Complete
50+
Select a task from the list and click Mark as Complete (add this button in your application).
51+
Completed tasks will no longer appear in the pending tasks view.
52+
53+
7. Toggle Dark/Light Theme
54+
Click Toggle Theme in the sidebar to switch between dark and light modes.
55+
This changes the background color, text color, and button styles for a better visual experience.
56+
57+
8. Close the Application
58+
Close the application by clicking the window close button (X) or selecting Exit.
59+
The application safely saves your tasks and closes the database connection.
60+
61+
62+
**Database Structure**
63+
The application uses an SQLite database with the following table structure:
64+
65+
Table Name: tasks
66+
67+
Column Name Type Description
68+
69+
id INTEGER Primary key, unique task ID
70+
task TEXT Description of the task
71+
category TEXT Category of the task (e.g., Work, Home)
72+
due_date TEXT Due date of the task
73+
priority TEXT Priority level (High, Medium, Low)
74+
completed INTEGER Status (0 = Pending, 1 = Completed)
75+
76+
**License**
77+
This project is licensed under the MIT License. See the LICENSE file for details.
78+
79+
**Acknowledgments**
80+
Thanks to the Python community for their extensive libraries and documentation.
81+
Special thanks to the creators of tkcalendar for providing a simple date picker widget for Tkinter.

To Do App/To_Do_AppTkInter.py

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
import tkinter as tk
2+
from tkinter import messagebox, ttk
3+
from tkcalendar import DateEntry
4+
import sqlite3
5+
6+
class TodoApp:
7+
def __init__(self, root):
8+
self.root = root
9+
self.root.title("To-Do List App")
10+
self.root.geometry("900x600")
11+
12+
# Initialize attributes
13+
self.is_dark_theme = True # Start with dark theme
14+
15+
# Create main frame and sidebar frame
16+
self.main_frame = tk.Frame(self.root, bg="#2E2E2E")
17+
self.main_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
18+
19+
self.sidebar_frame = tk.Frame(self.root, width=200, bg="#3A3A3A")
20+
self.sidebar_frame.pack(side=tk.LEFT, fill=tk.Y)
21+
22+
self.create_widgets()
23+
self.create_database()
24+
self.apply_theme() # Apply theme after frames are created
25+
self.create_sidebar()
26+
self.load_tasks()
27+
28+
# Bind the window close event to close the database connection
29+
self.root.protocol("WM_DELETE_WINDOW", self.close_app)
30+
31+
def create_sidebar(self):
32+
"""Create the sidebar with navigation options."""
33+
tk.Label(self.sidebar_frame, text="Menu", font=("Helvetica", 16), bg="#3A3A3A", fg="#FFFFFF").pack(pady=10)
34+
35+
# Create the "View All Tasks" button
36+
self.view_all_button = tk.Button(
37+
self.sidebar_frame,
38+
text="View All Tasks",
39+
command=self.load_tasks,
40+
bg="#5A5A5A",
41+
fg="#FFFFFF",
42+
relief="flat"
43+
)
44+
self.view_all_button.pack(pady=5, padx=10, fill=tk.X)
45+
46+
# Create other buttons like "View Completed Tasks", "View Pending Tasks", etc.
47+
self.view_completed_button = tk.Button(
48+
self.sidebar_frame,
49+
text="View Completed Tasks",
50+
command=self.load_completed_tasks,
51+
bg="#5A5A5A",
52+
fg="#FFFFFF",
53+
relief="flat"
54+
)
55+
self.view_completed_button.pack(pady=5, padx=10, fill=tk.X)
56+
57+
self.view_pending_button = tk.Button(
58+
self.sidebar_frame,
59+
text="View Pending Tasks",
60+
command=self.load_pending_tasks,
61+
bg="#5A5A5A",
62+
fg="#FFFFFF",
63+
relief="flat"
64+
)
65+
self.view_pending_button.pack(pady=5, padx=10, fill=tk.X)
66+
67+
# Search entry and label
68+
tk.Label(self.sidebar_frame, text="Search:", bg="#3A3A3A", fg="#FFFFFF").pack(pady=5)
69+
self.search_entry = tk.Entry(self.sidebar_frame, bg="#4B4B4B", fg="#FFFFFF", relief="flat")
70+
self.search_entry.pack(pady=5, padx=10, fill=tk.X)
71+
self.search_entry.bind('<KeyRelease>', self.search_tasks)
72+
73+
# Toggle theme button
74+
self.theme_button = tk.Button(
75+
self.sidebar_frame,
76+
text="Toggle Theme",
77+
command=self.toggle_theme,
78+
bg="#5A5A5A",
79+
fg="#FFFFFF",
80+
relief="flat"
81+
)
82+
self.theme_button.pack(pady=5, padx=10, fill=tk.X)
83+
84+
def apply_theme(self):
85+
"""Apply the current theme to the application."""
86+
if self.is_dark_theme:
87+
bg_color = "#2E2E2E"
88+
fg_color = "#FFFFFF"
89+
button_bg = "#5A5A5A"
90+
entry_bg = "#4B4B4B"
91+
else:
92+
bg_color = "#F0F0F0"
93+
fg_color = "#000000"
94+
button_bg = "#D0D0D0"
95+
entry_bg = "#FFFFFF"
96+
97+
self.root.configure(bg=bg_color)
98+
self.main_frame.configure(bg=bg_color)
99+
self.sidebar_frame.configure(bg="#3A3A3A" if self.is_dark_theme else "#F0F0F0")
100+
101+
# Update the colors of sidebar elements
102+
for widget in self.sidebar_frame.winfo_children():
103+
if isinstance(widget, tk.Button):
104+
widget.configure(bg=button_bg, fg=fg_color)
105+
elif isinstance(widget, tk.Entry):
106+
widget.configure(bg=entry_bg, fg=fg_color)
107+
108+
def toggle_theme(self):
109+
"""Toggle between light and dark themes."""
110+
self.is_dark_theme = not self.is_dark_theme
111+
self.apply_theme()
112+
113+
def create_database(self):
114+
"""Create the tasks table if it doesn't exist."""
115+
self.conn = sqlite3.connect("tasks.db")
116+
# Create the table if it doesn't exist yet
117+
with self.conn:
118+
self.conn.execute("""
119+
CREATE TABLE IF NOT EXISTS tasks (
120+
id INTEGER PRIMARY KEY,
121+
task TEXT NOT NULL,
122+
category TEXT,
123+
due_date TEXT,
124+
priority TEXT,
125+
completed INTEGER DEFAULT 0
126+
)
127+
""")
128+
129+
def create_widgets(self):
130+
"""Create the main content area widgets."""
131+
frame = tk.Frame(self.main_frame, bg="#2E2E2E" if self.is_dark_theme else "#FFFFFF", padx=10, pady=10)
132+
frame.pack(pady=20, padx=20, fill=tk.BOTH, expand=True)
133+
134+
# Task entry
135+
tk.Label(frame, text="Task:", font=("Helvetica", 12), bg=frame["bg"], fg="#FFFFFF" if self.is_dark_theme else "#000000").grid(row=0, column=0, sticky="w", pady=5)
136+
self.task_entry = tk.Entry(frame, width=50, bg="#4B4B4B", fg="#FFFFFF", relief="flat")
137+
self.task_entry.grid(row=0, column=1, sticky="ew", padx=5, pady=5)
138+
139+
# Category entry
140+
tk.Label(frame, text="Category:", font=("Helvetica", 12), bg=frame["bg"], fg="#FFFFFF" if self.is_dark_theme else "#000000").grid(row=1, column=0, sticky="w", pady=5)
141+
self.category_entry = tk.Entry(frame, width=50, bg="#4B4B4B", fg="#FFFFFF", relief="flat")
142+
self.category_entry.grid(row=1, column=1, sticky="ew", padx=5, pady=5)
143+
144+
# Due date entry
145+
tk.Label(frame, text="Due Date:", font=("Helvetica", 12), bg=frame["bg"], fg="#FFFFFF" if self.is_dark_theme else "#000000").grid(row=2, column=0, sticky="w", pady=5)
146+
self.due_date_entry = DateEntry(frame, width=20, date_pattern='yyyy-mm-dd', background='#4B4B4B', foreground='white', relief="flat")
147+
self.due_date_entry.grid(row=2, column=1, sticky="w", padx=5, pady=5)
148+
149+
# Priority menu
150+
tk.Label(frame, text="Priority:", font=("Helvetica", 12), bg=frame["bg"], fg="#FFFFFF" if self.is_dark_theme else "#000000").grid(row=3, column=0, sticky="w", pady=5)
151+
self.priority_var = tk.StringVar(value="Medium")
152+
self.priority_menu = ttk.Combobox(frame, textvariable=self.priority_var, values=["High", "Medium", "Low"], state="readonly")
153+
self.priority_menu.grid(row=3, column=1, sticky="w", padx=5, pady=5)
154+
155+
# Add task button
156+
self.add_task_button = tk.Button(frame, text="Add Task", command=self.add_task, bg="#5A5A5A", fg="#FFFFFF", relief="flat")
157+
self.add_task_button.grid(row=4, column=1, sticky="e", pady=10)
158+
159+
# Listbox for tasks
160+
self.task_listbox = tk.Listbox(self.main_frame, font=("Helvetica", 10), bg="#2E2E2E", fg="#FFFFFF", height=15, relief="flat")
161+
self.task_listbox.pack(pady=10, padx=20, fill=tk.BOTH, expand=True)
162+
163+
def load_tasks(self):
164+
"""Load all pending tasks from the database."""
165+
self.task_listbox.delete(0, tk.END)
166+
cursor = self.conn.cursor()
167+
# Retrieve tasks that are not yet completed (completed=0)
168+
cursor.execute("SELECT * FROM tasks WHERE completed=0")
169+
for row in cursor.fetchall():
170+
# Format the task details for display in the listbox
171+
self.task_listbox.insert(tk.END, f"{row[1]} | {row[2]} | Due: {row[3]} | Priority: {row[4]}")
172+
173+
def load_completed_tasks(self):
174+
"""Load completed tasks from the database."""
175+
self.task_listbox.delete(0, tk.END)
176+
cursor = self.conn.cursor()
177+
# Retrieve tasks that are marked as completed (completed=1)
178+
cursor.execute("SELECT * FROM tasks WHERE completed=1")
179+
for row in cursor.fetchall():
180+
self.task_listbox.insert(tk.END, f"{row[1]} | {row[2]} | Due: {row[3]} | Priority: {row[4]}")
181+
182+
def load_pending_tasks(self):
183+
"""Load pending tasks."""
184+
# Reuse the load_tasks method since it already loads pending tasks
185+
self.load_tasks()
186+
187+
def add_task(self):
188+
"""Add a new task to the database."""
189+
task = self.task_entry.get()
190+
category = self.category_entry.get()
191+
due_date = self.due_date_entry.get()
192+
priority = self.priority_var.get()
193+
194+
# Validate that required fields are filled
195+
if task and category and due_date:
196+
with self.conn:
197+
# Insert a new task into the database
198+
self.conn.execute("INSERT INTO tasks (task, category, due_date, priority) VALUES (?, ?, ?, ?)",
199+
(task, category, due_date, priority))
200+
# Refresh the task list to show the new entry
201+
self.load_tasks()
202+
# Clear the input fields after adding the task
203+
self.task_entry.delete(0, tk.END)
204+
self.category_entry.delete(0, tk.END)
205+
else:
206+
messagebox.showwarning("Input Error", "Please fill all fields.")
207+
208+
def search_tasks(self, event):
209+
"""Search tasks based on input in the search bar."""
210+
query = self.search_entry.get().lower()
211+
self.task_listbox.delete(0, tk.END)
212+
cursor = self.conn.cursor()
213+
# Retrieve all tasks and filter by the search query
214+
cursor.execute("SELECT * FROM tasks WHERE completed=0")
215+
for row in cursor.fetchall():
216+
task_str = f"{row[1]} | {row[2]} | Due: {row[3]} | Priority: {row[4]}"
217+
# Display only tasks that match the search query
218+
if query in task_str.lower():
219+
self.task_listbox.insert(tk.END, task_str)
220+
221+
def close_app(self):
222+
"""Close the database connection and exit the application."""
223+
if self.conn:
224+
self.conn.close()
225+
self.root.destroy()
226+
227+
if __name__ == "__main__":
228+
root = tk.Tk()
229+
app = TodoApp(root)
230+
root.mainloop()

To Do App/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
tkinter==8.6
2+
sqlite3==3.45.3

To Do App/runtime.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Python 3.12.4

To Do App/tasks.db

8 KB
Binary file not shown.

0 commit comments

Comments
 (0)