Scrollable Canvases and Image Thumbnails
At the end of Chapter 8, we looked at a collection of scripts that display thumbnail
image links for all photos in a directory. There, we noted that scrolling is a major
requirement for large photo collections. Now that we know about canvases and scroll-
bars, we can finally put them to work to implement this much-needed extension, and
conclude the image viewer story we began in Chapter 8 (well, almost).
Example 9-15 is a mutation of the last chapter’s code, which displays thumbnails in a
scrollable canvas. See the prior chapter for more details on its operation, including
the ImageTk module imported from the required Python Imaging Library (PIL) third-
party extension (needed for thumbnails and JPEG images).
In fact, to fully understand Example 9-15, you must also refer to Example 8-45, since
we’re reusing that module’s thumbnail creator and photo viewer tools. Here, we are
just adding a canvas, positioning the fixed-size thumbnail buttons at absolute coordi-
nates in the canvas, and computing the scrollable size using concepts outlined in the
prior section. Both horizontal and vertical scrollbars allow us to move through the
canvas of image buttons freely, regardless of how many there may be.
Example 9-15. PP4E\Gui\PIL\viewer_thumbs_scrolled.py
"""
image viewer extension: uses fixed-size thumbnail buttons for uniform layout, and
adds scrolling for large image sets by displaying thumbs in a canvas widget with
scroll bars; requires PIL to view image formats such as JPEG, and reuses thumbs
maker and single photo viewer in viewer_thumbs.py; caveat/to do: this could also
scroll popped-up images that are too large for the screen, and are cropped on
Windows as is; see PyPhoto later in Chapter 11 for a much more complete version;
"""
import sys, math
from tkinter import *
from PIL.ImageTk import PhotoImage
from viewer_thumbs import makeThumbs, ViewOne
def viewer(imgdir, kind=Toplevel, numcols=None, height=300, width=300):
"""
use fixed-size buttons, scrollable canvas;
sets scrollable (full) size, and places thumbs at absolute x,y
coordinates in canvas; caveat: assumes all thumbs are same size
"""
win = kind()
win.title('Simple viewer: ' + imgdir)
quit = Button(win, text='Quit', command=win.quit, bg='beige')
quit.pack(side=BOTTOM, fill=X)
canvas = Canvas(win, borderwidth=0)
vbar = Scrollbar(win)
hbar = Scrollbar(win, orient='horizontal')
vbar.pack(side=RIGHT, fill=Y) # pack canvas after bars
Canvas | 557