pythontkintertk-toolkittkinter-layout

Switching between Class Frames Tkinter


Main/Parent Class


class tkinterApp(tk.Tk): #Root Window
    def __init__(self):
        #main set up
        super().__init__()
        self.geometry("700x700")
        self.title('Wuiz')

        #widgets
        #Trying to switch between "frames", have to comment out so they all arent on one window
        #self.Homepage = Homepage(self) 
        self.Weatherpage = Weatherpage(self)
        



        self.mainloop()


This Being the main class followed by Frame classes:

WeatherPage Frame/Class -> Holding widget elements, labels, buttons, etc.. then packing it to the main root window

class Weatherpage(tk.Frame):
    def __init__(self, parent):
        super().__init__(parent)

        # Back Button at corner => to homepage

        backbutton = Button(self, text="Back", fg="black", font=("Helvetica", 10), width=30)

        ....etc ...

        self.pack(expand=True, fill="both") # Problem probably here 

Then the info class/frame -> Again Holding widget elements, labels, buttons, etc.. then packing it to the main root window

class Infopage(tk.Frame):
    def __init__(self, parent):
        super().__init__(parent)
   
        backbutton = Button(self, text="Back", fg="black", font=("Helvetica", 10),
                            width=30)  # Back button does nothing
        backbutton.pack(side=TOP, anchor=NW)
        ..... etc...
        self.pack(expand=True, fill="both") # Problem probably here 

if __name__ == '__main__':
    tkinterApp()

Do you guys know any methods or soultions/ways to switch frames based of this? I think it might be how I am packing the classes to the root window, I probably need to switch it off and on somehow.


Solution

  • Create a method to switch pages, and remove the self.pack call in each of the page classes. The main app should be responsible for adding and removing the page in the root window.

    Then it's just a matter of tracking the current page, and when switching it remove it and pack the new page. It might look something like this:

    class tkinterApp(tk.Tk): #Root Window
        def __init__(self):
            ...
            self.current_page = None
            ...
            self.Homepage = Homepage(self) 
            self.Weatherpage = Weatherpage(self)
            ...
            self.switch_page(self.HomePage)
    
        def switch_page(self, new_page):
            if self.current_page is not None:
                self.current_page.pack_forget()
            self.current_page = new_page
            self.current_page.pack(fill="both", expand=True)
    

    A variation would be to not create the pages initially, and instead pass in the classname of the new page. switch_page can then destroy the old page, create the new, and pack it:

        def switch_page(self, new_page_cls):
            if self.current_page is not None:
                self.current_page.destroy()
            self.current_page = new_page_cls(self)
            self.current_page.pack(fill="both", expand=True)