如何使用字典创建tkinter复选框,然后检查哪些是勾选的

时间:2018-04-01 16:38:02

标签: python dictionary checkbox tkinter

我正在尝试在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。

我不确定我的问题是什么,或者我是否以错误的方式接近这个问题。

1 个答案:

答案 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字典,以便我们可以跟踪是否已选择按钮。
它很容易参考这个表,因为键是项目本身!整洁,不是吗?

关于tkinter的更多提示:

  • 如果您每次都在下一行进行网格化,只需调用grid()而不使用col和row参数 - tkinter会为您添加行,并保留该列。

  • 最好始终创建窗口小部件,将其存储为变量,然后对此变量进行网格化。有些人尝试将其全部集中在一起,然后在尝试通过此变量引用其窗口小部件时感到困惑。他们什么都找不到,因为网格方法什么都没有返回!

我希望这有帮助。祝你好运!