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

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

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!")

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:

确定