11"""
2- tkinter_ui.py (v0.5)
2+ tkinter_ui.py
33--------------------
44Improved teaching Tkinter UI for SchedPlus.
55
1010import tkinter as tk
1111from tkinter import ttk
1212from ui .shortcuts import bind_enter_key
13+ from tkcalendar import Calendar
14+ from logic .scheduler import Scheduler , Task
15+ from sys import path
1316
1417
15- def run_ui (scheduler ) :
18+ def run_ui (scheduler : Scheduler ) -> None :
1619 root = tk .Tk ()
17- root .title ("SchedPlus v0.5 (Tkinter) " )
20+ root .title ("SchedPlus - Basic " )
1821
19- # Center window
20- root .geometry ("420x420" )
22+ # Window sizing
23+ root .geometry ("530x480" )
24+ root .minsize (420 , 420 )
25+ root .resizable (True , True )
2126
2227 # --- Main container ---
2328 container = ttk .Frame (root , padding = 15 )
2429 container .grid (row = 0 , column = 0 , sticky = "nsew" )
2530
26- root .columnconfigure (0 , weight = 1 )
31+ container .columnconfigure (1 , weight = 1 )
32+ container .columnconfigure (2 , weight = 0 )
2733 root .rowconfigure (0 , weight = 1 )
2834
2935 # --- Heading ---
30- heading = ttk .Label (container , text = "Add a Task" , font = ("Segoe UI" , 12 , "bold" ))
31- heading .grid (row = 0 , column = 0 , columnspan = 2 , pady = (0 , 10 ))
36+ ttk .Label (container , text = "Add a Task" , font = ("Segoe UI" , 12 , "bold" )).grid (
37+ row = 0 , column = 0 , columnspan = 3 , pady = (0 , 10 )
38+ )
3239
33- # --- Input fields ---
40+ # --- Date ---
3441 ttk .Label (container , text = "Date (YYYY-MM-DD):" ).grid (row = 1 , column = 0 , sticky = "w" , pady = 3 )
35- date_entry = ttk .Entry (container , width = 25 )
42+ date_entry = ttk .Entry (container )
3643 date_entry .grid (row = 1 , column = 1 , sticky = "ew" , pady = 3 )
3744
45+ def open_calendar ():
46+ top = tk .Toplevel (root )
47+ top .title ("Select Date" )
48+
49+ cal = Calendar (top , selectmode = "day" , date_pattern = "yyyy-mm-dd" )
50+ cal .pack (padx = 10 , pady = 10 )
51+
52+ def choose ():
53+ date_entry .delete (0 , tk .END )
54+ date_entry .insert (0 , cal .get_date ())
55+ top .destroy ()
56+
57+ ttk .Button (top , text = "Select" , command = choose ).pack (pady = 5 )
58+
59+ ttk .Button (container , text = "📅" , width = 3 , command = open_calendar ).grid (
60+ row = 1 , column = 2 , padx = (5 , 0 )
61+ )
62+
63+ # --- Time ---
3864 ttk .Label (container , text = "Time (HH:MM):" ).grid (row = 2 , column = 0 , sticky = "w" , pady = 3 )
39- time_entry = ttk .Entry (container , width = 25 )
65+ time_entry = ttk .Entry (container )
4066 time_entry .grid (row = 2 , column = 1 , sticky = "ew" , pady = 3 )
4167
68+ def open_time_picker ():
69+ top = tk .Toplevel (root )
70+ top .title ("Select Time" )
71+
72+ frame = ttk .Frame (top , padding = 10 )
73+ frame .grid (row = 1 , column = 1 )
74+
75+ ttk .Label (frame , text = "Hour:" ).grid (row = 0 , column = 0 , padx = 5 , pady = 5 )
76+ hour_spin = ttk .Spinbox (frame , from_ = 0 , to = 23 , width = 3 , format = "%02.0f" )
77+ hour_spin .grid (row = 0 , column = 1 , padx = 5 , pady = 5 )
78+
79+ ttk .Label (frame , text = "Minute:" ).grid (row = 1 , column = 0 , padx = 5 , pady = 5 )
80+ minute_spin = ttk .Spinbox (frame , from_ = 0 , to = 59 , width = 3 , format = "%02.0f" )
81+ minute_spin .grid (row = 1 , column = 1 , padx = 5 , pady = 5 )
82+
83+ def choose ():
84+ time_entry .delete (0 , tk .END )
85+ time_entry .insert (0 , f"{ hour_spin .get ()} :{ minute_spin .get ()} " )
86+ top .destroy ()
87+
88+ ttk .Button (top , text = "Select" , command = choose ).grid (row = 1 , column = 0 , pady = 10 )
89+
90+ ttk .Button (container , text = "🕒" , width = 3 , command = open_time_picker ).grid (
91+ row = 2 , column = 2 , padx = (5 , 0 )
92+ )
93+
94+ # --- Task text ---
4295 ttk .Label (container , text = "Task:" ).grid (row = 3 , column = 0 , sticky = "w" , pady = 3 )
43- task_entry = ttk .Entry (container , width = 25 )
96+ task_entry = ttk .Entry (container )
4497 task_entry .grid (row = 3 , column = 1 , sticky = "ew" , pady = 3 )
4598
4699 # --- Add Task button ---
47100 add_button = ttk .Button (container , text = "Add Task" )
48- add_button .grid (row = 4 , column = 0 , columnspan = 2 , pady = (10 , 15 ))
101+ add_button .grid (row = 4 , column = 0 , columnspan = 3 , pady = (10 , 15 ))
49102
50- # --- Task list frame ---
103+ # --- Task list ---
51104 list_frame = ttk .LabelFrame (container , text = "Tasks" , padding = 10 )
52- list_frame .grid (row = 5 , column = 0 , columnspan = 2 , sticky = "nsew" )
105+ list_frame .grid (row = 5 , column = 0 , columnspan = 3 , sticky = "nsew" )
53106
54- container .rowconfigure (5 , weight = 1 )
55- list_frame .rowconfigure (0 , weight = 1 )
56- list_frame .columnconfigure (0 , weight = 1 )
107+ # --- Task list (Treeview) ---
108+ columns = ("date" , "time" , "text" )
109+
110+ task_list = ttk .Treeview (
111+ list_frame ,
112+ columns = columns ,
113+ show = "headings" ,
114+ height = 10
115+ )
116+
117+ # Column headings
118+ task_list .heading ("date" , text = "Date" )
119+ task_list .heading ("time" , text = "Time" )
120+ task_list .heading ("text" , text = "Task" )
121+
122+ # Column widths
123+ task_list .column ("date" , width = 100 , anchor = "center" ) # YYYY-MM-DD
124+ task_list .column ("time" , width = 60 , anchor = "center" ) # HH:MM
125+ task_list .column ("text" , width = 300 , anchor = "w" ) # expands
57126
58- # --- Task list ---
59- task_list = tk .Listbox (list_frame , width = 50 , height = 10 , borderwidth = 1 , relief = "solid" )
60127 task_list .grid (row = 0 , column = 0 , sticky = "nsew" )
61128
62- # Populate existing tasks
63- for task in scheduler .get_tasks ():
64- task_list .insert (tk .END , f"{ task .date } { task .time } - { task .text } " )
129+ # Scrollbar
130+ scrollbar = ttk .Scrollbar (list_frame , orient = "vertical" , command = task_list .yview )
131+ task_list .configure (yscrollcommand = scrollbar .set )
132+ scrollbar .grid (row = 0 , column = 1 , sticky = "ns" )
133+
134+
135+ for task in scheduler .get_tasks (): # type: Task
136+ task_list .insert ("" , "end" , values = (task .date , task .time , task .text ))
65137
66138 # --- Add Task logic ---
67139 def add_task ():
@@ -72,11 +144,11 @@ def add_task():
72144 if date and time and text :
73145 scheduler .add_task (date , time , text )
74146 new_task = scheduler .get_tasks ()[- 1 ]
75-
76- task_list .insert (tk .END , f"{ new_task .date } { new_task .time } - { new_task .text } " )
147+ task_list .insert ("" , "end" , values = (new_task .date , new_task .time , new_task .text ))
77148
78149 try :
79150 scheduler .save_tasks ()
151+ print ("Saving to:" , filepath )
80152 except Exception :
81153 pass
82154
0 commit comments