I want to display a lot of thumbnails and be able to do different operations on them, depending on the content of the thumbnail. For this I took the example from Adding a scrollbar to a group of widgets in Tkinter and put labels in the first column and images in the second column of the embedded grid. As a sample thumbnail you can download this image and rename it to 160x120.jpg
.
import Tkinter as tk
from PIL import Image, ImageTk
class Example(tk.Frame):
def __init__(self, root):
tk.Frame.__init__(self, root)
self.canvas = tk.Canvas(root, borderwidth=0, background="#ffffff")
self.frame = tk.Frame(self.canvas, background="#ffffff")
self.vsb = tk.Scrollbar(root, orient="vertical", command=self.canvas.yview)
self.canvas.configure(yscrollcommand=self.vsb.set)
self.vsb.pack(side="right", fill="y")
self.canvas.pack(side="left", fill="both", expand=True)
self.canvas.create_window((4,4), window=self.frame, anchor="nw",
tags="self.frame")
self.frame.bind("<Configure>", self.OnFrameConfigure)
self.photos = []
self.imgs = []
self.images = []
self.lbls = []
self.populate()
def populate(self):
'''Put in some fake data'''
# n_thumbs = 100 : As expected, one label and one image per row.
# n_thumbs = 300 : Images are only displayed up to the 278th.
# n_thumbs = 600 : Just 63 images are displayed. Two labels per row.
n_thumbs = 100
for i in range(n_thumbs):
lbl = tk.Label(self.frame, text="img " + str(i), width=10)
lbl.grid(row=i, column=0)
photo = Image.open("160x120.jpg")
img = ImageTk.PhotoImage(photo)
image = tk.Label(self.frame, image=img)
image.grid(row=i, column=1)
self.lbls.append(lbl)
self.photos.append(photo)
self.images.append(image)
self.imgs.append(img)
def OnFrameConfigure(self, event):
'''Reset the scroll region to encompass the inner frame'''
self.canvas.configure(scrollregion=self.canvas.bbox("all"))
if __name__ == "__main__":
root=tk.Tk()
Example(root).pack(side="top", fill="both", expand=True)
root.mainloop()
Now, if you set n_thumbs = 100
, everything works as expected, i.e. there is one label and one image per row.
If you set n_thumbs = 300
, the list abruptly ends with the 278th image.
If you set n_thumbs = 600
, only 63 images are shown, but you can still scroll down beyond the last image. Furthermore, suddenly there are two labels in each row.
How can these effects be explained? How can I display more than 300 images in a grid using Tkinter?