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