How can i display courses in the listbox of gui window in Python?

63 Views Asked by At

I have a project to make a timetable for a university when I run the code I don't have any errors but I got this problem. When I enter the path of my excel CSV file on the Entry widget, then I click to read and display but nothing shows on the courses or filtered courses, can you help me solve this problem?

import tkinter as tk
import csv
from tkinter import messagebox
from tkinter import ttk

all_courses = []


def read_csv(path):
    # use the csv module to read the contents of the file at the provided path
    with open(path, newline='', encoding='utf-8') as csvfile:
        data = csv.reader(csvfile)
        all_courses.extend([row for row in data])
        display_courses()

def filter_courses(all_courses, year, code):
    # filter the courses based on the selected year and/or code
    filtered_courses = []
    for course in all_courses:
        if (year in course[1] or year == "") and (code in course[0] or code == ""):
            filtered_courses.append(course)
    return filtered_courses


def add_course(course, timetable=None):
    # add the selected course to the timetable
    timetable.append(course)
    print("Added course:", course)


def remove_course(course, timetable=None):
    # remove the selected course from the timetable
    timetable.remove(course)
    print("Removed course:", course)


def clear_timetable(timetable=None):
    # clear the timetable
    timetable.clear()
    print("Timetable cleared.")


def save_timetable(timetable=None):
    # use the csv module to write the timetable to a new file
    with open("timetable.csv", "w", newline='', encoding='utf-8') as f:
        writer = csv.writer(f)
        writer.writerows(timetable)
    print("Timetable saved.")


def display_courses(all_courses=None):
    filtered_courses = filter_courses(all_courses, year_var.get(), code_var.get())
    courses_list.delete(0, tk.END)
    for course in filtered_courses:
        courses_list.insert(tk.END, course)



# add a warning message for when the user doesn't choose a file path
def display_warning():
    if not file_path_entry.get():
        messagebox.showwarning("Warning", "Please select a file path first")

        display_button.config(command=lambda: [display_courses(all_courses), display_warning()])


# create a GUI window
root = tk.Tk()
root.title("Timetable Tool")

# create an Entry widget to accept the input csv file path
file_path_label = tk.Label(root, text="Input File Path:")
file_path_label.pack()
file_path_entry = tk.Entry(root,)
file_path_entry.pack()

file_path_entry.pack()

# create a button to read the contents of the input file
read_button = tk.Button(root, text="Read", command=lambda: read_csv(file_path_entry.get()))
read_button.pack()

# create a button to display the filtered courses
display_button = tk.Button(root, text="Display", command=lambda: display_courses(all_courses))
display_button.pack()

# create a ComboBox widget to allow the user to select the year and code
year_label = tk.Label(root, text="Year:")
year_label.pack()
year_var = tk.StringVar()
year_var.set("")
year_dropdown = tk.OptionMenu(root, year_var, "1", "2", "3", "4","5")
year_dropdown.pack()

code_label = tk.Label(root, text="Code:")
code_label.pack()
code_var = tk.StringVar()
code_var.set("")
code_dropdown = tk.OptionMenu(root, code_var,"CHI" ,"CS","ECE","ECON","EE", "EECS","ENGR","FRE","IE","ISE","LIFE",
                              "MATH", "MGT", "UNI")
code_dropdown.pack()

# create a Label widget for the "Courses" box
courses_label = tk.Label(root, text="Courses:")
courses_label.pack()

# create a Listbox widget to display the filtered courses
courses_list = tk.Listbox(root)
courses_list.pack()

# create a Label widget for the "Selected Courses" box
selected_courses_label = tk.Label(root, text="Selected Courses:")
selected_courses_label.pack()

# create a Listbox widget to display the selected courses
selected_courses_list = tk.Listbox(root)
selected_courses_list.pack()


# create buttons to add and remove courses from the timetable
add_button = tk.Button(root, text="Add", command=lambda: add_course(courses_list.get(courses_list.curselection())))
add_button.pack()
remove_button = tk.Button(root, text="Remove", command=lambda: remove_course(courses_list.get(courses_list.curselection(
))))
remove_button.pack()

# create a button to clear the timetable
clear_button = tk.Button(root, text="Clear", command=clear_timetable)
clear_button.pack()

# create a button to save the timetable to a new file
save_button = tk.Button(root, text="Save", command=save_timetable)
save_button.pack()

s = ttk.Style()
s.theme_use("clam")
courses_list.configure(background='yellow')
selected_courses_list.configure(background='blue')

# run the GUI
root.mainloop()

I tried to activate this function but it didn't work out.

read_csv
def read_csv(path):
1

There are 1 best solutions below

0
acw1668 On

You have called display_courses() without argument inside read_csv(), so all_courses inside display_courses is set to None which will raise exception when filter_courses(all_courses, ...) is executed.

Pass all_courses to display_courses() inside read_csv():

def read_csv(path):
    # use the csv module to read the contents of the file at the provided path
    with open(path, newline='', encoding='utf-8') as csvfile:
        data = csv.reader(csvfile)
        all_courses.extend([row for row in data])
        display_courses(all_courses)

Or set the default value of all_courses argument to all_courses instead of None for the display_courses() function:

def display_courses(all_courses=all_courses):
    ...

Also suggest to add empty string "" option to the two OptionMenu so that you can reset the filter:

...
year_dropdown = tk.OptionMenu(root, year_var, "", "1", "2", "3", "4","5")
...
code_dropdown = tk.OptionMenu(root, code_var, "", "CHI" ,"CS","ECE","ECON","EE", "EECS","ENGR","FRE","IE","ISE","LIFE",
                              "MATH", "MGT", "UNI")
...