Tkinter画布滚动展示控件(一般用于不定数目的控件展示(或者空间有限))
需求:有限空间展示不定数量的控件
需求分析及其实现方法:canvas控件捆绑滚动条,不定数量的其他控件画在canvas上面。另外增加鼠标滑轮的缩放控制上下滚动效果
实现代码如下:
def groups_outer_view(self, parent):
"""画一个带滚动条的canvas,里面有个frame用于放置需要的不定数量的控件:self.frame_groups"""
self.canvas = tk.Canvas(parent, scrollregion=(0, 0, 400, 100), bg="black") # 创建canvas: self.frame_center_down_l
self.canvas.pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES, padx=0, pady=0) # 放置canvas的位置
# 这个frame放在canvas画布中,其他不定数量的控件按顺序放置在其中即可
self.frame_groups = tk.Frame(self.canvas)
self.frame_groups.pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES, padx=0, pady=0)
self.vbar = tk.Scrollbar(self.canvas, orient=tk.VERTICAL) # 竖直滚动条
self.vbar.pack(side=tk.RIGHT, fill=tk.Y, expand=tk.NO)
self.vbar.configure(command=self.canvas.yview)
self.hbar = tk.Scrollbar(self.canvas, orient=tk.HORIZONTAL) # 水平滚动条
self.hbar.pack(side=tk.BOTTOM, fill=tk.X, expand=tk.NO)
self.hbar.configure(command=self.canvas.xview)
self.canvas.config(xscrollcommand=self.hbar.set, yscrollcommand=self.vbar.set) # 设置
self.canvas.config(yscrollcommand=self.vbar.set) # 设置
self.canvas.create_window((0, 0), window=self.frame_groups, anchor='nw') # create_window
self.canvas.config(scrollregion=(0, 0, 320, self.filter_group_num * 29)) # 29是每行预估的高度
# return self.frame_groups
def process_wheel_inside_canvas(self, event):
"""滚轮上下滚动"""
# print(f"process_wheel_inside_canvas-event: {event}")
if event.delta > 0: # 滚轮往上滚动
self.canvas.yview_scroll(-1, "units")
else: # 滚轮往下滚动
self.canvas.yview_scroll(1, "units")
def bind_wheel_inside_canvas(self, widget):
"""为此控件绑定MouseWheel事件,执行self.process_wheel_inside_canvas"""
event, callback = "<MouseWheel>", self.process_wheel_inside_canvas
widget.bind(event, callback)
def groups_inner_view(self, parent, num):
"""这里根据实际情况画每组的真正需要的控件(每组放入自身的父frame,所有父frame又画在self.frame_groups即可)"""
self.frame_outer_group_dict = dict()
for i in range(num):
# 先搞个外部frame:每组自身的父frame
self.frame_outer_group_dict[i] = tk.Frame(master=parent, bg='black') # self.frame_groups
self.frame_outer_group_dict[i].pack(side=tk.TOP, fill=tk.BOTH, expand=tk.YES)
# 再生成每组的真正需要的控件
。。。
# 给如下控件绑定滑动鼠标的事件:每行的外部frame及其上面的控件(除了Combobox外:因为Combobox本身会对鼠标滚轮有响应,两者一起响应的话可能会误改Combobox的内容而不自知)
self.bind_wheel_inside_canvas(self.frame_outer_group_dict[i])
for widget in [每个需要的子控件(要除开Combobox)]:
self.bind_wheel_inside_canvas(每个需要的子控件)
# 画一个带滚动条的canvas,里面有个frame用于放置需要的不定数量的控件:self.frame_groups
self.groups_outer_view(self.frame_parent)
# 这里根据实际情况画多组控件(画在self.frame_groups即可了)
self.groups_inner_view(self.frame_groups, font_size_iir)
效果如下:
参考:
tkinter绑定鼠标滚轮滚动事件 https://blog.csdn.net/WhoisPo/article/details/49557987
python tkinter画布设置按钮对图片放大缩小_使用鼠标移动和缩放Tkinter画布 https://blog.csdn.net/weixin_30550287/article/details/112989812
Python Canvas.yview_scroll方法代码示例 https://vimsky.com/examples/detail/python-ex-Tkinter-Canvas-yview_scroll-method.html
Tkinter 吐槽之二:Event 事件在子元素中共享 https://www.cnblogs.com/libitum/p/14959960.html