【问题标题】:Resize columns in Frame with Scrollbar使用滚动条调整 Frame 中的列大小
【发布时间】:2017-04-28 12:36:45
【问题描述】:

基于此处的示例:Scrollbar in Tkinter grid

我制作了一个简化版本,它或多或少是我需要的,只是我希望在调整窗口大小时列始终填充框架的宽度。

没有滚动条非常简单,我只是添加了grid_columnconfigure 并且开箱即用,但是当我添加滚动条时,我无法弄清楚如何让列再次调整大小。

示例如下:

import tkinter as tk

row = 1


class ProgramWindow(tk.Frame):
    def __init__(self):
        self.canvas = tk.Canvas(root, borderwidth=0, background="#ffffff")
        tk.Frame.__init__(self, self.canvas)
        self.grid(column=0, row=0, sticky='ESW')
        self.grid_columnconfigure(0, weight=1)
        self.grid_columnconfigure(1, weight=1)
        self.grid_columnconfigure(2, weight=1)

        tk.Label(self, text="FirstCol", ).grid(row=0, column=0)
        tk.Label(self, text="SecndCol", ).grid(row=0, column=1)
        tk.Label(self, text="ThirdCol", ).grid(row=0, column=3)

        self.vsb = tk.Scrollbar(root, orient="vertical", command=self.canvas.yview)
        self.canvas.configure(yscrollcommand=self.vsb.set)

        self.vsb.pack(side="right", fill="y")
        self.canvas.pack(side="left", fill="both", expand=True)
        self.canvas.create_window((4, 4), window=self)

        self.bind("<Configure>", self.OnFrameConfigure)

    def OnFrameConfigure(self, event):
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

    def addrow(self, stuff, otherstuff):
        global row

        var = tk.StringVar(value=stuff)
        entry = tk.Entry(self, textvariable=var)
        entry.grid(row=row, column=0)

        var = tk.StringVar(value=otherstuff)
        entry = tk.Entry(self, textvariable=var)
        entry.grid(row=row, column=1)

        var = tk.StringVar(value="foobar")
        entry = tk.Entry(self, textvariable=var)
        entry.grid(row=row, column=3)

        row += 1


def SomeProg():
    for i in range(20):
        stuff = "Stuff is " + str(i)
        otherstuff = i * 4
        win.addrow(stuff, otherstuff)


root = tk.Tk()
root.title("Stuff")

win = ProgramWindow()
SomeProg()

root.mainloop()

【问题讨论】:

    标签: python-3.x tkinter grid resize scrollbar


    【解决方案1】:

    我已经改编了 Bryan Oakley 对 Adding a scrollbar to a group of widgets in Tkinter 的回答,以便画布中包含的框架适合画布的宽度。

    画布窗口对象有一个宽度选项。因此,每次调整画布大小时,我都会使用

    将新的画布宽度传递给此宽度选项

    self.canvas.itemconfigure(&lt;frame tag&gt;, width=self.canvas.winfo_width())

    这是完整的代码

    import tkinter as tk
    
    class Example(tk.Frame):
        def __init__(self, root):
    
            tk.Frame.__init__(self, root)
            self.canvas = tk.Canvas(root, borderwidth=0, background="#ffffff")
            self.frame = tk.Frame(self.canvas, background="#ffffff")
            self.frame.columnconfigure(0, weight=1)
            self.frame.columnconfigure(1, weight=1)
            self.frame.columnconfigure(2, weight=1)
            self.vsb = tk.Scrollbar(root, orient="vertical", command=self.canvas.yview)
            self.canvas.configure(yscrollcommand=self.vsb.set)
    
            self.vsb.pack(side="right", fill="y")
            self.canvas.pack(side="left", fill="both", expand=True)
            self.canvas.create_window((4,4), window=self.frame, anchor="nw", 
                                      tags="self.frame")
    
            self.canvas.bind("<Configure>", self.onCanvasConfigure)
    
            self.populate()
    
        def populate(self):
            '''Put in some fake data'''
            for i in range(100):
                tk.Entry(self.frame).grid(row=i, column=0, sticky='ew')
                tk.Entry(self.frame).grid(row=i, column=1, sticky='ew')
                tk.Entry(self.frame).grid(row=i, column=2, sticky='ew')
    
        def onCanvasConfigure(self, event):
            self.canvas.itemconfigure("self.frame", width=self.canvas.winfo_width())
            self.canvas.configure(scrollregion=self.canvas.bbox("all"))
    
    if __name__ == "__main__":
        root=tk.Tk()
        Example(root).pack(side="top", fill="both", expand=True)
        root.mainloop()
    

    【讨论】:

    • 谢谢!奇迹般有效!我也意识到 Example 类可以是 Canvas 然后你可以使用 self.canvas 来代替 self
    • 还要了解为什么我必须进行 itemconfigure... 是因为我使用了两个不同的布局管理器还是因为框架位于画布中?因为 Frame in Frame 和网格布局都可以在没有任何手动处理宽度的情况下工作。
    • 这里,self.frame 不是由包、位置或网格布局处理,而是由画布处理。在这种情况下,没有等效的包装选项fill="x", expand=True或网格选项sticky="ew"组合宽度columnconfigure,所以我们必须手动更改宽度。
    猜你喜欢
    • 2020-07-09
    • 1970-01-01
    • 1970-01-01
    • 2019-04-07
    • 2012-05-20
    • 2018-05-11
    • 2011-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多