从函数调用Tkinter框架控制器而非按钮命令
我有以下代码,它运行得很好:
import tkinter as tk
class App(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (LoginPage, ProjPage):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, rowspan=12, columnspan=6, sticky="nsew")
self.show_frame(LoginPage)
def show_frame(self, c):
frame = self.frames[c]
frame.tkraise()
class LoginPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
Btn = tk.Button(self, text="Sign In", command=lambda: controller.show_frame(ProjPage))
但是我想把最后一个按钮的命令放到一个单独的函数里,这样我可以先做一些判断:
Btn = tk.Button(self, text="Sign In", command=self.signIn)
def signIn(self):
# do some stuff here
self.controller.show_frame(ProjPage)
可是这样不行;无论我尝试传递控制器,还是用一个lambda表达式,似乎都不管用。到底是哪里出了问题呢?
2 个回答
我的程序有一个主页面,上面有5个单选按钮和一个“确定”按钮,还有5个其他的页面。我希望在点击“确定”按钮后,根据选择的单选按钮,程序能跳转到相应的页面。
当点击“确定”按钮时,它会调用一个小函数,获取选中的单选按钮的值,然后根据这个值找到一个字符串(veg),这个字符串代表页面的名称。
以下是代码:
首先,我们导入需要的库:
import tkinter as tk
from tkinter import ttk
from win32print import StartPage
接下来,我们定义一个应用程序类 KBSapp,它是从 tkinter 的 Tk 类继承而来的:
class KBSapp(tk.Tk):
def init(self, *args, **kwargs):
tk.Tk.init(self, *args, **kwargs)
tk.Tk.iconbitmap(self,default="icon.ico")
tk.Tk.wm_title(self, "蔬菜作物的病虫害")
container = tk.Frame(self, width=200, height=200, bg='black')
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage,carrot,celery, potato, wheat, bean):
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( )
然后,我们定义一个 StartPage 类,它也是从 tk.Frame 继承的:
class StartPage(tk.Frame):
def init(self, parent, controller):
tk.Frame.init(self, parent)
label = tk.Label(self, width=0, height=20)
label.pack()
button2 = ttk.Button(self, command=lambda : okclick(v) ,text='OK', width=25)
button2.pack( )
v = tk.IntVar( )
self.option1 = ttk.Radiobutton(self, text="Carrot", variable=v, value=1);self.option1.pack( )
self.option2 = ttk.Radiobutton(self, text="Celery", variable=v, value=2);self.option2.pack( )
self.option3 = ttk.Radiobutton(self, text="potato", variable=v, value=3);self.option3.pack( )
self.option4 = ttk.Radiobutton(self, text="wheat", variable=v, value=4);self.option4.pack( )
self.option5 = ttk.Radiobutton(self, text="bean", variable=v, value=5);self.option5.pack( )
v.set(1) # initializing the choice
接下来是处理“确定”按钮点击事件的函数 okclick(v):
def okclick(v):
global veg
input1=v.get( )
if input1==1:
veg="胡萝卜"
if input1==2:
veg='芹菜'
if input1==3:
veg='土豆'
if input1==4:
veg='小麦'
if input1==5:
veg='豆子'
print(veg)
然后我们定义了几个页面类,每个类代表一个不同的页面:
class carrot(tk.Frame):
def init(self, parent, controller):
tk.Frame.init(self, parent)
label = tk.Label(self, width=0, height=20)
label.pack( )
button3 = ttk.Button(self, command=lambda : controller.show_frame(celery) , text='芹菜', width=25)
button3.pack( )
class celery(tk.Frame):
def init(self, parent, controller):
tk.Frame.init(self, parent)
label = tk.Label(self, width=0, height=20)
label.pack( )
button4 = ttk.Button(self, command=lambda : controller.show_frame(potato) , text='土豆', width=25)
button4.pack( )
class potato(tk.Frame):
def init(self, parent, controller):
tk.Frame.init(self, parent)
label = tk.Label(self, width=0, height=20)
label.pack( )
button4 = ttk.Button(self, command=lambda : controller.show_frame(wheat) , text='小麦', width=25)
button4.pack( )
class wheat(tk.Frame):
def init(self, parent, controller):
tk.Frame.init(self, parent)
label = tk.Label(self, width=0, height=20)
label.pack( )
button4 = ttk.Button(self, command=lambda : controller.show_frame(bean) , text='豆子', width=25)
button4.pack( )
class bean(tk.Frame):
def init(self, parent, controller):
tk.Frame.init(self, parent)
label = tk.Label(self, width=0, height=20)
label.pack( )
button4 = ttk.Button(self, command=lambda : controller.show_frame(StartPage) , text='开始页面', width=25)
button4.pack( )
最后,我们创建应用程序的实例并运行它:
app = KBSapp( )
app.mainloop( )
你似乎没有在 self
中初始化 controller
。可以在 LoginPage
的 __init__
方法里加上它,像这样:
self.controller = controller