Tkinter多框架Python应用中Radiobutton变量未定义错误排查求助
问题分析与解决方案
你遇到的错误核心是变量作用域问题:movie是PageOne类的__init__方法里的局部变量,而save_info是全局函数,它根本无法访问类内部的局部变量。另外还有个小坑:你用mybutton=ttk.Radiobutton(...).grid(...)的写法,其实grid()方法返回None,所以mybutton并不是按钮对象,只是个None值,以后如果要操作按钮会出问题。
下面是修正后的完整代码,我会一步步解释改动点:
import tkinter as tk from tkinter import ttk LARGE_FONT=("Verdana", 12) class Movies(tk.Tk): def __init__(self, *args, **kwargs): tk.Tk.__init__(self,*args, **kwargs) tk.Tk.wm_title(self, "Movie I like") tk.Tk.wm_geometry(self, "500x500") container=tk.Frame(self) container.pack(side="top", fill="both", expand="True") self.frames={} for F in (StartPage, PageOne): frame= F(container, self) self.frames[F]= frame frame.grid(row=0, column=0, sticky="nsew") self.show_frame(StartPage) def show_frame(self, cont): frame=self.frames[cont] frame.tkraise() class StartPage(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) s = ttk.Style() s.configure('my.TButton', font=('Verdana', 8)) label=tk.Label(self, text="Home Page", font=LARGE_FONT) label.pack(pady=10, padx=30) button_load=ttk.Button(self, text="Kind of Movie ", width=30, style='my.TButton', command= lambda: controller.show_frame(PageOne)) button_load.pack(padx=30) class PageOne(tk.Frame): def __init__(self, parent, controller): tk.Frame.__init__(self, parent) # 把movie改成实例属性,这样类内部的方法能访问到 self.movie= tk.StringVar() self.movie.set("1") # 分开创建按钮和布局,避免变量被赋值为None mybutton=ttk.Radiobutton(self, text='Drama', variable=self.movie, value="Drama") mybutton.grid(column=1,row=1, sticky=tk.W, padx=10) mybutton1=ttk.Radiobutton(self, text='Comedy', variable=self.movie, value="Comedy") mybutton1.grid(column=2,row=1, sticky=tk.W, padx=10) # 把command指向当前实例的save_info方法 button_submit=ttk.Button(self, text="Submit", width=15, command=self.save_info) button_submit.grid(column=3, row= 10, padx=5) # 把save_info改成类的方法,这样就能访问self.movie def save_info(self): movie_info=self.movie.get() print("you like " + movie_info) app=Movies() app.mainloop()
关键改动说明:
- 将
movie改为实例属性:把movie= tk.StringVar()改成self.movie= tk.StringVar(),这样PageOne的所有方法都能通过self.movie访问这个变量。 - 把
save_info转为类方法:将全局的save_info移到PageOne类内部,作为实例方法,这样它就能通过self访问到self.movie。 - 修正按钮赋值方式:把按钮创建和
grid()布局分开写,比如先创建mybutton,再调用mybutton.grid(...),这样mybutton会保存按钮对象的引用,方便后续操作(如果需要的话)。 - 调整按钮的command参数:把
command=save_info改成command=self.save_info,让按钮点击时调用当前实例的save_info方法。
这样修改后,你的单选按钮值就能正常获取,不会再出现变量未定义的错误了。
内容的提问来源于stack exchange,提问作者startingover
相关产品推荐
相关产品推荐

