Posts: 13
Threads: 4
Joined: Apr 2020
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()
Posts: 1,145
Threads: 114
Joined: Sep 2019
Look at tkinter callback function
Posts: 2,168
Threads: 35
Joined: Sep 2016
Jun-24-2020, 10:44 PM
(This post was last modified: Jun-24-2020, 10:44 PM by Yoriz.)
Posts: 13
Threads: 4
Joined: Apr 2020
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()
Posts: 1,145
Threads: 114
Joined: Sep 2019
You will need to set the parent frame to the bottom frame
Posts: 13
Threads: 4
Joined: Apr 2020
Jun-25-2020, 06:14 PM
(This post was last modified: Jun-25-2020, 06:15 PM by PeroPuri.)
(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
Posts: 1,145
Threads: 114
Joined: Sep 2019
Jun-25-2020, 09:13 PM
(This post was last modified: Jun-25-2020, 09:27 PM by menator01.)
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
Posts: 13
Threads: 4
Joined: Apr 2020
Jun-26-2020, 12:21 AM
(This post was last modified: Jun-26-2020, 12:21 AM by PeroPuri.)
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!
Posts: 1,145
Threads: 114
Joined: Sep 2019
Jun-26-2020, 12:57 AM
(This post was last modified: Jun-26-2020, 01:07 AM by menator01.)
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
|