Ashmoreinc
Ashmoreinc

Reputation: 122

Changing a tkinter frame from inside a method/function other than __init__

What im trying to do is find a way to change the Frame from a method/function other than def __init__

My main class which im using to change and manage the Frames with is:

class ShopCounter(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 i in (PageOne, PageTwo):
            frame = i(container, self)
            self.frames[i] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.showFrame(Login)

    def showFrame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()

The issue im having from here is that when i make a new window such as

class PageOne (tk.Frame):
    def __init__ (self, parent, controller):
        tk.Frame.__init__(self, parent)
        lbl = tk.Label(self, text="Page 1")
        lbl.pack()

This is also in __init__ as this calls the nextPage function (Later shown) nextPage()

But i need to read from a CSV spread sheet to check if the person has inputted the user name and pass word (Haven't put checking code or input fields for convenience) i then find that i need to change the frame from a different function in the class PageOne

I have then met the problem of now having to define a controller in this new function s through the parenthesis of the function when it is called which is a problem because i don't know how to do that apart from just putting it as a parameter in the __init__method

Quick example:

Say the function in the class is something like this..

def nextPage (self, controller):
    controller.showFrame(PageTwo)

IDLE then tells me that i the arguments for this function "controller" is missing but i don't know how I'd set that manually

Upvotes: 2

Views: 2544

Answers (1)

Ashmoreinc
Ashmoreinc

Reputation: 122

I have found a fix

class PageOne (tk.Frame):
    def __init__ (self, parent, controller):
        tk.Frame.__init__(self, parent)
        lbl = tk.Label(self, text="Page 1")
        lbl.pack()

        button = tk.Button(self, text="switch", command=lambda: self.launch(controller)
        button.pack()

    def launch (self, cont):
        cont.showFrame(PageTwo)

Now I've made a function (launch) in the PageOne class which takes self and cont (the controller) as the parameters. You will then pass the controller from init into the launch function when you press the button.

Hope this helps some on. 'Cause personally I've been stumped on this one for months.

UPDATE

After months of this answer being up, i have now found a new way, rather than always passing the controller as a parameter to each function you with to use in each page class, in the initiation of the class (__ init __), you can declare a variable to the object that holds the controller, heres an example:

class PageTwo(tk.Frame):
    def __init__ (self, parent, controller):
        self.controller = controller

    def doSomething (self):
        self.controller.doSomething()

by referencing the controller you can run any class within the controller class, you can also get variable data and change it.

Upvotes: 1

Related Questions