0

I am building a menu using tkinter which has different buttons for Entrees, Mains and Desserts. When you click a certain button the menu items should change to reflect that however the .delete() I am using in my printItems function doesn't seem to be working. The program is stuck on the Entrees menu by default

#Setup - TKinter
import tkinter as tk
w = tk.Tk()
w.title("Interactive Restaurant Menu")
w.geometry("640x640")
w.resizable(False,False)
w['bg'] = 'black'

#Setup - SQL
import mysql.connector as mc
con = mc.connect(user = 'root',host = 'localhost', password = 'Cars!234',database = 'Zayan')
cur = con.cursor()

#Printing Menu Items
v = tk.Scrollbar( orient='vertical')
items = tk.Text(bg = 'black',font = ('Baskerville', 18),wrap = tk.WORD,yscrollcommand = v.set)
items.grid(column = 0,row = 2, columnspan = 4,padx = 20)

def getItem(ID, course):
    currentItem = []
    table_name = "Menu" + course
    query = "SELECT Item,Price,Description FROM {} WHERE ID = %s".format(table_name)
    cur.execute(query, (ID,))
    result = cur.fetchone()
    currentItem.append(result[0] + ' (' + str(result[1]) + '$)')
    currentItem.append(result[2])
    return currentItem

def printItems(course):
    items.delete(1.0,'end')
    cur.execute("select max(ID) from {}".format("Menu" + course))
    n = cur.fetchone()
    for i in range(1,n[0] + 1):
        items.insert(tk.END,'\n\n' + str(i) + "." + getItem(i,course)[0] + '\n' + getItem(i,course)[1])
    items.config(state='disabled',highlightthickness=0)

#Title And Buttons
head = tk.Label(text = "Menu",font = ("Garamond",40),bg = 'black')
head.grid(column = 0,row = 0,columnspan = 4, sticky = 'N', pady = 10)

app = tk.Button(text="Entrees",width = 12,height = 2,command = printItems('Entree'))
main = tk.Button(text="Mains",width = 12,height = 2,command  = printItems("Main"))
des = tk.Button(text="Desserts",width = 12,height = 2)
deal = tk.Button(text="Deals",width = 12,height = 2)

app.grid(column = 0, row = 1,padx = 8)
main.grid(column = 1, row = 1,padx = 8)
des.grid(column = 2, row = 1,padx = 8)
deal.grid(column = 3, row = 1,padx = 8)
w.grid_columnconfigure((0,1,2,3), weight=1)

w.mainloop()

Output:

  • Replace this `items.delete(1.0,'end')` to `items.delete(0, tk.END)` – toyota Supra Jul 03 '23 at 15:12
  • @toyotaSupra for whatever it's worth `tk.END` *is* the literal string `'end'` so it's no different, and an index of `0` will result in `_tkinter.TclError: bad text index "0"` (though `0.0` is valid). All that said, `items.delete(1.0,'end')` *should* work, so it's likely that something else is going on here. – JRiggles Jul 03 '23 at 15:22

1 Answers1

1

The issue lies in how you're binding printItems here:

app = tk.Button(text="Entrees",width = 12,height = 2,command = printItems('Entree'))
main = tk.Button(text="Mains",width = 12,height = 2,command  = printItems("Main"))

The command parameter for each of these buttons should be made into a lambda so that you can pass the appropriate string argument to printItems like so:

app = tk.Button(text="Entrees", width=12, height=2, command=lambda: printItems('Entree'))
main = tk.Button(text="Mains", width=12, height=2, command=lambda: printItems("Main"))

The difference is that as-written, printItems is being called immediately when you instantaite your tk.Button objects, which isn't what you want. Instead, wrapping them in a lambda expression turns them into so-called "anonymous functions" - basically, you're telling it to call the lambda that runs your function for you as-needed, instead of calling it directly.

JRiggles
  • 4,847
  • 1
  • 12
  • 27
  • The function no longer runs upon execution. Much appreciated! However, the text still doesn't get cleared, meaning that pressing one button has the desired effect, but pressing another after that does nothing. Thank you for addressing the other problem though! – Zayan Anwar Jul 03 '23 at 15:36
  • I've figured it out! It was the state = disabled at the end of the function. Putting a state = normal at the beginning of the function fixed the issue. – Zayan Anwar Jul 03 '23 at 15:50
  • Ah, that'd do it - good catch! – JRiggles Jul 03 '23 at 15:52