使用滚动条调整Frame中的列的大小

时间:2017-04-28 12:36:45

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

基于此处的示例: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()

1 个答案:

答案 0 :(得分:2)

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

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

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

self.canvas.itemconfigure(<frame tag>, 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()