Basic information: (Python, Customtkinter, datetime, Python 3.10, time.sleep, threading, tkinter messagebox, openpyxl, to-do app, GUI, SyntaxError)
Hi, I'm building a to-do app with a customTkinter interface, I'm storing all the tasks in an excel database with openpyxl and the functions are create a task, open a task and mark it as done, delete a task, and delete all tasks. I use threading for a function that checks if the checkbox in a task is checked.
Now to the error, the error is that when I run it on line 90 I have a function that's named open and has the parameter num, open opens a task when a button of that task is clicked and then you can mark it as done, the error is a SyntaxError, if someone can explain what the problem is with using a variable as a parameter and a global, that would be great.
File #removed file structure for security reasons, line 90
global checkbox_done, num
^^^^^^^^^^^^^^^^^^^^^^^^^
SyntaxError: name 'num' is parameter and global
the excel database is as in the image below:
I'm saving the Title, Description with a form that the user fills out, the status is False until the user checks the checkbox that the threading function then marks as True, the date created I use the DateTime module and I use strtime to format the date and time, Year, Month, Day, Hour, Minute.
if someone could fix this code it would be amazing, and if you find a solution it would help extra much if you just answer with the finished code. Thanks.
I have commented out the iconbitmap so that you can run the code to test it
CODE:
#to-do app
import openpyxl
from customtkinter import *
import datetime
from tkinter import messagebox
import threading
from time import sleep
root = CTk()
root.iconbitmap("C:/Users/Axelr/PycharmProjects/PC01/main/Self built/To-Do app/icon.ico")
root.geometry("500x600")
root.title("To-Do App")
set_appearance_mode("light")
workbook = openpyxl.load_workbook(filename="data.xlsx")
sheet = workbook.active
#functions
def delete_all():
answer = messagebox.askyesno(title="Confirmation", message="Are you sure you want to delete all of your To-Do items?")
if answer:
row = sheet.max_row - 1
if row != 0:
for _ in range(row):
sheet[f"A{row}"] = None
sheet[f"B{row}"] = None
sheet[f"C{row}"] = None
sheet[f"D{row}"] = None
row -= 1
workbook.save(filename="data.xlsx")
print("Deleted all items")
else:
print("No items in database")
else:
print("Cancelled")
def create_task_window():
form_root = CTk()
form_root.iconbitmap("C:/Users/Axelr/PycharmProjects/PC01/main/Self built/To-Do app/icon.ico")
form_root.geometry("700x250")
form_root.title("Create a new to-do task")
form_root.configure(fg_color="yellow")
def create():
place = sheet.max_row 1
current_datetime = datetime.datetime.now()
current_datetime = current_datetime.strftime("%Y-%m-%d %H:%M")
sheet[f"A{place}"] = title_entry.get()
sheet[f"B{place}"] = description_entry.get()
sheet[f"C{place}"] = False
sheet[f"D{place}"] = current_datetime
workbook.save(filename="data.xlsx")
print("Task Created!")
form_root.destroy()
title_label = CTkLabel(form_root, text="Title:", text_font=("Roboto", 20))
title_label.grid(row=0, column=0, padx=12, pady=20)
title_entry = CTkEntry(form_root, placeholder_text="Title", text_font=("Roboto", 20), width=400)
title_entry.grid(row=0, column=1, padx=12, pady=20)
description_label = CTkLabel(form_root, text="Description:", text_font=("Roboto", 20))
description_label.grid(row=1, column=0, padx=12, pady=20)
description_entry = CTkEntry(form_root, placeholder_text="Description", text_font=("Roboto", 20), width=400)
description_entry.grid(row=1, column=1, padx=12, pady=20)
create_btn = CTkButton(form_root, text="Create", text_font=("Roboto", 25), width=300, command=create)
create_btn.grid(row=2, column=1, padx=50, pady=30)
form_root.mainloop()
def thread_checkbox():
while True:
sleep(1.5)
try:
if checkbox_done:
sheet[f"C{num}"] = True
workbook.save(filename="data.xlsx")
except:
pass
def open(num):
global checkbox_done, num
num = num
view_root = CTk()
view_root.iconbitmap("C:/Users/Axelr/PycharmProjects/PC01/main/Self built/To-Do app/icon.ico")
view_root.geometry("700x500")
view_root.title("View task")
def delete():
answer = messagebox.askyesno(title="Confirmation", message="Are you sure you want to delete?")
if answer:
sheet[f"A{num}"] = None
sheet[f"B{num}"] = None
sheet[f"C{num}"] = None
sheet[f"D{num}"] = None
workbook.save(filename="data.xlsx")
view_root.destroy()
title_label = CTkLabel(view_root, text=f"Title: {title}", text_font=("Roboto", 20))
title_label.grid(row=0, column=0, padx=12, pady=20)
description_label = CTkLabel(view_root, text=f"Description: {description}", text_font=("Roboto", 20))
description_label.grid(row=1, column=0, padx=12, pady=20)
status_label = CTkLabel(view_root, text=f"Status: {done}", text_font=("Roboto", 20))
status_label.grid(row=2, column=0, padx=12, pady=20)
date_label = CTkLabel(view_root, text=f"Date Created: {date}", text_font=("Roboto", 20))
date_label.grid(row=3, column=0, padx=12, pady=20)
checkbox_label = CTkLabel(view_root, text="Make done: ", text_font=("Roboto", 20))
checkbox_label.grid(row=4, column=0, padx=12, pady=20)
checkbox_done = CTkCheckBox(view_root, text="Check Me If Finished", text_font=("Roboto", 20))
checkbox_done.grid(row=4, column=1, padx=12, pady=20)
delete_btn = CTkButton(view_root, text="Delete", text_font=("Roboto", 20), command=delete)
delete_btn.grid(row=5, column=0, padx=12, pady=20)
view_root.mainloop()
def load():
check_thread = threading.Thread(target=thread_checkbox)
check_thread.start()
row = sheet.max_row - 1
if row != 0:
global title, description, done, date
for _ in range(row):
if row == 0:
break
title = (sheet.cell(row, 1).value)
description = (sheet.cell(row, 2).value)
status = bool(sheet.cell(row, 3).value)
date = (sheet.cell(row, 4).value)
done = "Done" if status else "To-Do"
CTkButton(root, text=f"{title} | {done}", text_font=("Roboto", 20), fg_color="yellow", command=lambda: open(row)).pack(pady=10)
row - 1
#call load function
load()
#frames
menu_frame = CTkFrame(root, width=500, height=150, fg_color="yellow")
menu_frame.pack()
#menu frame items
create_task_window_btn = CTkButton(menu_frame, text=" ", text_font=("Roboto", 25), width=100, height=70, command=create_task_window)
create_task_window_btn.grid(row=0, column=0)
main_title_label = CTkLabel(menu_frame, text="To-Do App", text_font=("Roboto", 20), width=260, height=70)
main_title_label.grid(row=0, column=1)
delete_all_btn = CTkButton(menu_frame, text="Delete All", text_font=("Roboto", 22), width=100, height=70, command=delete_all)
delete_all_btn.grid(row=0, column=2)
root.mainloop()
I was expecting the main GUI to work but I didn't know if the others would work.
one last thing is that if you run it and it works, try to use it a bit and let me know if something is rong.
Thanks.
CodePudding user response:
The problem is that your open
function accepts a parameter named num
, but you also have a global variable with that name. Just change the name of your num
parameter in open
to something else to avoid the conflict
def open(num_in):
global checkbox_done, num
num = num_in
Also, it's probably a good idea to name the open
function something else since open
is already a function keyword in Python
def open_todo(num_in):
global checkbox_done, num
num = num_in