如何让Tkinter中的可滚动框架使用起来更自然?
实现类标准Tkinter组件的可滚动框架
需求描述
我正在开发一个可滚动框架,它本质是包含滚动条和画布的框架,画布内部还有一个子框架,通过滚动条可滚动画布内的子框架。
我希望它能像左侧带滚动条的普通框架一样使用,示例代码如下:
root = tkinter.Tk() scroll_frame = ScrollFrame(root) for i in range(100): ttk.Button(scroll_frame, text=f"Button {i}").pack() scroll_frame.pack() root.mainloop()
显然上述方式在现有实现中无法达成,因为按钮会被放置在不可滚动的容器框架中,必须改为:
ttk.Button(scroll_frame.interior, text=...)
这使得ScrollFrame不再像标准Tkinter组件那样易用。
尝试的方案
- 最初想捕获
ScrollFrame被指定为父组件的事件,自动替换为interior子框架,但未找到实现方法。
还尝试调换角色:ScrollFrame()返回内部子框架,容器框架通过ScrollFrame().container获取,但这样需要编写如下不自然的代码:
scroll_frame = ScrollFrame() ... scroll_frame.container.pack() #doesn't look natural
为解决该问题,提出两种思路:
- 在
ScrollFrame.__init__中添加:
self.pack = self.pack_configure = container.pack self.grid = self.grid_configure = container.grid self.place = self.place_configure = container.place
但这可能引发问题,因为pack、grid、place关联大量方法,比如pack_forget、packinfo、grid_forget等,无法全部覆盖。
- 之后发现
<Map>事件,打算这样实现:
def on_map(event): container.tk.call((event.geometry_manager, "configure", container._w) + event.options) self.bind("<Map>", on_map)
遗憾的是,无法获取事件的调用方式信息。如果调用grid方法时传入参数,希望容器框架也用grid和对应参数显示,而非pack或其他方法。
求助
我的需求是否不合理?有没有合适的实现方式?
内容的提问来源于stack exchange,提问作者Arkeor
相关产品推荐
相关产品推荐

