Task Zapper Python GUI
👤 Sharing: AI
import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext
import datetime
import threading
import time
import os
class TaskZapperApp:
def __init__(self, root):
self.root = root
self.root.title("Task Zapper")
self.root.geometry("800x600")
self.tasks = []
self.task_timers = {}
self.style = ttk.Style()
self.style.theme_use('clam')
self.setup_ui()
def setup_ui(self):
# Task Input Frame
input_frame = ttk.Frame(self.root, padding=10)
input_frame.pack(fill=tk.X)
ttk.Label(input_frame, text="Task Description:").grid(row=0, column=0, sticky=tk.W)
self.task_entry = ttk.Entry(input_frame, width=50)
self.task_entry.grid(row=0, column=1, sticky=tk.EW)
ttk.Label(input_frame, text="Due Date (YYYY-MM-DD):").grid(row=1, column=0, sticky=tk.W)
self.date_entry = ttk.Entry(input_frame, width=20)
self.date_entry.grid(row=1, column=1, sticky=tk.W)
ttk.Label(input_frame, text="Due Time (HH:MM):").grid(row=2, column=0, sticky=tk.W)
self.time_entry = ttk.Entry(input_frame, width=20)
self.time_entry.grid(row=2, column=1, sticky=tk.W)
add_button = ttk.Button(input_frame, text="Add Task", command=self.add_task)
add_button.grid(row=3, column=1, sticky=tk.E)
# Task List Frame
list_frame = ttk.Frame(self.root, padding=10)
list_frame.pack(fill=tk.BOTH, expand=True)
self.task_list = tk.Listbox(list_frame, height=15, width=70, bg="#f0f0f0", fg="#333333")
self.task_list.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
scrollbar = ttk.Scrollbar(list_frame, orient=tk.VERTICAL, command=self.task_list.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
self.task_list['yscrollcommand'] = scrollbar.set
# Task Management Frame
management_frame = ttk.Frame(self.root, padding=10)
management_frame.pack(fill=tk.X)
complete_button = ttk.Button(management_frame, text="Mark Complete", command=self.mark_complete)
complete_button.pack(side=tk.LEFT, padx=5)
delete_button = ttk.Button(management_frame, text="Delete Task", command=self.delete_task)
delete_button.pack(side=tk.LEFT, padx=5)
self.details_button = ttk.Button(management_frame, text="Details", command=self.show_details)
self.details_button.pack(side=tk.LEFT, padx=5)
# Status Bar
self.status_label = ttk.Label(self.root, text="Ready", anchor=tk.W)
self.status_label.pack(side=tk.BOTTOM, fill=tk.X, padx=10, pady=5)
def add_task(self):
description = self.task_entry.get()
due_date_str = self.date_entry.get()
due_time_str = self.time_entry.get()
try:
due_datetime = datetime.datetime.strptime(f'{due_date_str} {due_time_str}', '%Y-%m-%d %H:%M')
except ValueError:
messagebox.showerror("Error", "Invalid date or time format. Use YYYY-MM-DD and HH:MM.")
return
if not description:
messagebox.showerror("Error", "Task description cannot be empty.")
return
task = {
'description': description,
'due_date': due_datetime,
'completed': False
}
self.tasks.append(task)
self.update_task_list()
self.task_entry.delete(0, tk.END)
self.date_entry.delete(0, tk.END)
self.time_entry.delete(0, tk.END)
self.start_timer_thread(task)
def update_task_list(self):
self.task_list.delete(0, tk.END)
for i, task in enumerate(self.tasks):
status = "[?]" if task['completed'] else "[ ]"
due_str = task['due_date'].strftime('%Y-%m-%d %H:%M')
self.task_list.insert(tk.END, f"{status} {task['description']} (Due: {due_str})")
def mark_complete(self):
selected_index = self.task_list.curselection()
if selected_index:
index = selected_index[0]
self.tasks[index]['completed'] = True
self.update_task_list()
def delete_task(self):
selected_index = self.task_list.curselection()
if selected_index:
index = selected_index[0]
task = self.tasks.pop(index)
self.update_task_list()
# Stop the timer if it exists
if task in self.task_timers:
self.task_timers[task]['stop_flag'] = True # Signal the thread to stop
del self.task_timers[task]
def start_timer_thread(self, task):
# Initialize the stop flag
self.task_timers[task] = {'stop_flag': False}
timer_thread = threading.Thread(target=self.task_timer, args=(task,))
timer_thread.daemon = True # Allow the main program to exit even if the thread is running
timer_thread.start()
def task_timer(self, task):
while True:
if self.task_timers[task]['stop_flag']:
break # Exit if stop flag is set
now = datetime.datetime.now()
time_left = task['due_date'] - now
if time_left.total_seconds() <= 0 and not task['completed']:
self.show_notification(task['description'])
break # Stop the timer after notification
hours, remainder = divmod(time_left.total_seconds(), 3600)
minutes, seconds = divmod(remainder, 60)
time_str = f'{int(hours):02}:{int(minutes):02}:{int(seconds):02}'
self.status_label.config(text=f"Time left for '{task['description']}': {time_str}")
time.sleep(1)
def show_notification(self, task_description):
# Cross-platform notification
if os.name == 'nt': # Windows
import win10toast
toaster = win10toast.ToastNotifier()
toaster.show_toast("Task Due!", f"{task_description} is due now!", duration=10)
else: # macOS, Linux (requires plyer)
try:
from plyer import notification
notification.notify(
title="Task Due!",
message=f"{task_description} is due now!",
timeout=10
)
except ImportError:
messagebox.showinfo("Notification", f"Task '{task_description}' is due!")
def show_details(self):
detail_window = tk.Toplevel(self.root)
detail_window.title("Details")
text_area = scrolledtext.ScrolledText(detail_window, wrap=tk.WORD, width=80, height=20)
text_area.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)
details_text = """
Task Zapper: Your Versatile Task Management Solution
Features:
- Add tasks with descriptions, due dates, and due times.
- View a list of all tasks with their status (complete/incomplete).
- Mark tasks as complete.
- Delete tasks.
- Real-time countdown timer for each task displayed in the status bar.
- Cross-platform notifications when a task is due (Windows, macOS, Linux).
How to Use:
1. Enter the task description.
2. Enter the due date in YYYY-MM-DD format.
3. Enter the due time in HH:MM format.
4. Click 'Add Task'.
5. Select a task from the list to mark it complete or delete it.
Requirements:
- Python 3.x
- tkinter (usually included with Python)
- plyer (for macOS/Linux notifications): pip install plyer
- win10toast (for Windows notifications): pip install win10toast
Potential Improvements:
- Implement task prioritization.
- Add recurring task functionality.
- Integrate with cloud services for task synchronization.
- Allow custom notification sounds.
- Implement task categories/tags.
"""
text_area.insert(tk.INSERT, details_text)
text_area.config(state=tk.DISABLED) # Make it read-only
if __name__ == "__main__":
root = tk.Tk()
app = TaskZapperApp(root)
root.mainloop()
👁️ Viewed: 5
Comments