KrazylassPlayz
KrazylassPlayz

Reputation: 19

Why are my tkinter labels arranged by .pack() arranging themselves strangely and how do I fix it

Lately I've been having issues with the positioning of my tkinter labels, but just as I thought I was beginning to understand things the results I get from my tkinter window are strange and I don't understand it at all. This is what I got: enter image description here The aim was to have the two yellow boxes, or 'cards' under the labels 'Player 1's card' and 'Player 2's card' and have the blue 'card' under 'Deck'. Some explanation on why the 'cards' have been positioned this way, and how to fix and position them how I want, would be appreciated. I am aware it is awkward how I have used pack() and grid() together - grid() for the labels and pack() for the frames - however this was the easier way of arranging it so the titles were centralized.

This is the code that got me the resulting gui:

#game GUI goes here

maingame = tk.Tk()
maingame.title("Louise's Card Game")
maingame.geometry("600x350")
maingame['background']='#856ff8'
maingame.resizable(0, 0)


#Note to self - pack() and grid() should only be used seperately with one for frames and the other for
#the labels themselves. (This code exists to centalize the stuff in the frames)

#frame creation
titleframe = tk.Frame(maingame, background="White")
namesframe = tk.Frame(maingame)
cardsframe = tk.Frame(maingame)
cardsframeL = tk.Frame(cardsframe)
cardsframeM = tk.Frame(cardsframe)
cardsframeR = tk.Frame(cardsframe)

#frame packing
titleframe.pack()
namesframe.pack()
cardsframe.pack()
cardsframeL.pack(side=tk.LEFT)
cardsframeM.pack(side=tk.TOP)
cardsframeR.pack(side=tk.RIGHT)

#titleframe labels
gameturns = tk.Label(titleframe, text="{}'s Turn".format(currentTurn), font=("Courier", 10), padx=10, pady=10)
gametitle = tk.Label(titleframe, text="Louise's Card Game", font=("Courier", 15), padx=10, pady=10)
gamerounds = tk.Label(titleframe, text=("Round {}".format(currentRound)), font=("Courier", 10), padx=10, pady=10)

#namesframe labels
name1label = tk.Label(namesframe, text="Player 1's card", font=("Courier", 10), padx=50, pady=5)
maindecklabel = tk.Label(namesframe, text="Deck", font=("Courier", 10), padx=50, pady=5)
name2label = tk.Label(namesframe, text="Player 2's card", font=("Courier", 10), padx=50, pady=5)

#cardsframe labels
p1cardimage = tk.Label(cardsframeL, text="test", font=("Courier", 10), padx=25, pady=50)
deckcardimage = tk.Label(cardsframeM, text="test", font=("Courier", 10), padx=25, pady=50)
p2cardimage = tk.Label(cardsframeR, text="test", font=("Courier", 10), padx=25, pady=50)

#titleframe label colours
gameturns.config(bg="white")
gametitle.config(bg="white")
gamerounds.config(bg="white")

#namesframe label colours
name1label.config(bg="white")
maindecklabel.config(bg="white")
name2label.config(bg="white")

#cardsframe label colours
p1cardimage.config(bg="yellow")
deckcardimage.config(bg="blue")
p2cardimage.config(bg="yellow")

#titleframe label positionings
gameturns.grid(row=0, column=0)
gametitle.grid(row=0, column=1)
gamerounds.grid(row=0, column=2)

#namesframe label positionings
name1label.grid(row=1, column=0)
maindecklabel.grid(row=1, column=1)
name2label.grid(row=1, column=2)

#cardsframe label positionings
p1cardimage.grid(row=3, column=0)
deckcardimage.grid(row=3, column=1)
p2cardimage.grid(row=3, column=2)
    
maingame.mainloop()

Upvotes: 0

Views: 77

Answers (1)

Thingamabobs
Thingamabobs

Reputation: 8037

Mixing pack and grid in the same master together wont work, the math simply don't match. What you doing is correct, you use grid and pack separately.

If you want to have something in line to each other it makes sense to have them in the same master with same keyword arguments, except for columns and rows.

p1cardimage = tk.Label(namesframe, text="test", font=("Courier", 10), padx=25, pady=50) 
deckcardimage = tk.Label(namesframe, text="test", font=("Courier", 10), padx=25, pady=50) 
p2cardimage = tk.Label(namesframe, text="test", font=("Courier", 10), padx=25, pady=50)

Another mistake you seem to do is you are thinking the grid is globally in place. In fact a the geometry management is working for each master (Window/Frame) separately. So your code should look like this:

name1label.grid(row=0, column=0) 
maindecklabel.grid(row=0, column=1) 
name2label.grid(row=0, column=2)

p1cardimage.grid(row=1, column=0) 
deckcardimage.grid(row=1, column=1) 
p2cardimage.grid(row=1, column=2)

Keep in mind that window or frame is in the view of a geometry manager nothing more than a rectangle and if you skip a number in tkinter the geometry manager ignores the skipper and align your widgets right below/besides or above the next filled spot.

Last but not least, even widgets are rectangles for your geometry manager. Therefore mostly it dosent makes sense to have an extra frame for a single widget.

You may find this link interesting

Upvotes: 1

Related Questions