You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tkinter复选框滚动列表尺寸过大,如何自定义调整?

Tkinter 复选框滚动列表尺寸控制问题

我经过多次测试并求助后,实现了包含多个复选框的滚动列表代码,但当前滚动区域远大于所需空间,且无法按需调整其尺寸。尝试修改grid参数未能解决问题,希望能更好地控制该滚动列表的整体尺寸(包括高度)。

初始代码

import tkinter as tk
class CheckboxList(tk.Frame):
    def __init__(self, master=None, **kw):
        super().__init__(master, **kw)
        self.checkbuttons = []
        self.vars = []
        self.canvas = tk.Canvas(self, bg='white', bd=0, highlightthickness=0)
        self.yscroll = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
        self.frame = tk.Frame(self.canvas)
        self.canvas.create_window((0, 0), window=self.frame, anchor='nw')
        self.canvas.configure(yscrollcommand=self.yscroll.set)
        self.canvas.grid(row=0,column=0, sticky='nsew')
        self.yscroll.grid(row=0, column=1, sticky='nse')
        for i in range(20):
            var = tk.IntVar(value=0)
            cb = tk.Checkbutton(self.frame, text=f"checkbutton #{i}", variable=var, onvalue=1, offvalue=0)
            cb.grid(row=i, column=0, sticky='w')
            self.checkbuttons.append(cb)
            self.vars.append(var)
        self.frame.update_idletasks()
        self.canvas.config(scrollregion=self.canvas.bbox("all"))
        
        self.canvas.bind_all("<MouseWheel>", self._on_mousewheel)
        
    def _on_mousewheel(self, event):
        self.canvas.yview_scroll(int(-1*(event.delta/120)), "units")

root = tk.Tk()
cl = CheckboxList(root, width=20, height=10)
cl.grid(row=0,column=0,sticky='nsew')
root.mainloop()

修改后的可用代码

import tkinter as tk
class CheckboxList(tk.Frame):
    def __init__(self, master=None, **kw):
        super().__init__(master, **kw)
        self.checkbuttons = []
        self.vars = []
        self.canvas = tk.Canvas(self, bg='white', bd=0, highlightthickness=0)
        # self.canvas = tk.Canvas(self, bg='white', bd=0,width=115, highlightthickness=0)
        self.yscroll = tk.Scrollbar(self, orient="vertical", command=self.canvas.yview)
        self.frame = tk.Frame(self.canvas)
        self.canvas.create_window((0, 0), window=self.frame, anchor='nw')
        self.canvas.configure(yscrollcommand=self.yscroll.set)
        self.canvas.grid(row=0,column=0, sticky='nsew')
        self.yscroll.grid(row=0, column=1, sticky='nse')
        self.frame.bind("<Configure>", lambda e: self.canvas.config(width=e.width, scrollregion=self.canvas.bbox("all")))
        # 配置容器网格权重,让canvas填满分配空间
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

        for i in range(20):
            var = tk.IntVar(value=0)
            cb = tk.Checkbutton(self.frame, text=f"checkbutton #{i}", variable=var, onvalue=1, offvalue=0)
            cb.grid(row=i, column=0, sticky='w')
            self.checkbuttons.append(cb)
            self.vars.append(var)
        self.frame.update_idletasks()
   
        self.canvas.bind_all("<MouseWheel>", self._on_mousewheel)
    
    def _on_mousewheel(self, event):
        self.canvas.yview_scroll(int(-1*(event.delta/120)), "units")

root = tk.Tk()
cl = CheckboxList(root, width=20, height=10)
cl.grid(row=0,column=0,sticky='nsew')
root.mainloop()

解决要点说明

  • 绑定<Configure>事件到内部列表容器:当复选框列表宽度变化时,自动同步canvas宽度并更新滚动区域,避免出现多余空白
  • 配置容器网格权重:让canvas完全填满CheckboxList的空间,实例化时传入的width和height参数可直接控制滚动列表的可视尺寸
  • 移除硬编码的canvas宽度:改为动态适配内容宽度,让列表宽度由复选框文本长度决定

内容的提问来源于stack exchange,提问作者Jake85

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 09:00:55