canvas pack(side=topfill=bothexpand=yesso clipped first vbar config(command=canvas yviewhbar config(command=canvas xviewcanvas config(yscrollcommand=vbar setcanvas config(xscrollcommand=hbar setcanvas config(height=heightwidth=widthcall on scroll move call on canvas move init viewable area size changes if user resizes [(imgfileimgobj)thumbs makethumbs(imgdirnumthumbs len(thumbsif not numcolsnumcols int(math ceil(math sqrt(numthumbs))fixed or numrows int(math ceil(numthumbs numcols) true div linksize max(thumbs[ ][ sizefullsize ( (linksize numcols)(linksize numrowscanvas config(scrollregion=fullsize(widthheightupper left , lower right , scrollable area size rowpos savephotos [while thumbsthumbsrowthumbs thumbs[:numcols]thumbs[numcols:colpos for (imgfileimgobjin thumbsrowphoto photoimage(imgobjlink button(canvasimage=photohandler lambda savefile=imgfileviewone(imgdirsavefilelink config(command=handlerwidth=linksizeheight=linksizelink pack(side=leftexpand=yescanvas create_window(colposrowposanchor=nwwindow=linkwidth=linksizeheight=linksizecolpos +linksize savephotos append(photorowpos +linksize return winsavephotos if __name__ ='__main__'imgdir 'imagesif len(sys argv else sys argv[ mainsave viewer(imgdirkind=tkmain mainloop(to see this program in actionmake sure you've installed the pil extension described near the end of and launch the script from command linepassing the name of the image directory to be viewed as command-line argument\pp \gui\pilviewer_thumbs_scrolled py :\users\mark\temp\ msdcf as beforeclicking on thumbnail image opens the corresponding image at its full size in new pop-up window figure - shows the viewer at work on large directory copied from my digital camerathe initial run must create and cache thumbnailsbut later runs start quickly tkinter tourpart