I’m trying to use images from icrawler to populate buttons on tkinter

I’m a newbie at coding in general. I’m trying to create a program that downloads the first 20 google images and puts them on buttons using tkinter. I’ve managed to create the grid and the buttons. If I put the ‘create_grid’ code outside of the function, the last image appears, but not the rest of them. I assume it has something to do with garbage collection, but I’ve been banging my head with this all week. Any idea on how it make it work would be more than appreciated.

    from tkinter import *
    from PIL import ImageTk,Image
    from icrawler.builtin import GoogleImageCrawler
    import time
    import os
    
    fileLocation = "C:\Python projects\tkinter\images\"
    fileList = os.listdir(fileLocation)
    root = Tk()
    root.title("Product image search")
    root.iconbitmap("favicon.ico")
    e = Entry(root, borderwidth=5)
    e.grid(row=0, column=0, columnspan=5)
    
    
    length  = len(fileList)
    i = 0
    rows = 0
    cols = 1    
    button_list = []
    
    
    def create_grid():
        global i, rows, cols 
        while i < length:
        
            # Define image boxes
    
            img_path = (f"{fileLocation}{fileList[i]}")
            img_raw= Image.open(img_path)   
            print(img_path)
            img_resize = img_raw.resize((200, 200), Image.ANTIALIAS)    
            img_1 = ImageTk.PhotoImage(img_resize)  
            img_btn = Button(image=img_1)   
            img_btn.grid(row= rows, column= cols)
            button_list.append(img_btn)
            
            rows += 1
            
            if rows == 5:       
                rows = 0
                cols += 1
            i += 1
    
    
    def crawlerAction():
        google_crawler = GoogleImageCrawler(
            parser_threads=2,
            downloader_threads=4,
            storage={'root_dir': 'images'})
    
    
        google_crawler.crawl(keyword=(e.get()), max_num=20)
        time.sleep(5)
        create_grid()
    
    search_btn = Button(text="検査", command=crawlerAction)
    search_btn.grid(row=0, column=3)
    
    root.mainloop()

Answer

You need to call os.listdir inside the function. If you call it before, your images haven’t been downloaded yet, so the folder is empty. Moving fileLocation, fileList and length inside the function should fix it.

root = Tk()
root.title("Product image search")
root.iconbitmap("favicon.ico")
e = Entry(root, borderwidth=5)
e.grid(row=0, column=0, columnspan=5)



i = 0
rows = 0
cols = 1    
button_list = []


def create_grid():
    global i, rows, cols
    fileLocation = "C:\Python projects\tkinter\images\"
    fileList = os.listdir(fileLocation)
    length  = len(fileList)
    while i < length:
    
        # Define image boxes

        img_path = (f"{fileLocation}{fileList[i]}")
        img_raw= Image.open(img_path)   
        print(img_path)
        img_resize = img_raw.resize((200, 200), Image.ANTIALIAS)    
        img_1 = ImageTk.PhotoImage(img_resize)  
        img_btn = Button(image=img_1)   
        img_btn.grid(row= rows, column= cols)
        button_list.append(img_btn)
        
        rows += 1
        
        if rows == 5:       
            rows = 0
            cols += 1
        i += 1

If your images still do not show up, they may be getting garbage collected. In that case, add img_btn.image = img_1 on the line after img_btn = Button(.... By creating a reference to the PhotoImage object, it won’t get garbage collected.