Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Updating TKinter frames with child classes

I’m currently making a GUI for a python program, and am using TKinter in an OOP fashion. I have a root class which creates a window and creates an array of all frames in the program, where each frame is a child class, and a method ‘show_frame’ which when called will update the window to show the frame passed as an argument. However I am having issues calling the show_frame method within methods of child classes, I was wondering if this is possible?

The root class:

from tkinter import *
from tkinter import ttk

class rootClass(Tk):
    def __init__(self): 
        
        Tk.__init__(self)
        
        window = Frame(self) 
        self.title("Application")
        window.pack(side="top", fill="both", expand=True) 
        window.grid_rowconfigure(0, weight = 1)
        window.grid_columnconfigure(0, weight = 1)
        self.frames = {} 

        pagesTuple = (firstPage, secondPage, thirdPage)
        for F in pagesTuple:
            frame = F(window, self)
            self.frames[F] = frame 
            frame.grid(row = 0, column = 0, sticky ="NSEW")

        self.show_frame(firstPage)

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

The first child class:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

class firstPage(Frame):

    def newPageMethod(self, controller, newPage):
                print("newPageMethod executed")
                controller.show_frame(newPage)
    def __init__(self, parent, controller): 
        super().__init__(parent)
        
        titleLabel = Label(self, text ="firstPage")
        titleLabel.grid(row = 0, column = 1, padx = 10, pady = 10) 

        loginButton = Button(self, text ="go to second page", command = self.newPageMethod(controller, secondPage))
        loginButton.grid(row = 1, column = 1, padx = 10, pady = 10)

Second child class:

class secondPage(Frame):

    def newPageMethod(self, controller, newPage):
                print("newPageMethod executed")
                controller.show_frame(newPage)
    def __init__(self, parent, controller): 
        super().__init__(parent)
        
        titleLabel = Label(self, text ="secondPage")
        titleLabel.grid(row = 0, column = 1, padx = 10, pady = 10) 

        loginButton = Button(self, text ="go to third page", command = self.newPageMethod(controller, thirdPage))
        loginButton.grid(row = 1, column = 1, padx = 10, pady = 10)

And so on. The error being returned is:

    frame = self.frames[cont]

KeyError: <class '__main__.firstPage'>

>Solution :

The error comes from:

loginButton = Button(self, text ="go to second page", command = self.newPageMethod(controller, secondPage))

When creating the button, instead of passing self.newPageMethod as argument to Button you are calling the function.

Then the show_frame function is called and it tries to get the value from cont key before the key is even assigned:

        for F in pagesTuple:
            frame = F(window, self) # calls 'show_frame' before assigning the key
            self.frames[F] = frame # assigning the key
            frame.grid(row = 0, column = 0, sticky ="NSEW")
    def show_frame(self, cont):
        frame = self.frames[cont] # ---> error here
        frame.tkraise()

That can be fixed using the lambda function:

        loginButton = Button(self, text ="go to second page", command = lambda: self.newPageMethod(controller, secondPage))

And also here:

        loginButton = Button(self, text ="go to third page", command = lambda: self.newPageMethod(controller, thirdPage))

And I am guessing that it should also be fixed in your other classes as well.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading