Calling Tkinter frame controller from function rather then button command

允我心安 提交于 2021-02-08 06:07:36

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!