如何为Tkinter左侧面板中的按钮添加滚动条?
Tkinter左侧面板添加滚动条实现按钮滚动
我想在Tkinter程序的左侧面板中添加滚动条,用来滚动面板内的按钮,但目前无法直接给Frame组件添加滚动条。希望实现的效果是:左侧出现一个带垂直滚动条的面板,面板内的按钮超出高度时可以通过滚动条上下查看。
以下是我尝试的代码:
import tkinter as tk # 创建窗口 aplicacion = tk.Tk() # 获取屏幕信息 width= aplicacion.winfo_screenwidth() height= aplicacion.winfo_screenheight() # 设置窗口大小 aplicacion.geometry("%dx%d" % (width, height)) aplicacion.title("Gestor de Flotas - Tallers Citoler") # 窗口标题 aplicacion.title("Tallers Citoler - Gestor de flotas") # 窗口背景色,暂时设置为这个 aplicacion.config(bg='gainsboro') # 顶部面板(标题标签) panel_superior = tk.Frame(aplicacion, bd=1, relief = tk.FLAT, bg = 'steelblue') panel_superior.pack(side=tk.TOP) # 标题标签 etiqueta_titulo = tk.Label(panel_superior, text='Tallers Citoler - Sistema de Gestion de Flotas', fg='black', font=('Dosis', 58), bg= 'darksalmon' , width=43) etiqueta_titulo.grid(row=0, column=0) # 左侧面板 panel_izquierdo = tk.Frame(aplicacion, bd=1, relief=tk.FLAT, bg = 'steelblue') panel_izquierdo.pack(side=tk.LEFT) fondo_panel_izquierdo = etiqueta_titulo = tk.Label(panel_izquierdo, bg= 'lightgrey', width=100, height=65) fondo_panel_izquierdo.grid(row=0, column=0) # 右侧面板 panel_derecho = tk.Frame(aplicacion, bd=1, relief=tk.FLAT, bg = 'steelblue') panel_derecho.pack(side=tk.RIGHT) fondo_panel_derecho = panel_derecho = tk.Label(panel_derecho, bg= 'khaki', width=172, height=65) fondo_panel_derecho.grid(row=0, column=0) # 左侧面板滚动条 scrollbar_panel_izquierdo = tk.Scrollbar(panel_izquierdo) scrollbar_panel_izquierdo.grid(row=0, column=1, sticky='ns') # 将滚动条绑定到左侧面板 scrollbar_panel_izquierdo.config(command=panel_izquierdo.yview) scrollbar_panel_izquierdo.config(yscrollcommand=scrollbar_panel_izquierdo.set) aplicacion.mainloop()
解决方案
Tkinter的Frame本身不支持滚动,需要通过Canvas+Frame的组合实现滚动效果:在Canvas中嵌入存放按钮的Frame,再把滚动条和Canvas绑定,让Frame随Canvas的滚动同步移动。
修改后的完整代码如下:
import tkinter as tk # 创建窗口 aplicacion = tk.Tk() # 获取屏幕信息 width = aplicacion.winfo_screenwidth() height = aplicacion.winfo_screenheight() # 设置窗口大小 aplicacion.geometry("%dx%d" % (width, height)) aplicacion.title("Tallers Citoler - Gestor de flotas") # 窗口背景色 aplicacion.config(bg='gainsboro') # 顶部面板(标题标签) panel_superior = tk.Frame(aplicacion, bd=1, relief=tk.FLAT, bg='steelblue') panel_superior.pack(side=tk.TOP, fill=tk.X) # 标题标签 etiqueta_titulo = tk.Label(panel_superior, text='Tallers Citoler - Sistema de Gestion de Flotas', fg='black', font=('Dosis', 58), bg='darksalmon') etiqueta_titulo.pack(pady=10) # ---------------------- 左侧滚动面板实现 ---------------------- panel_izquierdo = tk.Frame(aplicacion, bd=1, relief=tk.FLAT, bg='steelblue') panel_izquierdo.pack(side=tk.LEFT, fill=tk.Y, padx=5, pady=5) # 1. 创建Canvas作为滚动容器 canvas_izquierdo = tk.Canvas(panel_izquierdo, bg='lightgrey') canvas_izquierdo.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) # 2. 创建滚动条并绑定Canvas scrollbar_izquierdo = tk.Scrollbar(panel_izquierdo, orient=tk.VERTICAL, command=canvas_izquierdo.yview) scrollbar_izquierdo.pack(side=tk.RIGHT, fill=tk.Y) canvas_izquierdo.configure(yscrollcommand=scrollbar_izquierdo.set) # 3. 创建存放按钮的Frame,嵌入Canvas中 contenedor_botones = tk.Frame(canvas_izquierdo, bg='lightgrey') # 将Frame与Canvas的窗口绑定 canvas_izquierdo.create_window((0, 0), window=contenedor_botones, anchor='nw') # 4. 添加测试按钮(模拟大量按钮场景) for i in range(30): btn = tk.Button(contenedor_botones, text=f"按钮 {i+1}", font=('Arial', 12), width=20, bg='white', bd=1) btn.pack(pady=8, padx=10, fill=tk.X) # 5. 绑定Frame大小变化事件,更新Canvas的滚动区域 def actualizar_scroll_region(event): canvas_izquierdo.configure(scrollregion=canvas_izquierdo.bbox("all")) contenedor_botones.bind("<Configure>", actualizar_scroll_region) # ---------------------- 右侧面板 ---------------------- panel_derecho = tk.Frame(aplicacion, bd=1, relief=tk.FLAT, bg='steelblue') panel_derecho.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=5, pady=5) fondo_panel_derecho = tk.Label(panel_derecho, bg='khaki') fondo_panel_derecho.pack(fill=tk.BOTH, expand=True) aplicacion.mainloop()
关键改动说明
- 用
Canvas替代原Label作为左侧滚动容器,在Canvas中嵌入专门存放按钮的contenedor_botonesFrame - 将滚动条的
command绑定到Canvas的yview方法,同时把Canvas的yscrollcommand绑定到滚动条的set方法,实现双向联动 - 给按钮容器Frame绑定
<Configure>事件,当Frame内元素增减导致大小变化时,自动更新Canvas的滚动区域范围 - 调整面板的
pack参数,使用fill和expand让面板自适应窗口大小
内容的提问来源于stack exchange,提问作者Ricard Citoler
相关产品推荐
相关产品推荐

