EDIT: for first version probably you could use PannedWindow
I wasn't sure which version you need

or

First version uses pack()
, pack_forget()
to add and remove bottom frame below main frame.
import tkinter as tk
root = tk.Tk()
# - main frame -
f1 = tk.Frame(root, width=800, height=600, bg='green')
f1.pack_propagate(False) # dont change size
f1.pack() # visible
label1 = tk.Label(f1, text='800x600')
label1.place(relx=0.5, rely=0.5, anchor='c')
button1 = tk.Button(f1, text="Show")
button1.place(relx=1, rely=1, anchor='se')
# - bottom frame -
f2 = tk.Frame(root, width=800, height=230, bg='red')
f2.pack_propagate(False) # dont change size
#f2.pack() # hidden
label2 = tk.Label(f2, text='800x230')
label2.place(relx=0.5, rely=0.5, anchor='c')
button2 = tk.Button(f2, text="Close", command=f2.pack_forget) # function to hide
button2.place(relx=1, rely=1, anchor='se')
# - assign function from bottom-frame to button in main-frame
button1['command'] = f2.pack # function to show
root.mainloop()
Second method use place()
to put bottom frame on top of main frame. It uses place_forget()
to remove it.
import tkinter as tk
# --- main ---
root = tk.Tk()
root.geometry('800x600')
# - main frame -
f1 = tk.Frame(root, width=800, height=600, bg='green')
f1.place(x=0, y=0) # visible
label1 = tk.Label(f1, text='800x600')
label1.place(relx=0.5, rely=0.5, anchor='c')
button1 = tk.Button(f1, text="Show") #, command=lambda:f2.place(x=800, y=600, anchor='se'))
button1.place(relx=1, rely=1, anchor='se')
# - bottom frame -
f2 = tk.Frame(root, width=800, height=230, bg='red')
#f2.place(x=800, y=600, anchor='se') # hidden
label2 = tk.Label(f2, text='800x230')
label2.place(relx=0.5, rely=0.5, anchor='c')
button2 = tk.Button(f2, text="Close", command=f2.place_forget)
button2.place(relx=1, rely=1, anchor='se')
# - assign function from bottom-frame to button in main-frame
button1['command'] = lambda:f2.place(x=800, y=600, anchor='se')
root.mainloop()
Inside frames I use place()
but you can use pack()
or grid()
EDIT: for second version I made code with classes - and I can show bottom frame and top frame on top of main frame.
import tkinter as tk
class MainFrame(tk.Frame):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self['bg'] = 'green'
self['width'] = 800
self['height'] = 600
self.label = tk.Label(self, text='800x600')
self.label.place(relx=0.5, rely=0.5, anchor='c')
self.button1 = tk.Button(self, text="Show")
self.button1.place(relx=1, rely=1, anchor='se')
self.button2 = tk.Button(self, text="Show")
self.button2.place(relx=1, rely=0, anchor='ne')
def show(self):
self.place(x=0, y=0, anchor='nw')
#def hide(self):
# self.place_forget()
class BottomFrame(tk.Frame):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self['bg'] = 'red'
self['width'] = 800
self['height'] = 230
self.label = tk.Label(self, text='800x230')
self.label.place(relx=0.5, rely=0.5, anchor='c')
self.button = tk.Button(self, text="Hide", command=self.hide)
self.button.place(relx=1, rely=1, anchor='se')
def show(self):
self.place(relx=0, rely=1, anchor='sw')
def hide(self):
self.place_forget()
class TopFrame(tk.Frame):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self['bg'] = 'blue'
self['width'] = 800
self['height'] = 230
self.label = tk.Label(self, text='800x230')
self.label.place(relx=0.5, rely=0.5, anchor='c')
self.button = tk.Button(self, text="Hide", command=self.hide)
self.button.place(relx=1, rely=0, anchor='ne')
def show(self):
self.place(relx=0, rely=0, anchor='nw')
def hide(self):
self.place_forget()
# --- main ---
root = tk.Tk()
root.geometry('800x600')
f1 = MainFrame()
f1.show()
f2 = BottomFrame()
#f2.show() # hiddem
f3 = TopFrame()
#f3.show() # hiddem
f1.button1['command'] = f2.show
f1.button2['command'] = f3.show
root.mainloop()