Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. 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.

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):

like image 238
Jay Jen Avatar asked Mar 28 '15 16:03

Jay Jen


2 Answers

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"))
like image 155
Jay Jen Avatar answered Nov 12 '22 17:11

Jay Jen


Set a binding on the canvas <Configure> event, which fires whenever the canvas changes size. From the event object you can get the canvas width and height, and use that to resize the frame.

like image 18
Bryan Oakley Avatar answered Nov 12 '22 18:11

Bryan Oakley