如何使Tkinter Notebook及其组件支持大小调整?(OOP新手求助)
Fixing Tkinter Notebook Resizing with OOP
Hey there! No worries at all—resizing widgets properly in Tkinter with OOP just requires making sure every level of your widget hierarchy has the right grid configuration. Let's break this down step by step and fix your code.
The Core Issues in Your Current Code:
- You aren't setting
grid_rowconfigure/grid_columnconfigurefor most containers (main window, notebook tabs, inner frames), so Tkinter doesn't know which rows/columns should stretch. - Some widgets don't have
sticky=NSEWset, so they won't fill the space their container gives them. - When you do
self.benjamin = ttk.Button(...).grid(...), you're assigningNonetoself.benjamin(sincegrid()returnsNone)—always create the widget first, then callgrid()separately if you need to reference the widget later.
Fixed Code with Explanations:
from tkinter import * from tkinter import ttk class Files(ttk.Frame): def __init__(self, master=None): ttk.Frame.__init__(self, master) # Configure this frame's grid: let column 0 stretch, row 1 stretch (for the Listbox) self.grid_rowconfigure(1, weight=1) self.grid_columnconfigure(0, weight=1) self.grid(sticky=NSEW) # Make this frame fill its parent container self.createWidgets() def createWidgets(self): # Create button first, then grid it (so self.benjamin actually references the button) self.benjamin = ttk.Button(self, text="Benjamin") self.benjamin.grid(row=0, column=0, sticky=NSEW) self.box = Listbox(self) # Make Listbox fill the entire row 1, column 0, and stretch with the frame self.box.grid(row=1, column=0, columnspan=4, sticky=NSEW) class Results(ttk.Frame): def __init__(self, master=None): ttk.Frame.__init__(self, master) # Configure this frame's grid: row 0 (Treeview) stretches, column 0 stretches self.grid_rowconfigure(0, weight=1) self.grid_columnconfigure(0, weight=1) self.grid(sticky=NSEW) # Fill parent container self.create_widgets() def create_widgets(self): self.columns = ("0", "1", "2", "3") self.chart = ttk.Treeview(self, columns=self.columns, show="headings") # Make Treeview fill row 0, column 0 and stretch self.chart.grid(row=0, column=0, columnspan=3, sticky=NSEW) self.button = ttk.Button(self, text="Also Benjamin") # Button stays aligned to the right, doesn't stretch self.button.grid(row=1, column=2, sticky=E) class App(Tk): def __init__(self): super().__init__() self.title("Resizable Notebook Demo") # Configure main window's grid: let row 0 and column 0 stretch self.grid_rowconfigure(0, weight=1) self.grid_columnconfigure(0, weight=1) self.notebook = ttk.Notebook(master=self) # Make notebook fill the entire main window and stretch with it self.notebook.grid(row=0, column=0, sticky=NSEW) self.frame1 = ttk.Frame(master=self.notebook) # Configure tab frame 1: let row 0 and column 0 stretch (for Files widget) self.frame1.grid_rowconfigure(0, weight=1) self.frame1.grid_columnconfigure(0, weight=1) self.notebook.add(self.frame1, text="TAB1") self.frame2 = ttk.Frame(master=self.notebook) # Configure tab frame 2: let row 0 and column 0 stretch (for Results widget) self.frame2.grid_rowconfigure(0, weight=1) self.frame2.grid_columnconfigure(0, weight=1) self.notebook.add(self.frame2, text="TAB2") self.choose_files = Files(master=self.frame1) # Files widget fills frame1 self.choose_files.grid(row=0, column=0, sticky=NSEW) self.show_results = Results(master=self.frame2) # Results widget fills frame2 self.show_results.grid(row=0, column=0, sticky=NSEW) self.mainloop() if __name__ == '__main__': App()
Key Takeaways for Resizing:
- Every container matters: For every window, Frame, or notebook tab, use
grid_rowconfigure(row_index, weight=1)andgrid_columnconfigure(col_index, weight=1)to tell Tkinter which rows/columns should expand when the container resizes. (Weight 1 means it takes all available extra space; higher weights get more space relative to others.) - Stick widgets to their container: Add
sticky=NSEWtogrid()calls for widgets you want to fill their allocated space. - Separate widget creation and grid placement: Never assign the result of
grid()to a widget variable—create the widget first, then callgrid()on it.
内容的提问来源于stack exchange,提问作者Xen
相关产品推荐
相关产品推荐

