默认选中的单选按钮未分配值,导致NameError。

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

Default selected radio button isn't assigned a value resulting in NameError

问题

我正在尝试使用Python的tkinter创建一个带有Radiobuttons的GUI。尽管我已经在选择函数内指定了相关变量(material_category)为全局,但我仍然无法检索所选选项的值。

当我按“Enter Data”按钮运行代码时,没有选择除默认选择(即“Common Steel”)之外的不同选项,我会收到以下错误消息:

“NameError: name 'material_category' is not defined”

只有当用户根本不触碰单选按钮窗口并立即按“Enter”按钮时,才会出现此错误。如果用户按下任何单选按钮,代码就会正常工作。

但我感到困惑的是,为什么起始单选按钮(即“Common Steel”)似乎被选中但未被分配一个值(换句话说,为什么x未被分配值0,即使该选项被选中)。是否有办法将x的默认值设置为0?

我该如何修改代码,以使其在没有错误或异常处理的情况下运行?是否有更好、更紧凑的编码方式,以省略检查选择的material_category_selection()函数?

Python版本:3.11.1
IDE:VSCodium

英文:

I am trying to create a GUI with radiobuttons using tkinter from python. I am having trouble retrieving the value of the selected option, even though I have specified the variable (material_category) in question to be global inside the selection function.

When I press the Enter Data button to run my code without selecting a different option other than the one appearing selected by default (i.e. Common Steel), I am greeted with this error:

"NameError: name 'material_category' is not defined"

This error appears only if the user doesn't fiddle at all with the radio-button windows and presses the Enter button button straight away. In case the user gets to press any radio button the code works fine.

I am bamboozled though, as to why the starting radio button (i.e. "Common Steel") appears selected but is not assigned a value (in other words why x is not assigned the value of 0, even though that option appears selected). Is there a way I could assign the default value of 0 to x?

What can I do to actually make this code run without errors or handling an exception? Is there a better, more compact way to code this in order to omit the material_category_selection() function that checks the selection?

Python version: 3.11.1
IDE: VSCodium

  1. import tkinter
  2. from tkinter import *
  3. from tkinter import ttk
  4. from tkinter import messagebox
  5. def enter_data():
  6. print(material_category)
  7. window.quit()
  8. #GUI
  9. window = tkinter.Tk()
  10. window.title("Stress Data Entry")
  11. window.resizable(0,0)
  12. frame = tkinter.Frame(window)
  13. frame.pack()
  14. #MATERIAL CATEGORY
  15. material_category_frame =tkinter.LabelFrame(frame, text="Material Category")
  16. material_category_frame.grid(row= 0, column=1, padx=20, pady=10)
  17. material_category_option=["Common Steel","Soldering Steel", "Carburized Steel", "Upgraded Steel", "Nitrogenous Steel"]
  18. x=IntVar()
  19. def material_category_selection():
  20. global material_category
  21. if(x.get()==0):
  22. material_category="commonsteel"
  23. elif(x.get()==1):
  24. material_category="solderingsteel"
  25. elif(x.get()==2):
  26. material_category="carburizedsteel"
  27. elif(x.get()==3):
  28. material_category="upgradedsteel"
  29. elif(x.get()==4):
  30. material_category="nitrogenoussteel"
  31. else:
  32. tkinter.messagebox.showwarning(title="Error!", message="Something went wrong!")
  33. for index in range(len(material_category_option)):
  34. radiobutton = Radiobutton(material_category_frame,
  35. text=material_category_option[index],
  36. variable=x,
  37. value=index,
  38. padx=20,
  39. pady=10,
  40. command=material_category_selection)
  41. for widget in material_category_frame.winfo_children():
  42. widget.grid_configure(padx=10, pady=5)
  43. button = tkinter.Button(frame, text="Enter Data", command= enter_data)
  44. button.grid(row=3, column=1, sticky="news", padx=20, pady=10)
  45. window.mainloop()

答案1

得分: 1

错误是由于 material_category_selection() 尚未执行,因此 material_category 未被创建。

