我一直在尝试使用此处的许多答案和分散的指南使用 Tkinter / ttk 创建一个可滚动框架。框架用于保存一个可以添加和删除行的表。我遇到的一个在其他地方找不到的问题是,如果框架内有空间容纳更多内容,我可以将表格的内容滚动到框架的底部。当框架已满时,它的行为符合预期。
我目前无法转换为 gif,因此我添加了一些屏幕截图来尝试说明。
这是我的可滚动框架类,从网络上的示例来看,它非常标准;
class ScrollableFrame(ttk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.canvas = tk.Canvas(self)
self.scrollbar = ttk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
self.scrollableFrame = ttk.Frame(self.canvas)
self.canvas.configure(yscrollcommand=self.scrollbar.set)
self.scrollableFrame.bind("<Configure>", lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))
self.bind("<Enter>", self.bind_to_mousewheel)
self.bind("<Leave>", self.unbind_from_mousewheel)
self.scrollbar.pack(side='right', fill='y')
self.canvas.pack(side='top', expand=0, fill='x')
self.canvas.create_window((0, 0), window=self.scrollableFrame)
def bind_to_mousewheel(self, event):
self.canvas.bind_all("<MouseWheel>", self.on_mousewheel)
def unbind_from_mousewheel(self, event):
self.canvas.unbind_all("<MouseWheel>")
def on_mousewheel(self, event):
self.canvas.yview_scroll(int(-1*(event.delta/120)), "units")
表格行由父 GUI 添加到
ScrollableFrame.scrollableFrame
小部件,我认为这是触发绑定到 <Configure>
的 ScrollableFrame.canvas
所必需的。
有人有什么建议吗?
感谢@acw1668的提示,我找到了答案;
我调整了
<Configure>
命令来检查 scrollregion
的大小并将其与父 ScrollableFrame
类窗口进行比较。如果它更小,我将滚动区域更改为 ScrollableFrame
的大小。
这是我对班级所做的调整,包括将窗口锚点更改为位于框架的左上角;
class ScrollableFrame(ttk.Frame):
"""
"""
def __init__(self, parent):
"""
"""
...
self.scrollableFrame.bind("<Configure>", self.update_scroll_region)
...
self.canvas.create_window((0, 0), window=self.scrollableFrame, anchor='nw')
def update_scroll_region(self, event):
bbox = self.canvas.bbox('all')
sfHeight = self.winfo_height()
if (bbox[3] - bbox[1]) < sfHeight:
newBbox = (bbox[0], 0, bbox[2], sfHeight)
self.canvas.configure(scrollregion=newBbox)
else:
self.canvas.configure(scrollregion=self.canvas.bbox("all"))