Home > OS >  tkraise is not functioning
tkraise is not functioning

Time:01-18

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 call tkraise on.
  • I moved the call to grid onto self 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
  • Related