我建议将 material_category_selection() 的逻辑放入 enter_data() 中,因为我看不到 material_category_selection() 有任何必要性:

  1. # 移除通配符导入,因为不建议使用
  2. import tkinter
  3. from tkinter import messagebox
  4. def enter_data():
  5. global material_category
  6. try:
  7. if(x.get()==0):
  8. material_category="普通钢"
  9. elif(x.get()==1):
  10. material_category="焊接钢"
  11. elif(x.get()==2):
  12. material_category="渗碳钢"
  13. elif(x.get()==3):
  14. material_category="升级钢"
  15. elif(x.get()==4):
  16. material_category="含氮钢"
  17. else:
  18. raise Exception("出现了问题!")
  19. print(material_category)
  20. window.destroy()
  21. except Exception as ex:
  22. messagebox.showwarning(title="错误!", message=ex)
  23. # GUI
  24. window = tkinter.Tk()
  25. window.title("应力数据输入")
  26. window.resizable(0, 0)
  27. frame = tkinter.Frame(window)
  28. frame.pack()
  29. material_category_frame =tkinter.LabelFrame(frame, text="材料类别")
  30. material_category_frame.grid(row= 0, column=1, padx=20, pady=10)
  31. material_category_option=["普通钢", "焊接钢", "渗碳钢", "升级钢", "含氮钢"]
  32. x = tkinter.IntVar() # 默认值将设置为0
  33. for index, text in enumerate(material_category_option):
  34. radiobutton = tkinter.Radiobutton(material_category_frame,
  35. text=text,
  36. variable=x,
  37. value=index,
  38. padx=20,
  39. pady=10) # 移除了command选项
  40. radiobutton.grid_configure(padx=10, pady=5, sticky="w")
  41. button = tkinter.Button(frame, text="输入数据", command= enter_data)
  42. button.grid(row=3, column=1, sticky="news", padx=20, pady=10)
  43. window.mainloop()
英文:

The error is caused by that material_category_selection() has not been executed yet so material_category is not created.

I would suggest to put the logic of material_category_selection() into enter_data() as I don't see any necessity of material_category_selection():

  1. # removed wildcard import as it is not recommended
  2. import tkinter
  3. from tkinter import messagebox
  4. def enter_data():
  5. global material_category
  6. try:
  7. if(x.get()==0):
  8. material_category="commonsteel"
  9. elif(x.get()==1):
  10. material_category="solderingsteel"
  11. elif(x.get()==2):
  12. material_category="carburizedsteel"
  13. elif(x.get()==3):
  14. material_category="upgradedsteel"
  15. elif(x.get()==4):
  16. material_category="nitrogenoussteel"
  17. else:
  18. raise Exception("Something went wrong!")
  19. print(material_category)
  20. window.destroy()
  21. except Exception as ex:
  22. messagebox.showwarning(title="Error!", message=ex)
  23. #GUI
  24. window = tkinter.Tk()
  25. window.title("Stress Data Entry")
  26. window.resizable(0, 0)
  27. frame = tkinter.Frame(window)
  28. frame.pack()
  29. material_category_frame =tkinter.LabelFrame(frame, text="Material Category")
  30. material_category_frame.grid(row= 0, column=1, padx=20, pady=10)
  31. material_category_option=["Common Steel", "Soldering Steel", "Carburized Steel", "Upgraded Steel", "Nitrogenous Steel"]
  32. x = tkinter.IntVar() # value 0 will be set by default
  33. for index, text in enumerate(material_category_option):
  34. radiobutton = tkinter.Radiobutton(material_category_frame,
  35. text=text,
  36. variable=x,
  37. value=index,
  38. padx=20,
  39. pady=10) # removed command option
  40. radiobutton.grid_configure(padx=10, pady=5, sticky="w")
  41. button = tkinter.Button(frame, text="Enter Data", command= enter_data)
  42. button.grid(row=3, column=1, sticky="news", padx=20, pady=10)
  43. window.mainloop()

答案2

得分: 0

在你的情况下,如果用户没有点击“Radiobutton”而点击了“'Enter Data'”,它会调用“enter_data()”,但你从未定义了“material_category”,会导致“NameError”。因此,你可以使用错误处理:

  1. def enter_data():
  2. try:
  3. print(material_category)
  4. window.quit()
  5. except NameError:
  6. tkinter.messagebox.showwarning(title="Error!", message="Please provide a material!")
英文:

In your case, if the user does not click a Radiobutton but clicks 'Enter Data', it calls enter_data(), but you never defined material_category, giving a NameError. So, you can use error handling:

  1. def enter_data():
  2. try:
  3. print(material_category)
  4. window.quit()
  5. except NameError:
  6. tkinter.messagebox.showwarning(title="Error!", message="Please provide a material!")

huangapple
  • 本文由 发表于 2023年7月14日 04:00:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76682861.html
匿名

发表评论

匿名网友

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

确定