简体   繁体   English

Tkinter:如何让画布窗口中的框架扩展到画布的大小?

[英]Tkinter: How to get frame in canvas window to expand to the size of the canvas?

So I've been using the canvas widget in tkinter to create a frame full of labels which has a scrollbar.所以我一直在 tkinter 中使用画布小部件来创建一个充满标签的框架,该框架有一个滚动条。 All is working good except that the frame only expands to the size of the labels placed in it - I want the frame to expand to the size of the parent canvas.一切都很好,除了框架只扩展到放置在其中的标签的大小 - 我希望框架扩展到父画布的大小。

This can easily be done if I use pack(expand = True) (which I have commented out in the code below) for the frame in the canvas but then then the scrollbar doesn't work.如果我对画布中的框架使用 pack(expand = True) (我已在下面的代码中注释掉),则可以轻松完成此操作,但随后滚动条不起作用。

Here's the appropriate bit of code:这是适当的代码:

    ...
    self.canvas = Canvas(frame, bg = 'pink')
    self.canvas.pack(side = RIGHT, fill = BOTH, expand = True)

    self.mailbox_frame = Frame(self.canvas, bg = 'purple')

    self.canvas.create_window((0,0),window=self.mailbox_frame, anchor = NW)

    #self.mailbox_frame.pack(side = LEFT, fill = BOTH, expand = True)

    mail_scroll = Scrollbar(self.canvas, orient = "vertical",
        command = self.canvas.yview)
    mail_scroll.pack(side = RIGHT, fill = Y)

    self.canvas.config(yscrollcommand = mail_scroll.set)

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


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

I've also provided an image with colored frames so you can see what I'm getting at.我还提供了带有彩色框架的图像,因此您可以看到我在做什么。 The pink area is the canvas that needs filling by the mailbox_frame (You can see the scrollbar on the right):粉色区域是需要通过mailbox_frame填充的画布(可以看到右边的滚动条):

Just for future reference in case anyone else needs to know:仅供将来参考,以防其他人需要知道:

        frame = Frame(self.bottom_frame)
        frame.pack(side = LEFT, fill = BOTH, expand = True, padx = 10, pady = 10)

        self.canvas = Canvas(frame, bg = 'pink')
        self.canvas.pack(side = RIGHT, fill = BOTH, expand = True)

        self.mailbox_frame = Frame(self.canvas, bg = 'purple')

        self.canvas_frame = self.canvas.create_window((0,0),
            window=self.mailbox_frame, anchor = NW)
        #self.mailbox_frame.pack(side = LEFT, fill = BOTH, expand = True)

        mail_scroll = Scrollbar(self.canvas, orient = "vertical", 
            command = self.canvas.yview)
        mail_scroll.pack(side = RIGHT, fill = Y)

        self.canvas.config(yscrollcommand = mail_scroll.set)

        self.mailbox_frame.bind("<Configure>", self.OnFrameConfigure)
        self.canvas.bind('<Configure>', self.FrameWidth)

    def FrameWidth(self, event):
        canvas_width = event.width
        self.canvas.itemconfig(self.canvas_frame, width = canvas_width)

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

Set a binding on the canvas <Configure> event, which fires whenever the canvas changes size.在画布<Configure>事件上设置绑定,只要画布改变大小就会触发。 From the event object you can get the canvas width and height, and use that to resize the frame.从事件对象中,您可以获得画布宽度和高度,并使用它来调整框架的大小。

Just an updated answer which covers both horizontal and vertical scrollbars without breaking them.只是一个更新的答案,它涵盖了水平和垂直滚动条而不会破坏它们。

def FrameWidth(self, event):
    if event.width > self.mailbox_frame.winfo_width():
        self.canvas.itemconfig(self.canvas_frame, width=event.width-4)
    if event.height > self.mailbox_frame.winfo_height():
        self.canvas.itemconfig(self.canvas_frame, height=event.height-4)

Only sets the frame height and width if they are less than the canvas width.仅当框架高度和宽度小于画布宽度时才设置它们。 Respects both Horizontal and Vertical scrollbars.尊重水平和垂直滚动条。

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

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