网格填充可滚动区域tkinter中的空白空间

Posted

技术标签:

【中文标题】网格填充可滚动区域tkinter中的空白空间【英文标题】:Grid fill empty space in scrollable area tkinter 【发布时间】:2022-01-22 17:52:37 【问题描述】:

我正在构建一个带有可滚动区域中标签列表的 gui。现在我希望标签通过网格管理器填充空白空间。所以我使用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()

【问题讨论】:

【参考方案1】:

标签没有填满水平空间的原因有几个:

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

      self.scrollable_frame.columnconfigure(0, weight=1)
    

    您在将self.scrollable_frame 放入画布时没有设置它的宽度和高度,因此默认情况下,它保持显示其所有内容所需的大小。如果您希望它扩展以填充画布中的所有可用空间,您可以将画布调整大小事件绑定到将相应调整框架大小的函数。所以添加

     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))
    

    如果画布大于显示所有小部件所需的最小尺寸,则使框架扩展。

顺便说一句,我建议您遵循PEP 8 样式指南,尤其是对于名称,例如大写类名但不是变量名。最重要的是,保持一致,这将使代码更清晰、更容易理解。特别是,我发现使用 LabelButton 作为变量名非常令人困惑,因为它们是 tkinter 中的类名。

【讨论】:

您的回答很有帮助。谢谢!我想用垂直箭头表明网格管理器在这个方向上工作正常。但是是的,这有点令人困惑。 @lu3si 好的,太好了。我不确定你是否也想改变垂直间距。

以上是关于网格填充可滚动区域tkinter中的空白空间的主要内容,如果未能解决你的问题,请参考以下文章

无法在tkinter上使用网格调整树视图大小

使用 tkinter 的网格内的可滚动列表框

Tkinter 网格动态布局

防止网格区域扩大导致整个页面滚动

如何使 flexbox 元素填充剩余空间并滚动?

Recyclerview:监听填充点击事件