有没有更简单的方法来编写涉及多个组合框和嵌套字典的代码,同时避免 KeyError?
Is there a simpler way to write this code involving multiple comboboxes and nested dictionaries, and also avoid the KeyError?
我是 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()
目标只是从每个组合框中进行选择并取其指定值,将该整数与另一个组合框相加得出总数,同时解决键错误问题并使代码更易读和更易于编辑。我想放多个盒子,每个盒子有多个物品,用这种方法会变得很乱,提前谢谢你!
问题是 tk.StringVar
get()
方法调用将 return ""
当它们没有任何内容时。一个简单的修复方法是在两个字典中添加一个条目来匹配此 "empty" 键,并为它们提供一些关联值,以便在相应的 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()
编辑的值 return 是否是相应字典中的键使用它们。如果不是,则可以提供 a
、b
、c
或 d
的一些默认值。
这是完全可行的,但在我看来,更改两个词典要容易得多。
还要注意两个嵌套字典是如何定义的。我发现在多行上这样做更具可读性。
我是 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()
目标只是从每个组合框中进行选择并取其指定值,将该整数与另一个组合框相加得出总数,同时解决键错误问题并使代码更易读和更易于编辑。我想放多个盒子,每个盒子有多个物品,用这种方法会变得很乱,提前谢谢你!
问题是 tk.StringVar
get()
方法调用将 return ""
当它们没有任何内容时。一个简单的修复方法是在两个字典中添加一个条目来匹配此 "empty" 键,并为它们提供一些关联值,以便在相应的 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()
编辑的值 return 是否是相应字典中的键使用它们。如果不是,则可以提供 a
、b
、c
或 d
的一些默认值。
这是完全可行的,但在我看来,更改两个词典要容易得多。
还要注意两个嵌套字典是如何定义的。我发现在多行上这样做更具可读性。