why do frames overlap each other in tkinter?

Total
1
Shares

I found somewhere how you can navigate between pages in tkinter. Took this code, changed it a bit and now I have a problem with the grid. When I switch to the TablePage (where I tried to use the grid) it displays two labels overlap each other. I don’t quite understand why this is happening. When I programmed in WPF (C#) and worked with the grid, everything was great. But in tkinter this grid is very strange. All I want is to place two more frames in the parent frame at a 3:1 ratio. Well, the question itself – why do these two frames in the TablePage class overlap each other?

import tkinter as tk


class Page(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)

    def show(self):
        self.lift()


class TablePage(Page):
    def __init__(self, *args, **kwargs):
        Page.__init__(self, *args, **kwargs)
        # label = tk.Label(self, text="Table page")
        # label.pack(side="top", fill="both", expand=True)
        table_frame = tk.Frame(self, bg="red")
        table_frame.grid(row=0, column=0, columnspan=3)
        buttons_frame = tk.Frame(self, bg="blue")
        buttons_frame.grid(row=0, column=1, columnspan=1)
        label = tk.Label(table_frame, text="Left side")
        label.pack(side="top", fill="both", expand=True)
        label2 = tk.Label(buttons_frame, text="Right side")
        label2.pack(side="top", fill="both", expand=True)


class MainPage(Page):
    def __init__(self, *args, **kwargs):
        Page.__init__(self, *args, **kwargs)
        label = tk.Label(self, text="Main page")
        label.pack(side="top", fill="both", expand=True)


class SettingsPage(Page):
    def __init__(self, *args, **kwargs):
        Page.__init__(self, *args, **kwargs)
        label = tk.Label(self, text="Settings page")
        label.pack(side="top", fill="both", expand=True)


class MainView(tk.Frame):
    def __init__(self, *args, **kwargs):
        tk.Frame.__init__(self, *args, **kwargs)
        p1 = MainPage(self)
        p2 = TablePage(self)
        p3 = SettingsPage(self)

        buttonframe = tk.Frame(self)
        container = tk.Frame(self)
        buttonframe.pack(side="top", fill="x", expand=False)
        container.pack(side="top", fill="both", expand=True)

        p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
        p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
        p3.place(in_=container, x=0, y=0, relwidth=1, relheight=1)

        b1 = tk.Button(buttonframe, text="Page 1", command=p1.lift)
        b2 = tk.Button(buttonframe, text="Page 2", command=p2.lift)
        b3 = tk.Button(buttonframe, text="Page 3", command=p3.lift)

        b1.pack(side="left")
        b2.pack(side="left")
        b3.pack(side="left")

        p1.show()


if __name__ == "__main__":
    root = tk.Tk()
    main = MainView(root)
    main.pack(side="top", fill="both", expand=True)
    root.wm_geometry("900x600")
    root.configure(bg='green')
    root.mainloop()

Solution

It is because you have used columnspan=3 for table_frame, so table_frame will be across 3 columns, 0 to 2. Then you put buttons_frame in column 1 and it will overlap table_frame.

Either remove columnspan=3 or put buttons_frame in column 3.


Edit: you need to use .columnconfigure() to set the weight option to achieve 3:1 (round) layout:

class TablePage(Page):
    def __init__(self, *args, **kwargs):
        Page.__init__(self, *args, **kwargs)
        self.columnconfigure(0, weight=3)
        self.columnconfigure(1, weight=1)
        table_frame = tk.Frame(self, bg="red")
        table_frame.grid(row=0, column=0, sticky="ew")
        buttons_frame = tk.Frame(self, bg="blue")
        buttons_frame.grid(row=0, column=1, sticky="ew")
        label = tk.Label(table_frame, text="Left side", bg="red")
        label.pack(side="top", fill="both", expand=True)
        label2 = tk.Label(buttons_frame, text="Right side", bg="blue")
        label2.pack(side="top", fill="both", expand=True)
Leave a Reply

Your email address will not be published. Required fields are marked *