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)
The actual result is the board covers the title frame and the first column is spaced the same as the title.
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.
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: