我正在尝试在tkinter中创建一个菜单程序,其中复选框是从字典中的项目创建的,然后在单击按钮时计算所选项目的总价格。
menu_items = {"Spam - £3" : 3, "Eggs - £7" : 7, "Chips - £1" : 1, "Beer - £2" : 2}
def widgets(self):
# create menu list
row = 1
for item in menu_items:
self.item = BooleanVar()
Checkbutton(self,
text = item,
variable = self.item
).grid(row = row, column = 0, sticky = W)
row += 1
calc_but = Button(self,
text = "Click to calculate",
command = self.calculate
).grid(row = row + 1, column = 0, sticky = W)
self.results_txt = Text(self, width = 20, height = 4, wrap = WORD)
self.results_txt.grid(row = row + 2, column = 0, columnspan = 2)
这会创建复选框,按钮和文本显示,但我的问题来自于我的计算方法。
def calculate(self):
bill = 0
for item in menu_items:
if self.item.get():
bill += menu_items.get(item)
msg = "Total cost - £" + str(bill)
self.results_txt.delete(0.0, END)
self.results_txt.insert(0.0, msg)
它会添加所有内容(勾选或不勾选),但仅在勾选最后一个复选框时添加。如果未勾选最终项目,则显示0。
我不确定我的问题是什么,或者我是否以错误的方式接近这个问题。
答案 0 :(得分:1)
创建按钮的方式 - 通过循环遍历字典中的每个键 - 您的程序仅引用您创建的最后一个键,它保存为self.item
。当您致电calculate()
时,它只会检查并添加此按钮的值
解决此问题的一种方法是在表中保存对这些按钮的所有引用:
menu_items = {"eggs":7, "chips":1, "beer":2}
selected = {}
def calculate():
bill = 0
for item in menu_items:
if selected[item].get():
bill += menu_items[item]
results.delete(1.0, END)
results.insert(END, "Total cost - £" + str(bill))
for item in menu_items:
is_selected = BooleanVar()
button = Checkbutton(master, text=item, variable=is_selected)
button.grid(sticky="w")
selected[item] = is_selected
purchase_btn = Button(master, text="Calculate", command=calculate)
purchase_btn.grid()
results = Text(master, wrap=WORD)
results.grid(columnspan=2)
(我在这里省略了你的课程结构。重新合并它很容易)
现在我们要保留is_selected
字典,以便我们可以跟踪是否已选择按钮。
它很容易参考这个表,因为键是项目本身!整洁,不是吗?
如果您每次都在下一行进行网格化,只需调用grid()
而不使用col和row参数 - tkinter会为您添加行,并保留该列。
最好始终创建窗口小部件,将其存储为变量,然后对此变量进行网格化。有些人尝试将其全部集中在一起,然后在尝试通过此变量引用其窗口小部件时感到困惑。他们什么都找不到,因为网格方法什么都没有返回!
我希望这有帮助。祝你好运!