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