使用Tkinter滚动和校正缩放

时间:2015-10-28 23:19:51

标签: python tkinter tk tkinter-canvas

我需要这个简单的表格: 1)调整窗口大小时正确扩展字段 2)正确滚动字段列表。

我已经尝试过各种我能想到的方式,上述两种情况中只有一种是真的。此代码正确扩展但不滚动。没有frame2,并将字段添加到框架或画布,则相反的情况属实。

class test(Tkinter.Tk):

    def __init__(self,parent):
        Tkinter.Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()

    def makeform(self, root, fields):
        i = 0
        for field in fields:
            Label(root, text=field + ": ", anchor=W).grid(row=i)
            entry = Entry(root)
            entry.grid(row=i, column=1, sticky=E+W)
            entries[field] = entry
            i += 1

    def initialize(self):

        frame = Frame(self)
        frame.rowconfigure(0, weight=1)
        frame.columnconfigure(0, weight=1)
        frame.grid(sticky=N+S+E+W)

        canvas = Canvas(frame, width=900, height=800, bg='pink')
        canvas.grid(row=0, column=0, sticky=N+S+E+W)
        canvas.columnconfigure(0,weight=1)
        canvas.rowconfigure(0,weight=1)

        frame2 = Frame(canvas)
        frame2.grid(row=0, column=0, sticky=N+S+E+W)
        frame2.columnconfigure(1, weight=1)

        vscrollbar = Scrollbar(frame2,orient=VERTICAL)
        vscrollbar.grid(row=0, column=2, sticky=N+S)

        vscrollbar.config(command=canvas.yview)

        canvas.configure(yscrollcommand=vscrollbar.set)

        self.grid_rowconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)

        names = {'a','long','list','of','names','here'}
        self.makeform(frame2, names)

        Button(self, text='Quit', command=self.quit).grid(row=1, column=0, sticky=W, pady=4)

        canvas.create_window(0, 0)
        canvas.config(scrollregion=canvas.bbox(ALL))

        self.grid()

if __name__ == "__main__":

    entries = {}

    app = test(None)
    app.title('Hi ')
    app.mainloop()

更新

集成下面的Bryan示例,这适用于滚动,但在调整窗口大小时不会扩展字段。我尝试将weight = 1添加到框架的第二列,但它没有帮助。如何防止框架收缩?

class test(Tkinter.Frame):

    def __init__(self,parent):
        Tkinter.Frame.__init__(self, root)
        self.canvas = Tkinter.Canvas(root, borderwidth=0, background="#ffffff")
        self.frame = Tkinter.Frame(self.canvas, background="#ffffff")
        self.vsb = Tkinter.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((0,0), window=self.frame, anchor="nw",
                                  tags="self.frame")

        self.frame.bind("<Configure>", self.onFrameConfigure)

        self.populate()

    def onFrameConfigure(self, event):
        '''Reset the scroll region to encompass the inner frame'''
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

    def makeform(self, fields):
        i = 0
        for field in fields:
            Label(self.frame, text=field + ": ", anchor=W).grid(row=i)
            entry = Entry(self.frame)
            entry.grid(row=i, column=1, sticky=E+W)
            entries[field] = entry
            i += 1
        Button(self.frame, text='Quit', command=self.quit).grid(row=i, column=0, sticky=W, pady=4)


    def populate(self):
        names = {'a','long','list','of','names','here'}
        self.makeform(names)
        self.frame.columnconfigure(1, weight=1)
        self.frame.grid_columnconfigure(1, weight=1)

if __name__ == "__main__":

    entries = {}

    root=Tk()
    test(root).pack(side="top", fill="both", expand=True)
    root.mainloop()

1 个答案:

答案 0 :(得分:2)

您的代码中至少存在三个问题。

首先,要滚动的框架必须是画布的一部分。您无法使用packgrid将其放入画布,您必须使用create_window。您正在调用create_window,但您没有告诉它要添加哪个窗口。

其次,滚动条是框架的子项,但我假设这些是您想要滚动画布的滚动条。需要在内框架之外,在画布外面。

第三,您需要设置对画布的<Configure>事件的绑定,以便您可以调整内部框架的大小并重新计算画布的滚动区域。

可回滚框架的完整工作示例在此答案中:https://stackoverflow.com/a/3092341/7432