可滚动区域 tkinter 中的网格填充为空 space

Grid fill empty space in scrollable area tkinter

我正在构建一个带有可滚动区域中的标签列表的图形用户界面。现在我希望标签通过网格管理器填充空 space。所以我使用 columnconfigure(0, weight=1)rowconfigure(0, weight=1) 方法。它适用于滚动条但不适用于可滚动区域内的标签。显示我的问题的示例:

class app():

    def __init__(self):
        self.root = tk.Tk()
        self.root.geometry("341x448")
        self.root.minsize(340,440)
        self.root.rowconfigure(0, weight=1)
        self.root.columnconfigure(0, weight=1)


    def display(self):
        self.container = ttk.Frame(self.root)
        self.container.rowconfigure(0, weight=1)
        self.container.columnconfigure(0, weight=1)


        self.canvas = tk.Canvas(self.container)

        scrollbar = ttk.Scrollbar(self.container, orient = tk.VERTICAL, command = self.canvas.yview)
        self.scrollable_frame = ttk.Frame(self.canvas)


        self.scrollable_frame.bind(
            "<Configure>",
            lambda e: self.canvas.configure(
                scrollregion=self.canvas.bbox("all")))

        self.canvas.create_window((0, 0), window = self.scrollable_frame, anchor = "nw")
        self.canvas.configure(yscrollcommand = scrollbar.set)



        for i in range(15):
            Label = ttk.LabelFrame(self.scrollable_frame, text = "Sample scrolling label")
            Label.grid(row = i, column = 0,  columnspan=2, sticky=tk.NSEW)
            Label.columnconfigure(0, weight=1)

            Button = ttk.Button(Label, text=f"Button {i}")
            Button.grid(row=0, column=0, sticky=tk.NW)

        self.container.grid(row = 0, column = 0, sticky = "nswe")
        self.canvas.grid(row = 0, column = 0, sticky = 'nswe')
        scrollbar.grid(row = 0, column = 2, sticky = "ns")


        self.root.mainloop()

if __name__ =="__main__":
    start = app()
    start.display()

有几个原因导致您的标签未填满水平方向 space:

  1. 您对 self.scrollable_frame 中的标签进行了网格化,但尚未配置其网格展开。您需要添加

      self.scrollable_frame.columnconfigure(0, weight=1)
    
  2. self.scrollable_frame放入canvas时没有设置self.scrollable_frame的宽度和高度,所以默认保持显示所有内容所需的大小内容。如果您希望它扩展以填充 canvas 中可用的所有 space,您可以将 canvas 调整大小事件绑定到一个函数,该函数将相应地调整框架的大小。所以添加

     self.canvas.bind("<Configure>", self.resize)
    

    self.display() 中创建 self.resize() 函数

    def resize(self, event):
         w = self.scrollable_frame.winfo_reqwidth()
         h = self.scrollable_frame.winfo_reqheight()
         self.canvas.itemconfigure(1, width=max(w, event.width), height=max(h, event.height))
    

    如果 canvas 大于显示所有小部件所需的最小尺寸,则框架会展开。

顺便说一下,我建议您遵循 PEP 8 风格指南,尤其是名字,例如大写 class 名称但不是变量名称。最重要的是,要保持一致,这将使代码更清晰、更容易理解。特别是,我发现使用 LabelButton 作为变量名非常混乱,因为它们在 tkinter 中是 class 名称。