问题
So I have the following, which works perfectly:
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))
But I want that last button command to be in a separate function, so I can do some evaluations first:
Btn = tk.Button(self, text="Sign In", command=self.signIn)
def signIn(self):
# do some stuff here
self.controller.show_frame(ProjPage)
This doesn't work; regardless if I try to pass the controller, or use a lambda, nothing seems to work >.< What am I not getting?
回答1:
You don't seem to initialize controller
in self
. Put it there in __init__
of LoginPage
, like so:
self.controller = controller
回答2:
my program has a page(main page) that has 5 radio button in it and a button "ok",and I have 5 other Frame. I want my program to go to these frames after clicking the "ok" ( based on the chosen radio button).
when the "ok" is clicked it will call a lambda and get the value of chosen radiobutton and based on this valuefind the string (veg) which represent the name of the page.
here is the code:
import tkinter as tk from tkinter import ttk from win32print import StartPage
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, "Diseases and pests of vegetable crops") 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( )
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
def okclick(v): global veg input1=v.get( ) if input1==1: veg="carrot" if input1==2: veg='celery' if input1==3: veg='potato' if input1==4: veg='wheat' if input1==5: veg='bean' 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='celery', 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='potato', 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='wheat', 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='bean', 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='StartPage', width=25) button4.pack( )
app = KBSapp( ) app.mainloop( )
来源:https://stackoverflow.com/questions/15235794/calling-tkinter-frame-controller-from-function-rather-then-button-command