mzittlow 0 Newbie Poster

I am creating a scrolled frame object within Tkinter. My current approach is to have a frame embedded within a scrolling canvas. I have seen numerous examples of this technique but they have one common 'flaw'--the frame's contents are loaded and then the controlling canvas's scrollregion is set. In my case the size of the frame is unknown at the time of instantiation. I can get it to work by calling a class method to update the scrollregion but this must be done manually everytime the contents of the frame changes (i.e. widgets are added or deleted from the frame)

Is there a way to get the scrollregion to automatically respond to changes in the dimensions of the embedded frame?

Any assistance would be appreciated.

from Tkinter import Canvas, Frame, Scrollbar

class ScrolledFrame(Frame):

    def __init__(self, master=None, width=500, height=500):
        
        #create scrolling canvas
        canvas = Canvas(master, height=height, width=width)
        canvas.grid(row=0, column=0, sticky='nswe')

        #call super class using scrolling canvas as master
        Frame.__init__(self, master=canvas)

        #crete scrollbars for the canvas
        hScroll = Scrollbar(master, orient='horizontal', command=canvas.xview)
        hScroll.grid(row=1, column=0, sticky='we')
        vScroll = Scrollbar(master, orient='vertical', command=canvas.yview)
        vScroll.grid(row=0, column=1, sticky='ns')
        canvas.configure(xscrollcommand=hScroll.set, yscrollcommand=vScroll.set)

        #embed frame within the scrolling canvas
        canvas.create_window(0,0, window=self, anchor='nw')

        #save reference to scrolling canvas
        self.canvas=canvas

    def updateScrollers(self):
        '''update the canvas scrollregion based on size of embedded frame'''
        self.update_idletasks()
        self.canvas.configure(scrollregion=self.canvas.bbox('all'))

if __name__ == '__main__':
    from Tkinter import *

    root = Tk()
    ## Grid sizing behavior in window
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)

    #Create a scrolled frame and load with 100 labels
    scrollframe=ScrolledFrame(root,200,100)
    for i in range(100):
        Label(scrollframe, text=str(i)).pack()

    #update the scrollregion
    scrollframe.updateScrollers()

    #start mainloop
    root.mainloop()
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.