简体   繁体   English

tkinter:使用框架内容填充可滚动画布

[英]tkinter : Fill scrollable canvas with frame content

I've searched a lot but found no way to properly fill a scrollable canvas with this content frame. 我搜索了很多但发现无法用这个内容框架正确填充可滚动画布。 There is always extra space. 总有额外的空间。

In the code below found on SO and adapted to a simple example, I want my DummyFrame components to take all the extra space left of the canvas. 在下面的代码中找到并适用于一个简单的例子,我希望我的DummyFrame组件占用画布剩余的所有额外空间。

import Tkinter as tk

class DummyFrame(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root, borderwidth=10, background="#ff0000")
        tk.Label(self, text="DummyLabel").grid(row=0, column=0, sticky="wnes")
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

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, borderwidth=10, background="#000000")
        self.vsb = tk.Scrollbar(root, orient="vertical", command=self.canvas.yview)
        self.canvas.configure(yscrollcommand=self.vsb.set)

        self.vsb.grid(row=0, column=1, sticky="wnes")
        self.canvas.grid(row=0, column=0, sticky="wnes")
        self.canvas.create_window((0,0), window=self.frame, anchor="nw", 
                                  tags="self.frame")

        self.frame.columnconfigure(0, weight=1)
        self.frame.rowconfigure(0, weight=1)
        self.frame.bind("<Configure>", self.OnFrameConfigure)

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

        self.populate()

    def populate(self):
        for i_row in range(50):
            #Component I want to take extra space when resizing window
            DummyFrame(self.frame).grid(row = i_row+1, column = 0, sticky="we")

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

if __name__ == '__main__':
    fenetre = tk.Tk()
    fenetre.geometry('{}x{}'.format(800, 600))
    Example(fenetre)
    fenetre.columnconfigure(0, weight=1)
    fenetre.rowconfigure(0, weight=1)
    fenetre.mainloop()

This example is very strangely destined. 这个例子非常奇怪。 So you have DummyFrames in a Frame in a canvas window which is in a canvas in a Frame. 因此,在画布窗口的Frame中有DummyFrames,它位于Frame的画布中。 Its difficult to see what is happening here, and which widget dimension control most the resulting dimension the user sees. 很难看到这里发生了什么,以及哪个小部件维度控制了用户看到的最终维度。 Nevertheless, if you want to make the DummyFrame as width as your root window (ie 800 px) just change the canvas window width: 不过,如果你想让DummyFrame作为根窗口的宽度(即800 px),只需更改画布窗口宽度:

self.canvas.create_window((0,0), window=self.frame, anchor="nw", 
                          width=800,
                          tags="self.frame")

Finaly I found something fitted my needs using itemconfigure of the canvas: 最后,我使用画布的itemconfigure找到了符合我需求的东西:

import Tkinter as tk

class DummyFrame(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root, borderwidth=10, background="#ff0000")
        tk.Label(self, text="DummyLabel").grid(row=0, column=0, sticky="wnes")
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)
        pass

class Example(tk.Frame):
    def __init__(self, root):
        tk.Frame.__init__(self, root)

        self.canvas = tk.Canvas(root, borderwidth=0, background="#0000ff")
        self.vsb = tk.Scrollbar(root, orient="vertical", command=self.canvas.yview)
        self.canvas.configure(yscrollcommand=self.vsb.set)
        self.canvas.bind("<Configure>", self.OnCanvasConfigure)
        self.vsb.grid(row=0, column=1, sticky="wnes")
        self.canvas.grid(row=0, column=0, sticky="wnes")

        self.frame = tk.Frame(self.canvas, borderwidth=10, background="#000000")
        self.frame.columnconfigure(0, weight=1)
        self.frame.rowconfigure(0, weight=1)

        self.window = self.canvas.create_window((0,0), window=self.frame, anchor="nw",
                          tags="self.frame")

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

        self.populate()

    def populate(self):
        for i_row in range(50):
            #Component I want to take extra space when resizing window
            DummyFrame(self.frame).grid(row = i_row+1, column = 0, sticky="we")

    def OnCanvasConfigure(self, event):
        self.canvas.itemconfigure(self.window, width=event.width)
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

if __name__ == '__main__':
    fenetre = tk.Tk()
    fenetre.geometry('{}x{}'.format(800, 600))
    Example(fenetre)
    fenetre.columnconfigure(0, weight=1)
    fenetre.rowconfigure(0, weight=1)
    fenetre.mainloop()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM