-1

When trying to create nested frames with grid layouts I get overlapping and uneven spacing.

The expected results is the TitleFrame is above the Boardframe and the squares on the BoardFrame are evenly spaced. (quick mockup done here in paint)

Expected result

The actual result is the board covers the title frame and the first column is spaced the same as the title.

Actual result

from tkinter import *

class Square(Button):
    def __init__(self, rank, file, bg="white", startingPiece = None) -> None:
        Button.__init__(self, master=None, text="T", bg=bg, borderwidth=2)
        self.Piece = startingPiece or None
        self.IsSelected = False
        self.rank = rank
        self.file = file

class Window(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.master = master

        self.CreateGrid()

    def CreateGrid(self):
    
        self.TitleFrame = Frame()
        self.BoardFrame = Frame()
        self.TitleFrame.grid(row=0,column=0, sticky='news')
        self.BoardFrame.grid(row=1,column=0, sticky='news')

        self.TitleFrame.Title = Label(text="Chess Bot Viewer")
        self.TitleFrame.Title.grid(row=0,column=0,sticky='news')

    
        self.BoardFrame.Squares = [[0 for x in range(8)] for y in range(8)] 
        doFillBG = True
        for x in range(8):
            doFillBG = not doFillBG
            for y in range(8):
                if doFillBG: bg = 'gray' 
                else: bg = 'white'
                self.BoardFrame.Squares[x][y] = Square(rank=x,file=y,bg=bg)
                self.BoardFrame.Squares[x][y].grid(row=x,column=y,sticky='news')
                print(self.BoardFrame.Squares[x][y].rank, self.BoardFrame.Squares[x][y].file)
                doFillBG = not doFillBG
root = Tk()
app = Window(root)
root.wm_title("Chess")
root.geometry("400x400")
root.mainloop()

The CreateGrid method is part of a subclass of Frame, and there are two member frames created in the method.

  • Are you aware of the `columnspan` option? – Bryan Oakley Feb 07 '23 at 21:49
  • @BryanOakley yes. Though I was under the impression that it just allows an item to take up more than one column or row. The intent is for the two frames to have independent grids nested within the parent grid of the main frame. – Adrian Edelen Feb 07 '23 at 22:59
  • 1
    You didn't specify the parent for the title and squares, so they are created as children of root window. – acw1668 Feb 07 '23 at 23:09
  • Your code is missing some objects, and doesn't produce the image in your question. Please [edit] your question to include a [mcve]. – Bryan Oakley Feb 08 '23 at 01:29
  • @BryanOakley I added requested code. it runs and produces the result shown in the 'actual result' image. – Adrian Edelen Feb 08 '23 at 13:40

1 Answers1

1

Since you didn't specify the parent/master for the title label and instances of Square, they will be created as children of root window. So the title label is put at row 0 and column 0 in the root window which causes the wider width of column 0 of the table of squares.

You need to specify the parent for those widgets as below:

from tkinter import *

class Square(Button):
    # added master argument
    def __init__(self, master, rank, file, bg="white", startingPiece=None) -> None:
        Button.__init__(self, master=master, text="T", bg=bg, borderwidth=2)
        self.Piece = startingPiece
        self.IsSelected = False
        self.rank = rank
        self.file = file

class Window(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        #self.master = master  # it is implicitly set

        self.CreateGrid()

    def CreateGrid(self):

        self.TitleFrame = Frame(self) # passed self as the parent
        self.BoardFrame = Frame(self) # passed self as the parent
        self.TitleFrame.grid(row=0, column=0, sticky='news')
        self.BoardFrame.grid(row=1, column=0, sticky='news')

        # passed self.TitleFrame as the parent
        self.TitleFrame.Title = Label(self.TitleFrame, text="Chess Bot Viewer")
        self.TitleFrame.Title.grid(row=0, column=0,sticky='news')

        self.BoardFrame.Squares = [[0 for x in range(8)] for y in range(8)]
        doFillBG = True
        for x in range(8):
            doFillBG = not doFillBG
            for y in range(8):
                if doFillBG: bg = 'gray'
                else: bg = 'white'
                # passed self.BoardFrame as the parent
                self.BoardFrame.Squares[x][y] = Square(self.BoardFrame, rank=x, file=y, bg=bg)
                self.BoardFrame.Squares[x][y].grid(row=x, column=y, sticky='news')
                print(self.BoardFrame.Squares[x][y].rank, self.BoardFrame.Squares[x][y].file)
                doFillBG = not doFillBG

root = Tk()
app = Window(root)
app.pack() # show the frame using pack()
root.wm_title("Chess")
root.geometry("400x400")
root.mainloop()

Result:

enter image description here

acw1668
  • 40,144
  • 5
  • 22
  • 34