Python Forum

Full Version: Tkinter: Create an homepage look like
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I'd like to create for my GUI an homepage like look, I've manege to arrive at this point, but now I'm little stuck. What I'd like to achieve is change the bottom_box when clicking the button that link to Page One or Page Two. Thanks for your help!

import tkinter as tk

class MainApp(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent

        
        ###MENU FRAME
        left_frame = tk.Frame(root, borderwidth=1, bg= "white", relief="solid", highlightthickness=2)
        left_frame.pack(side="left", expand=False, fill="y")
        container = tk.Frame(left_frame, borderwidth=1, bg= "white", relief="solid")
        container.pack(expand=True, fill="both", padx=5, pady=5)
        btn_1 = tk.Button(container, text="Home")
        btn_1.pack(padx=20, pady=20)
        btn_2 = tk.Button(container, text="Page One")
        btn_2.pack(padx=20,pady=20)
        
        ###TOP
        right_frame = tk.Frame(root, borderwidth=1, bg= "white", relief="solid", highlightthickness=2)
        right_frame.pack(side="right", expand=True, fill="both")
        top_box = tk.Frame(right_frame, borderwidth=1, bg= "white", relief="solid")
        top_box.pack(expand=True, fill="both", padx=10, pady=10)
        label_top = tk.Label(top_box, text="Title Logo", bg= "white")
        label_top.pack()
        
        ###BOTTOM
        bottom_box = tk.Frame(right_frame, borderwidth=1, bg= "white", relief="solid")
        bottom_box.pack(expand=True, fill="both", padx=10, pady=10)

        
if __name__ == "__main__":
    root = tk.Tk()
    root.geometry("1200x650")
    MainApp(root).pack(side="top", fill="both", expand=True)
    root.mainloop()
Look at tkinter callback function
There is an example in the following link of switching frames
https://python-forum.io/Thread-Tkinter-switching-frames

And another
https://stackoverflow.com/questions/7546...in-tkinter
Thank you all! I've made some progress,my frame change but not the one I want: when I click my button the frame that change is the menu one and not the bottom one. How can I solve this? Also I've kinda made a copy and paste so I don't know if the structure of the code became really weird or something. Thank you again.
import tkinter as tk
from PageOne import PageOne
from PageTwo import PageTwo


class MainApp(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent

        
        ###MENU FRAME
        left_frame = tk.Frame(root, borderwidth=1, bg= "white", relief="solid", highlightthickness=2)
        left_frame.pack(side="left", expand=False, fill="y")
        container = tk.Frame(left_frame, borderwidth=1, bg= "white", relief="solid")
        container.pack(expand=True, fill="both", padx=5, pady=5)

        self.frames = {}
        for F in (StartPage, PageOne, PageTwo):
            page_name = F.__name__
            frame = F(parent=container, controller=self)
            self.frames[page_name] = frame

            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame("StartPage")

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

class StartPage(tk.Frame):

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

        button1 = tk.Button(self, text="Go to Page One",
                            command=lambda: controller.show_frame("PageOne"))

        button1.pack(padx=20, pady=20)

        button2 = tk.Button(self, text="Go to Page Two",
                            command=lambda: controller.show_frame("PageTwo"))

        button2.pack(padx=20, pady=20)
  
       
        ###TOP
        right_frame = tk.Frame(root, borderwidth=1, bg= "white", relief="solid", highlightthickness=2)
        right_frame.pack(side="right", expand=True, fill="both")
        top_box = tk.Frame(right_frame, borderwidth=1, bg= "white", relief="solid")
        top_box.pack(expand=True, fill="both", padx=10, pady=10)
        label_top = tk.Label(top_box, text="Title Logo", bg= "white")
        label_top.pack()
        
        ###BOTTOM
        bottom_box = tk.Frame(right_frame, borderwidth=1, bg= "white", relief="solid")
        bottom_box.pack(expand=True, fill="both", padx=10, pady=10)

        
if __name__ == "__main__":
    root = tk.Tk()
    root.geometry("1200x650")
    MainApp(root).pack(side="top", fill="both", expand=True)
    root.mainloop()
Page one:
import tkinter as tk                
from tkinter import font  as tkfont 


class PageOne(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        
        button_2 = tk.Button(self, text="Go to Start Page",
                           command=lambda: controller.show_frame("StartPage"))
        button_2.pack(padx=20, pady=20)

        button_3 = tk.Button(self, text="Go to Page Two",
                           command=lambda: controller.show_frame("PageTwo"))
        button_3.pack(padx=20, pady=20)



if __name__ == "__main__":
    app = SampleApp()
    app.mainloop()
Page two:
import tkinter as tk                
from tkinter import font  as tkfont 

class PageTwo(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        
        button_2 = tk.Button(self, text="Go to Start Page",
                           command=lambda: controller.show_frame("StartPage"))
        button_2.pack(padx=20, pady=20)

        button_3 = tk.Button(self, text="Go to Page One",
                           command=lambda: controller.show_frame("PageOne"))
        button_3.pack(padx=20, pady=20)



if __name__ == "__main__":
    app = SampleApp()
    app.mainloop()
You will need to set the parent frame to the bottom frame
(Jun-25-2020, 05:12 PM)menator01 Wrote: [ -> ]You will need to set the parent frame to the bottom frame

I've changed it like this:
        self.frames = {}
        for F in (StartPage, PageOne, PageTwo):
            page_name = F.__name__
            frame = F(parent=bottom_box, controller=self)
            self.frames[page_name] = frame

            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame("StartPage")
but it gives me back this error :
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files (x86)\Python38-32\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "C:/folder/01.py", line 17, in <lambda>
    button1 = tk.Button(container, text="Go to Page One", command=lambda: controller.show_frame("PageOne"))
NameError: name 'controller' is not defined
You will need to pass your bottom_frame to the page classes.

Here is an example from one of my projects. Not saying it's the best way but it worked for me.

class RootWindow:
    '''Docstring'''
    def __init__(self, master):
        self.master = master

        self.logo_frame() # Initialize the logo_frame function/method

        Child(self.logoframe) #  Give access for the logoframe parent to Child class
        # More code here ....

    def logo_frame(self):
        self.logoframe = ttk.Frame(self.master) # logoframe parent is root
        # More code here


class Child:
    def __init__(self, logoframe): # Pass logoframe to class
        self.my_logo(logoframe) # make sure my_logo function has access to logoframe
        # Other code here
    
    def my_logo(self, logoframe): # pass logoframe to function
        self.logo = ttk.Label(logoframe, image=imgfile) # logoframe now has parent in root window
        # More code here
Thank you a lot for your patience and help. I'm not understanding what to do with the code you posted very well, but thank you anyway. I'm kinda having hard time solving this on my own so I think I'll just give up and try to figure out another way to do my app so that I don't have to change page.
Thank you again and have a nice day!
If your wanting the buttons to change in the left frame this will do it.
Put this under the bottom_box statements. The buttons will change accordingly. The bottom frame works on the same principle.
PageOne(bottom_box,controller)
PageTwo(bottom_box, controller)
Never mind, my bad