Tkinter creating new window from a separate class results in widgets getting lost

This is based off of a simplified version of my actual code:

In file main.py, I create a new window with a placeholder widget and then call my second script backgroundProvider.py which should open a second window. This initially works fine, until the window.mainloop() is called, at which moment the background image of the second window disappears and it becomes an empty window. This is noticable by the image shortly showing. If one adds a wait before the window.mainloop(), the image stays up longer.

Any ideas what could cause this?

main.py:

import tkinter as tk
from backgroundProvider import BackgroundProdiver

window = tk.Tk()

somefield = tk.Entry()
somefield.pack()

BackgroundProdiver.showPIL(2, tk)

window.mainloop()

backgroundProvider.py:

from PIL import Image, ImageTk
import time

class BackgroundProdiver:
    def showPIL(index, tk):
        root = tk.Toplevel()

        path = "./backgrounds/"
        pilImage = Image.open(path + "film" + str(index) + ".png")

        w, h = 1920, 1200
        canvas = tk.Canvas(root,width=w,height=h, highlightthickness=0)
        root.overrideredirect(1)
        root.geometry(f"{w}x{h}-{w}+0")
        root.focus_set()
        canvas.pack(fill="both")
        canvas.configure(background='black')
        imgWidth, imgHeight = pilImage.size
        ratio = min(w/imgWidth, h/imgHeight)
        imgWidth = int(imgWidth*ratio)
        imgHeight = int(imgHeight*ratio)
        pilImage = pilImage.resize((imgWidth,imgHeight), Image.ANTIALIAS)   
        image = ImageTk.PhotoImage(pilImage)
        imagesprite = canvas.create_image(w/2,h/2,image=image)
        root.update_idletasks()
        root.update()

Solution 1:

Without delving into your code, my quick thought is garbage collection... You have to permanently store a handle to an image (and sometimes other resources, as well) so that it doesn't get collected. Something as simple as:

root.images = [image, pilImage]

right before the root.update_idletasks() call may suffice.