为什么我的文本小部件在使用删除函数时没有被清除?

huangapple go评论60阅读模式
英文:

Why isn't my text widget getting cleared with the delete function?

问题

我正在使用tkinter构建一个菜单,其中有不同的按钮用于前菜(Entrees)、主菜(Mains)和甜点(Desserts)。当您单击某个按钮时,菜单项应该更改以反映当前选择,然而,我在我的printItems函数中使用的.delete()似乎不起作用。程序默认停留在前菜(Entrees)菜单上。

#设置 - TKinter
import tkinter as tk
w = tk.Tk()
w.title("交互式餐厅菜单")
w.geometry("640x640")
w.resizable(False,False)
w['bg'] = 'black'

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

#打印菜单项
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)

#标题和按钮
head = tk.Label(text="菜单", font=("Garamond", 40), bg='black')
head.grid(column=0, row=0, columnspan=4, sticky='N', pady=10)

app = tk.Button(text="前菜", width=12, height=2, command=lambda: printItems('Entree'))
main = tk.Button(text="主菜", width=12, height=2, command=lambda: printItems("Main"))
des = tk.Button(text="甜点", width=12, height=2)
deal = tk.Button(text="特惠套餐", 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()

请注意,我对"前菜"和"主菜"按钮的命令使用了lambda函数,以便在单击按钮时才调用printItems函数,而不是在创建按钮时立即调用它。这样可以确保单击按钮时才会更新菜单项。

英文:

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()

为什么我的文本小部件在使用删除函数时没有被清除?

答案1

得分: 1

问题出在你如何绑定 printItems 函数的地方:

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

这两个按钮的 command 参数应该改成 lambda 表达式,这样你可以像这样传递正确的字符串参数给 printItems 函数:

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"))

不同之处在于,如原始写法所示,当你实例化 tk.Button 对象时,printItems 会立即被调用,这不是你想要的。相反,将它们包装在 lambda 表达式中会将它们变成所谓的“匿名函数” - 基本上,你告诉它在需要时调用运行你的函数的 lambda,而不是直接调用它。

英文:

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.

huangapple
  • 本文由 发表于 2023年7月3日 22:20:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76605641.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定