慕姐4208626
问题是滚动框架容器Frame没有Canvas水平填充。我不会费心修复一些复制/粘贴(例如滚动框架)并解释它,而是只给您我的滚动框架。它比您正在使用的要强大得多,而且您遇到的问题并不存在。我已经将其插入到下面的脚本版本中。在我的方法中找到了滚动框架问题的解决方案on_canvas_configure。它只是告诉容器框架在画布事件上与画布宽度相同<Configure>。import tkinter as tk, tkinter.ttk as ttkfrom typing import Iterable class ScrollFrame(tk.Frame): def __init__(self, master, scrollspeed=5, r=0, c=0, rspan=1, cspan=1, grid={}, **kwargs): tk.Frame.__init__(self, master, **{'width':400, 'height':300, **kwargs}) #__GRID self.grid(**{'row':r, 'column':c, 'rowspan':rspan, 'columnspan':cspan, 'sticky':'nswe', **grid}) #allow user to set width and/or height if {'width', 'height'} & {*kwargs}: self.grid_propagate(0) #give this widget weight on the master grid self.master.grid_rowconfigure(r, weight=1) self.master.grid_columnconfigure(c, weight=1) #give self.frame weight on this grid self.grid_rowconfigure(0, weight=1) self.grid_columnconfigure(0, weight=1) #_WIDGETS self.canvas = tk.Canvas(self, bd=0, bg=self['bg'], highlightthickness=0, yscrollincrement=scrollspeed) self.canvas.grid(row=0, column=0, sticky='nswe') self.frame = tk.Frame(self.canvas, **kwargs) self.frame_id = self.canvas.create_window((0, 0), window=self.frame, anchor="nw") vsb = tk.Scrollbar(self, orient="vertical") vsb.grid(row=0, column=1, sticky='ns') vsb.configure(command=self.canvas.yview) #attach scrollbar to canvas self.canvas.configure(yscrollcommand=vsb.set) #_BINDS #canvas resize self.canvas.bind("<Configure>", self.on_canvas_configure) #frame resize self.frame.bind("<Configure>", self.on_frame_configure) #scroll wheel self.canvas.bind_all('<MouseWheel>', self.on_mousewheel) #makes frame width match canvas width def on_canvas_configure(self, event): self.canvas.itemconfig(self.frame_id, width=event.width) #when frame dimensions change pass the area to the canvas scroll region def on_frame_configure(self, event): self.canvas.configure(scrollregion=self.canvas.bbox("all")) #add scrollwheel feature def on_mousewheel(self, event): self.canvas.yview_scroll(int(-event.delta / abs(event.delta)), 'units') #configure self.frame row(s) def rowcfg(self, index, **options): index = index if isinstance(index, Iterable) else [index] for i in index: self.frame.grid_rowconfigure(i, **options) #so this can be used inline return self #configure self.frame column(s) def colcfg(self, index, **options): index = index if isinstance(index, Iterable) else [index] for i in index: self.frame.grid_columnconfigure(i, **options) #so this can be used inline return self class AuxiliaryWindow(tk.Toplevel): def __init__(self, master, **kwargs): tk.Toplevel.__init__(self, master, **kwargs) self.geometry('600x300+600+200') self.attributes('-topmost', True) self.title('This Is Another Title') #:D #if you reconsider things, you can accomplish more with less labels = ["this is a sort of long label", "this is another label", "Other information: blah blah blah blah"] for i, text in enumerate(labels): ttk.Label(self, text=text).grid(row=0, column=i) self.grid_columnconfigure(i, weight=1) #doing it this way the text will always fit the display as long as you give it enough height to work with instr = tk.Text(self, height=3, wrap='word', bg='gray94', font='Arial 8 bold', bd=0, relief='flat') instr.insert('1.0', ' '.join(['instructions']*20)) instr.grid(row=1, columnspan=3, sticky='nswe') #instantiate the scrollframe, configure the first 5 columns and return the frame. it's inline mania! :p self.scrollframe = ScrollFrame(self, 10, 2, 0, cspan=3).colcfg(range(5), weight=1).frame self.fillScrollRegion() #why store a reference to this? Do you intend to change/delete it later? ttk.Button(self, text="Do Something", command=self.do).grid(row=3, columnspan=3, sticky='ew') def fillScrollRegion(self): """fills scrollable region with label widgets""" r, c = 30, 5 #math is our friend for i in range(r*c): ttk.Label(self.scrollframe, text=f"row_{i%r} col_{i//r}").grid(row=i%r, column=i//r, sticky='nsew') def do(self): pass class Root(tk.Tk): def __init__(self): tk.Tk.__init__(self) self.geometry('+550+150') self.title('This Is A Title Probably Or Something') #:D aux = AuxiliaryWindow(self) self.mainloop()Root() if __name__ == "__main__" else None