my_conn we will use in our main script. We will call the connection object from main script.
from tk_checkbutton4_connect import my_conn # database connection
Inside the file tk_checkbutton4_connect.py we will keep this code.
from sqlalchemy import create_engine
from sqlalchemy.exc import SQLAlchemyError
try: # connection to database
#my_path="D:\\testing\\sqlite\\my_db.db" #Change the path
#my_conn = create_engine("sqlite:///" + my_path)
### for MySQL database , use the below line and remove the above line
my_conn =create_engine("mysql+mysqldb://root:pw@localhost/my_tutorial")
except SQLAlchemyError as e:
error = str(e.__dict__['orig'])
print(error)
def my_upd(k):
if(my_ref[k][1].get()==True):
my_ref[k][0].config(font=f_done,fg='green')
q='UPDATE my_tasks SET status=True WHERE id='+str(k)
else:
my_ref[k][0].config(font=f_normal,fg='blue')
q='UPDATE my_tasks SET status=False WHERE id='+str(k)
r_set=my_conn.execute(q)
msg="No. Updated:"+str(r_set.rowcount) # Number of rows updated
my_msg(msg) # show message for 3 seconds
for w in task_frame.grid_slaves(): #Loop through each row
w.grid_forget() # remove the row
We will read the tasks and the status of the task from the my_tasks table to display. In our table my_tasks, we have four columns, id, tasks , status and dt. We will create one dictionary by using id as Key with tasks, status , dt list as values.
q='SELECT * FROM my_tasks '
my_cursor=my_conn.execute(q)
r_set=my_cursor.fetchall()
my_dict = {row[0]: [row[1],row[2],row[3]] for row in r_set}
We are using the date column value and converting to string by using strftime(). Here we are using the list of Date formats to show date.
#dt=datetime.strptime(my_dict[k][2],'%Y-%m-%d').strftime('%d-%b-%Y') # sqlite
dt=datetime.strftime(my_dict[k][2],'%d-%b-%Y') # MySQL
ld=tk.Label(task_frame,text=dt)
ld.grid(row=i,column=1,padx=2)
Here is the full code for the function my_disp()
my_ref={} # to store references to checkboxes
def my_show():
for w in task_frame.grid_slaves(): #Loop through each row
w.grid_forget() # remove the row
q='SELECT * FROM my_tasks '
my_cursor=my_conn.execute(q)
r_set=my_cursor.fetchall()
my_dict = {row[0]: [row[1],row[2],row[3]] for row in r_set}
i=2 # row number
for k in my_dict.keys(): # Number of checkbuttons
var=tk.BooleanVar() # variable
var.set(my_dict[k][1]) # set to value of status column
if my_dict[k][1]==True: # set font based on status column
font,fg=f_done,'green' # if True
else:
font,fg=f_normal,'blue'
ck = tk.Checkbutton(task_frame, text=my_dict[k][0],
variable=var,onvalue=True,offvalue=False,font=font,fg=fg,
command=lambda k=k: my_upd(k))
ck.grid(row=i,column=0,padx=20,pady=1,sticky='w')
#dt=datetime.strptime(my_dict[k][2],'%Y-%m-%d').strftime('%d-%b-%Y') # sqlite
dt=datetime.strftime(my_dict[k][2],'%d-%b-%Y') # MySQL
ld=tk.Label(task_frame,text=dt)
ld.grid(row=i,column=1,padx=2)
my_ref[k]=[ck,var] # to hold the references
i=i+1 # increase the row number
b1=tk.Button(my_w,text='+',font=18,command=lambda:add_task())
b1.grid(row=0,column=2)
Inside the function add_task() we will first read the data entered by the user in the Entry box e1 by using get() method.from tkcalendar import DateEntry
To display the calendar with other components
cal=DateEntry(my_w,selectmode='day',font=18)
cal.grid(row=1,column=1)
To display and collect user selected calendar date use this
dt=cal.get_date()
Calendar for Date selection
def add_task():
dt=cal.get_date()
#dt = date.today() # todays date
my_data=(e1.get(),False,dt) # data to pass using query
### for SQLite use the below line and remove MySQL line
#r_set=my_conn.execute("INSERT INTO my_tasks (tasks, status,dt) \
# VALUES(?,?,?)",my_data)
### for MySQL use the below line and remove the above line
r_set=my_conn.execute("INSERT INTO my_tasks (tasks, status,dt) \
VALUES(%s,%s,%s)",my_data)
msg="Task ID:"+str(r_set.lastrowid)
e1.delete(0,'end') # remove the task from entry box
my_msg(msg) # show message for 3 seconds
my_show() # refresh the view
def delete_task(): # remove all completed tasks
r_set=my_conn.execute("DELETE FROM my_tasks WHERE status=True")
msg="No Deleted:"+str(r_set.rowcount) # Number of rows deleted
my_msg(msg) # show message for 3 seconds
my_show() # refresh the view
def my_msg(msg):
l2.config(text=msg) # show message
my_w.after(3000,lambda:l2.config(text='')) # remove after 3 seconds
Full code is here ( Change the path to your database or connection string.
CREATE TABLE IF NOT EXISTS `my_tasks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`tasks` text,
`status` tinyint(1) DEFAULT NULL,
`dt` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=10 ;
--
-- Dumping data for table `my_tasks`
--
INSERT INTO `my_tasks` (`id`, `tasks`, `status`, `dt`) VALUES
(1, 'My tasks 1 ', True,'2026-09-10'),
(2, 'My tasks 2', False,'2026-09-11'),
(3, 'My tasks 3', True,'2026-09-12');
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.