Tkinter中Canvas滚动时不更新仅调整窗口大小时刷新的问题如何解决?
问题原因
- 你在
resize_frame回调方法中强制将嵌入Canvas的Frame高度设置为了Canvas的可视区域高度,导致Frame高度永远和Canvas可视窗口一致,内部超出可视区域的控件无法被正常渲染,滚动时Canvas仅改变视口位置,无法展示Frame外的内容,只有窗口大小调整触发重绘时才会临时刷新显示。 - 没有绑定Frame的尺寸变化事件更新Canvas的滚动区域,当Frame内部控件变化时滚动区域不会自动适配。
修复方案
- 移除
resize_frame方法中强制设置Frame高度的逻辑,仅保留宽度自适应配置,让Frame高度根据内部控件自动撑开 - 绑定Frame的
<Configure>事件,每次Frame尺寸变化时自动更新Canvas的scrollregion,保证滚动范围适配内容总高度
修改后完整代码如下:
from tkinter import Tk, Canvas, Scrollbar, Frame, Button class ScrollBar: def __init__(self,root): self.canvas = Canvas(root, bg='blue') self.scroll_y = Scrollbar(root, orient="vertical", command=self.canvas.yview) self.frame = Frame(self.canvas, bg='pink') #insert Widgets self.create_widgets() #Configure frame in canvas self.frame_id = self.canvas.create_window(0, 0, window=self.frame, anchor='nw') #Update scrollregion self.canvas.update_idletasks() self.canvas.configure(scrollregion=self.canvas.bbox('all'),yscrollcommand=self.scroll_y.set) self.canvas.pack(fill='both', expand=True, side='left') self.scroll_y.pack(fill='y', side='right') #Configure resized window self.frame.grid_columnconfigure(0, weight=1) self.canvas.bind("<Configure>", self.resize_frame) # 绑定Frame尺寸变化事件,自动更新滚动区域 self.frame.bind("<Configure>", lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all"))) def create_widgets(self): for i in range(20): Button(self.frame, text=f'Button {i}').grid(row=i, column=0, sticky='nsew', pady=2) self.canvas.configure(scrollregion=self.canvas.bbox('all')) def resize_frame(self,event): # 仅保留宽度自适应配置,移除固定高度限制 self.canvas.itemconfig(self.frame_id, width=event.width) root = Tk() ScrollBar(root) root.mainloop()
内容的提问来源于stack exchange,提问作者Narayan Gautam
相关产品推荐
相关产品推荐

