Tkinter Grid列权重设置失效,求井字棋布局解决方案
Fixing Grid Layout Issues in Your Tic Tac Toe Game
Hey there! Let's break down why your grid_columnconfigure isn't working and get those clickable frames properly laid out for your Tic Tac Toe game.
The Root Causes
- Canvas is covering your frames: You used
place(x=0,y=0)on the canvas, which makes it sit on top of all other widgets in the window. Your frames are there, but you can't see or interact with them because the canvas is blocking them. - Only one column has weight: You set
grid_columnconfigure(0, weight=1)but didn't apply this to columns 1 and 2—so the grid can't distribute space evenly across all three columns. - Fixed frame dimensions: You hardcoded
width=103andheight=83on your frames, which stops them from resizing with the grid cells. - Missing row weights: You didn't configure row weights at all, so rows won't resize vertically either.
Step-by-Step Fixes
Here's how to adjust your code to get the layout working as expected:
- Configure all grid rows and columns: Make sure every column and row in your 3x3 grid has equal weight so they expand with the window.
- Grid the canvas as a background: Instead of using
place, usegridto make the canvas fill the entire 3x3 grid area. - Remove fixed frame sizes: Let frames resize with their grid cells by using the
stickyattribute. - Fix image garbage collection: In your intro screen, save the photo images as attributes of the canvas to prevent them from disappearing.
Updated Code
from tkinter import * from tkinter import messagebox def intro(): global intro intro = Tk() intro.geometry("300x250+710+290") canvas = Canvas(intro, width=300, height=250) canvas.place(x=0, y=0) # Fix image garbage collection by storing images as canvas attributes canvas.filename = PhotoImage(file="rsz_2000px-tic_tac_toesvg.png") canvas.create_image(245, 210, image=canvas.filename) canvas.titlename = PhotoImage(file="rsz_1coollogo_com-141061778_1.png") canvas.create_image(150, 25, image=canvas.titlename) playb = Button(canvas, text="PLAY", command=game) exitb = Button(canvas, text="QUIT", command=quit) infolabel = Label(canvas, text="©moti de gever made this", fg="RED") playb.place(relx=0.5, rely=0.5, anchor=CENTER) exitb.place(relx=0.5, rely=0.61, anchor=CENTER) infolabel.place(relx=0.5, rely=0.95, anchor=CENTER) intro.mainloop() def quit(): if messagebox.askokcancel("exit?", "are you sure you want to exit?"): intro.destroy() def game(): intro.destroy() game_window = Tk() # Renamed from 'game' to avoid overwriting the function name game_window.geometry("300x250+710+290") # Configure all 3 columns and 3 rows to have equal weight for col in range(3): game_window.grid_columnconfigure(col, weight=1) for row in range(3): game_window.grid_rowconfigure(row, weight=1) canvas = Canvas(game_window, width=300, height=250) # Grid canvas to fill the entire 3x3 grid area canvas.grid(row=0, column=0, rowspan=3, columnspan=3, sticky="nsew") # Draw Tic Tac Toe lines canvas.create_line(105, 0, 105, 250, width=5) canvas.create_line(210, 0, 210, 250, width=5) canvas.create_line(0, 85, 300, 85, width=5) canvas.create_line(0, 170, 300, 170, width=5) # Create all 9 clickable frames (3x3 grid) frames = [] for row in range(3): row_frames = [] for col in range(3): frame = Frame(game_window, bg="") # Transparent background to show canvas lines frame.grid(row=row, column=col, sticky="nsew") # Sticky fills the entire cell frame.bind("<Button-1>", test) row_frames.append(frame) frames.append(row_frames) game_window.mainloop() def test(event): print("working! Clicked frame:", event.widget) intro()
Key Changes Explained
- Renamed
gamewindow togame_window: Avoids overwriting thegame()function name (a common bug). - Grid row/column configuration: Loops through all 3 rows and columns to set equal weight, ensuring the grid resizes evenly.
- Canvas grid layout: Using
sticky="nsew"makes the canvas fill the entire window, androwspan=3/columnspan=3lets it cover all grid cells. - Frame setup: Removed fixed dimensions, added
sticky="nsew"to make frames fill their grid cells, and set a transparent background so the canvas lines show through. - Image fix: Stored photo images as canvas attributes to prevent Python's garbage collector from deleting them (which makes images disappear).
Now your frames will be properly laid out, clickable, and resize with the window—perfect for building out your Tic Tac Toe game!
内容的提问来源于stack exchange,提问作者Moti Shakuri




