It works if you change it like so: from tkinter import * class ShowList(Frame): def __init__(self, root): Frame.__init__(self, root) self.grid() self.draw_widgets() def draw_widgets(self): cframe = Frame(self) cframe.grid(row=1, sticky=N+S+E+W) canv = Canvas(cframe) canv.grid(row=0, column=0, sticky=N+S+E+W) vscroll = Scrollbar(cframe, orient=VERTICAL, command=canv.yview) hscroll = Scrollbar(cframe, orient=HORIZONTAL, command=canv.xview) vscroll.grid(row=0, column=1, sticky=N+S) hscroll.grid(row=1, column=0, sticky=E+W) canv["xscrollcommand"] = hscroll.set canv["yscrollcommand"] = vscroll.set aframe = Frame(canv) id = canv.create_window(0,0,window=aframe, anchor=N+W) for i in range(0,100): Label(aframe, text=str(i), anchor=N+W).grid(row=i, column=0) aframe.update_idletasks() canv["scrollregion"]=canv.bbox(ALL) root = Tk() m=ShowList(root) root.mainloop()
You have to call update_idletasks to force the canvas to be mapped to screen; until it is mapped, its bounding box is (0,0,1,1). You can call update_idletasks through any widget. That said, I wonder if it wouldn't be better to put canvas objects directly on the canvas, instead of putting widgets in a frame on the canvas. The way you're doing it, you can't give the widgets tags, which are what give the canvas its real power. -- http://mail.python.org/mailman/listinfo/python-list