Search code examples
pythontkinterlayoutframes

padx values seem to affect the arrangement of tkinter Frames


So have a look at the below image. tk Window

On this window I have 3 Frames which are actually inherited from tk.Frame (i don't think that makes a difference here).

The first frame is at the up top which has 3 Buttons and 1 more will be added in the later parts of the program.Second Frame consists of those 9 buttons in a 3x3 layout. and 3rd frame has a label (i actually want two labels down there, one to the left and one to the right.)

What I want to achieve is keep the first frame as is, the 3x3 layout in the second frame need to be in the center (horizontally at least), and the labels in third frames, one to be at the left most and other one (haven't added it yet) to absolute right.

I have observed that whenever I change the padx (and even ipadx) values for any button in first frame, it seems to change the position of that 3x3 layout. Like when I increase padx for Stats Button, it slides both the 3x3 layout and bottom most label to the right. Which i feel like is weird because padding of something in a whole different frame altogether should not affect the layout of any other frame.

Here is the MCVE for the issue:

import tkinter as tk

class MenuBar(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)


class StBar(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)


class MidSpace(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)


class MainApp:
    def __init__(self, root):
        self.root = root
        self.StBar = StBar(self.root)
        self.MenuBar = MenuBar(self.root)
        self.MidSpace = MidSpace(self.root)

        self.root.grid_rowconfigure(0, weight=3)
        self.root.grid_rowconfigure(1, weight=55)
        self.root.grid_rowconfigure(2, weight=2)

        self.MenuBar.grid(row=0, column=0)
        self.MidSpace.grid(row=1, column=0)
        self.StBar.grid(row=2, column=0)

        self.htpb = tk.Button(self.MenuBar, text='How To Play', width=14,
                          bg='#00f', fg='#fff')
        self.htpb.grid(row=0, column=0, padx=10, ipady=5, sticky=tk.N + tk.S)

        self.statb = tk.Button(self.MenuBar, text='Stats', width=14,
                           bg='#00f', fg='#fff')
        self.statb.grid(row=0, column=1, padx=10, ipady=5, sticky=tk.N + tk.S)

        self.resb = tk.Button(self.MenuBar, text='Results', width=14,
                          bg='#00f', fg='#fff')
        self.resb.grid(row=0, column=2, padx=10, ipady=5, sticky=tk.N + tk.S)

        self.stLabel = tk.Label(self.StBar,
                            text='Some single line text here', bg='#00f',
                            fg='#fff', font=('roboto', 13))
        self.stLabel.pack(anchor=tk.W)

        self.b1 = tk.Button(self.MidSpace, text='  ',
                        bg='#da5', fg='#250038',
                        font=('roboto', 20), width=2, height=1)
        self.b2 = tk.Button(self.MidSpace, text='  ',
                        bg='#745', fg='#380601',
                        font=('roboto', 20), width=2, height=1)
        self.b3 = tk.Button(self.MidSpace, text='  ',
                        bg='#da5', fg='#250038',
                        font=('roboto', 20), width=2, height=1)
        self.b4 = tk.Button(self.MidSpace, text='  ',
                        bg='#745', fg='#380601',
                        font=('roboto', 20), width=2, height=1)
        self.b5 = tk.Button(self.MidSpace, text='  ',
                        bg='#da5', fg='#250038',
                        font=('roboto', 20), width=2, height=1)
        self.b6 = tk.Button(self.MidSpace, text='  ',
                        bg='#745', fg='#380601',
                        font=('roboto', 20), width=2, height=1)
        self.b7 = tk.Button(self.MidSpace, text='  ',
                        bg='#da5', fg='#250038',
                        font=('roboto', 20), width=2, height=1)
        self.b8 = tk.Button(self.MidSpace, text='  ',
                        bg='#745', fg='#380601',
                        font=('roboto', 20), width=2, height=1)
        self.b9 = tk.Button(self.MidSpace, text='  ',
                        bg='#da5', fg='#250038',
                        font=('roboto', 20), width=2, height=1)

        self.b1.grid(row=0, column=0, ipadx=40, ipady=40)
        self.b2.grid(row=0, column=1, ipadx=40, ipady=40)
        self.b3.grid(row=0, column=2, ipadx=40, ipady=40)
        self.b4.grid(row=1, column=0, ipadx=40, ipady=40)
        self.b5.grid(row=1, column=1, ipadx=40, ipady=40)
        self.b6.grid(row=1, column=2, ipadx=40, ipady=40)
        self.b7.grid(row=2, column=0, ipadx=40, ipady=40)
        self.b8.grid(row=2, column=1, ipadx=40, ipady=40)
        self.b9.grid(row=2, column=2, ipadx=40, ipady=40)

if __name__ == '__main__':
    win = tk.Tk()
    win.geometry('1360x710')
    win.title('TicTacToe - pssolanki')
    win.wm_geometry("+0+0")
    win.configure(bg='#fff')
    MainApp(win)
    win.mainloop()
    

If ya need to know anything else either let me know or check the code at Github Repository

Any help or suggestion is appreciated. You can also suggest a better title for the question 'cause I couldn't think of anything better.

Thank YOU :)


Solution

  • The reason is that all three frames are in a single column. Since a column has uniform width in a grid, if you make the top frame wider it makes the whole column wider, and that affects how the second and third frame appear.

    My advice would be to use pack for the three top-level frames. I would pack MenuBar along the top, StBar along the bottom, and then MidSpace in the middle.