Home > Net >  To-Do app on customtkinter not working (error: name 'num' is parameter and global) Python
To-Do app on customtkinter not working (error: name 'num' is parameter and global) Python

Time:12-13

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:

enter image description here

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
  • Related