有没有更简单的方法来编写包含多个组合框和嵌套字典的代码,并避免KeyError?

2024-10-03 06:24:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Python还比较陌生,在花了很多时间之后,我不必问任何问题就成功地实现了这一点,然而,它似乎可以被重写得更好,并且以一种可以摆脱这个KeyError: ''的方式。键错误只会出现(并使函数暂停),直到我从每个组合框中选择了一个项,然后由于我在函数中的数学运算,它会继续出现,但我无法找到另一种编写方法来解决这个问题并使代码更紧凑。我肯定有办法,但我绝对可以用一个指向正确方向的指针,谢谢! 下面是我的程序的一个更简单的演示版本:

import tkinter as tk
import tkinter.ttk as ttk

#DICTIONARIES#
weapondict = {"Bronze Sword": {"atk":32, "def":4}, "Iron Sword": {"atk":47, "def":5}}
shielddict = {"Bronze Shield": {"atk":3, "def":10}, "Iron Shield": {"atk":5, "def":27}}

#FUNCTION#
def selected(func):
    a = weapondict[weaponvar.get()]["atk"]
    b = shielddict[shieldvar.get()]["atk"]
    atkvar.set(a + b)
    c = weapondict[weaponvar.get()]["def"]
    d = shielddict[shieldvar.get()]["def"]
    defvar.set(c + d)

#WINDOWLOOP#
root = tk.Tk()
root.geometry("250x125")

#VARIABLES#
weaponvar = tk.StringVar()
shieldvar = tk.StringVar()
atkvar = tk.IntVar()
defvar = tk.IntVar()

#COMBOBOXES#
weaponbox = ttk.Combobox(root, height=5, state="readonly", values=list(weapondict.keys()), textvariable=weaponvar)
weaponbox.place(x=10, y=10, width=130)
weaponbox.bind('<<ComboboxSelected>>', func=selected)

shieldbox = ttk.Combobox(root, height=5, state="readonly", values=list(shielddict.keys()), textvariable=shieldvar)
shieldbox.place(x=10, y=70, width=130)
shieldbox.bind('<<ComboboxSelected>>', func=selected)

#LABELS#
atklabel = tk.Label(root, text='Atk Bonus:')
atklabel.place(x=150, y=10, width=70, height=20)

deflabel = tk.Label(root, text='Def Bonus:')
deflabel.place(x=150, y=70, width=70, height=20)

atktotal = tk.Label(root, textvariable=atkvar)
atktotal.place(x=155, y=30, width=100, height=20)

deftotal = tk.Label(root, textvariable=defvar)
deftotal.place(x=155, y=90, width=100, height=20)

root.mainloop()

我们的目标只是从每个组合框中选择一个值,并将其指定为一个值,然后将该整数添加到另一个组合框中以得到一个总数,同时解决keyerror问题并使代码更易于阅读和编辑。我想放多个盒子,每个盒子都有多个物品,这样会很乱,提前谢谢


Tags: getdefplacerootwidthlabeltkttk
1条回答
网友
1楼 · 发布于 2024-10-03 06:24:31

问题是tk.StringVarget()方法调用将返回"",而其中没有任何内容。一个简单的解决方法是在两个字典中添加一个条目来匹配这个“空”键,并给它们一些相关的值,以便在相应的Combobox中没有选择任何内容(即零)时使用:

#DICTIONARIES#
weapondict = {"": {"atk":0, "def":0},  # Use when nothing is selected.
              "Bronze Sword": {"atk":32, "def":4},
              "Iron Sword": {"atk":47, "def":5}}
shielddict = {"": {"atk":0, "def":0},  # Use when nothing is selected.
              "Bronze Shield": {"atk":3, "def":10},
              "Iron Shield": {"atk":5, "def":27}}

另一种方法是修改selected()函数,在尝试使用它们之前检查weaponvar.get()shieldvar.get()返回的值是否是相应字典中的键。如果不是,则可以提供abcd的一些默认值

这是完全可行的,但在我看来,修改这两本词典要容易得多

还要注意这两个嵌套字典是如何定义的。我发现在多行上做会更有可读性

相关问题 更多 >