I am trying to create two buttons to switch frame config by raising different Frame above an other. but the tkraise() function doesn't seems working... Please help to check if there are any mistake or concept error of using tkraise.
Thanks for helping
import tkinter as tk
from tkinter import ttk
SUNKABLE_BUTTON = 'SunkableButton.TButton'
class tkinterApp(tk.Tk):
# __init__ function for class tkinterApp
def __init__(self, *args, **kwargs):
# __init__ function for class Tk
tk.Tk.__init__(self, *args, **kwargs)
# initializing frames to an empty array
self.frames = {}
top_container = tk.LabelFrame(self, width=400, height=100, text="item")
top_container.grid(row = 0, column=0, columnspan=2)
mid_container_l = tk.LabelFrame(self, width=200, height=100, text="item_a")
mid_container_l.grid(row = 1, column=0)
mid_container_r = tk.LabelFrame(self, width=200, height=100, text="item_b")
mid_container_r.grid(row = 1, column=1)
but_container = tk.LabelFrame(self, width=400, height=400, text="item")
but_container.grid(row = 2, column=0, columnspan=2, sticky=tk.W)
for F in (One,Two):
frame = F(self)
self.frames[F] = frame
btn_1 = tk.Button(but_container, text="btn_1", command=lambda : self.show_frame(One))
btn_1.pack(side=tk.LEFT)
btn_2 = tk.Button(but_container, text="btn_2", command=lambda : self.show_frame(Two))
btn_2.pack(side=tk.LEFT)
#self.show_frame(One)
def show_frame(self, cont):
frame = self.frames[cont]
print(frame)
frame.tkraise(aboveThis=None)
class One(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
but_container_in = tk.Frame(parent, width=400, height=200, bg="yellow")
but_container_in.grid(row = 3, column=0, columnspan=2, sticky=tk.W)
class Two(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
but_container_in_l = tk.Frame(parent, width=400, height=200, bg="green")
but_container_in_l.grid(row = 3, column=0, columnspan=2, sticky=tk.W)
#but_container_in_r = tk.Frame(parent, width=200, height=200, bg="red")
#but_container_in_r.grid(row = 3, column=1, columnspan=2, sticky=tk.W)
# Driver Code
app = tkinterApp()
app.mainloop()
I am expecting someone can point out mine blind spot
CodePudding user response:
tkraise
is working. The problem is that you're raising frames that aren't visible on the screen so there's no visual indication that it's working.
The problem is in the definition of your classes One
and Two
. These classes make two frames: the instance of the class itself, and then an inner frame. Both are children of parent
, but only the inner frame is added to the window (in this case, with grid
).
I don't understand why you're creating an inner frame inside a class that is itself a frame. At the very least, those inner frames should be children of the class rather than children of the parent.
When you make the inner frames children of self
, and you call grid
on the instance of the class, your code works.
class One(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.grid(row = 3, column=0, columnspan=2, sticky=tk.W)
but_container_in = tk.Frame(self, width=400, height=200, bg="yellow")
but_container_in.pack(fill="both", expand=True)
class Two(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.grid(row = 3, column=0, columnspan=2, sticky=tk.W)
but_container_in_l = tk.Frame(self, width=400, height=200, bg="green")
but_container_in_l.pack(fill="both", expand=True)
Things to notice:
- the inner frames are now children of
self
, since the instance of those classes are themselves frames, and the instances of the classes are the ones you need to calltkraise
on. - I moved the call to
grid
ontoself
rather than onto the inner frame. - I added a call to
pack
on the inner frame since that's the simplest way to get a frame to fill its parent