英文:
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
import tkinter
from tkinter import *
from tkinter import ttk
from tkinter import messagebox
def enter_data():
print(material_category)
window.quit()
#GUI
window = tkinter.Tk()
window.title("Stress Data Entry")
window.resizable(0,0)
frame = tkinter.Frame(window)
frame.pack()
#MATERIAL CATEGORY
material_category_frame =tkinter.LabelFrame(frame, text="Material Category")
material_category_frame.grid(row= 0, column=1, padx=20, pady=10)
material_category_option=["Common Steel","Soldering Steel", "Carburized Steel", "Upgraded Steel", "Nitrogenous Steel"]
x=IntVar()
def material_category_selection():
global material_category
if(x.get()==0):
material_category="commonsteel"
elif(x.get()==1):
material_category="solderingsteel"
elif(x.get()==2):
material_category="carburizedsteel"
elif(x.get()==3):
material_category="upgradedsteel"
elif(x.get()==4):
material_category="nitrogenoussteel"
else:
tkinter.messagebox.showwarning(title="Error!", message="Something went wrong!")
for index in range(len(material_category_option)):
radiobutton = Radiobutton(material_category_frame,
text=material_category_option[index],
variable=x,
value=index,
padx=20,
pady=10,
command=material_category_selection)
for widget in material_category_frame.winfo_children():
widget.grid_configure(padx=10, pady=5)
button = tkinter.Button(frame, text="Enter Data", command= enter_data)
button.grid(row=3, column=1, sticky="news", padx=20, pady=10)
window.mainloop()
答案1
得分: 1
错误是由于 material_category_selection()
尚未执行,因此 material_category
未被创建。
我建议将 material_category_selection()
的逻辑放入 enter_data()
中,因为我看不到 material_category_selection()
有任何必要性:
# 移除通配符导入,因为不建议使用
import tkinter
from tkinter import messagebox
def enter_data():
global material_category
try:
if(x.get()==0):
material_category="普通钢"
elif(x.get()==1):
material_category="焊接钢"
elif(x.get()==2):
material_category="渗碳钢"
elif(x.get()==3):
material_category="升级钢"
elif(x.get()==4):
material_category="含氮钢"
else:
raise Exception("出现了问题!")
print(material_category)
window.destroy()
except Exception as ex:
messagebox.showwarning(title="错误!", message=ex)
# GUI
window = tkinter.Tk()
window.title("应力数据输入")
window.resizable(0, 0)
frame = tkinter.Frame(window)
frame.pack()
material_category_frame =tkinter.LabelFrame(frame, text="材料类别")
material_category_frame.grid(row= 0, column=1, padx=20, pady=10)
material_category_option=["普通钢", "焊接钢", "渗碳钢", "升级钢", "含氮钢"]
x = tkinter.IntVar() # 默认值将设置为0
for index, text in enumerate(material_category_option):
radiobutton = tkinter.Radiobutton(material_category_frame,
text=text,
variable=x,
value=index,
padx=20,
pady=10) # 移除了command选项
radiobutton.grid_configure(padx=10, pady=5, sticky="w")
button = tkinter.Button(frame, text="输入数据", command= enter_data)
button.grid(row=3, column=1, sticky="news", padx=20, pady=10)
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()
:
# removed wildcard import as it is not recommended
import tkinter
from tkinter import messagebox
def enter_data():
global material_category
try:
if(x.get()==0):
material_category="commonsteel"
elif(x.get()==1):
material_category="solderingsteel"
elif(x.get()==2):
material_category="carburizedsteel"
elif(x.get()==3):
material_category="upgradedsteel"
elif(x.get()==4):
material_category="nitrogenoussteel"
else:
raise Exception("Something went wrong!")
print(material_category)
window.destroy()
except Exception as ex:
messagebox.showwarning(title="Error!", message=ex)
#GUI
window = tkinter.Tk()
window.title("Stress Data Entry")
window.resizable(0, 0)
frame = tkinter.Frame(window)
frame.pack()
material_category_frame =tkinter.LabelFrame(frame, text="Material Category")
material_category_frame.grid(row= 0, column=1, padx=20, pady=10)
material_category_option=["Common Steel", "Soldering Steel", "Carburized Steel", "Upgraded Steel", "Nitrogenous Steel"]
x = tkinter.IntVar() # value 0 will be set by default
for index, text in enumerate(material_category_option):
radiobutton = tkinter.Radiobutton(material_category_frame,
text=text,
variable=x,
value=index,
padx=20,
pady=10) # removed command option
radiobutton.grid_configure(padx=10, pady=5, sticky="w")
button = tkinter.Button(frame, text="Enter Data", command= enter_data)
button.grid(row=3, column=1, sticky="news", padx=20, pady=10)
window.mainloop()
答案2
得分: 0
在你的情况下,如果用户没有点击“Radiobutton”而点击了“'Enter Data'”,它会调用“enter_data()”,但你从未定义了“material_category”,会导致“NameError”。因此,你可以使用错误处理:
def enter_data():
try:
print(material_category)
window.quit()
except NameError:
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:
def enter_data():
try:
print(material_category)
window.quit()
except NameError:
tkinter.messagebox.showwarning(title="Error!", message="Please provide a material!")
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论