I am trying to display the image passed from the MainFrame class to the CheckImageFrame class using the open_file and switch_frame methods. The object is a PIL PhotoImage/pyimage1 object.
I would like to understand why the Label with the "this is page one" text in the CheckImageFrame class will pack successfully, but the image will not.
Thanks in advance!
class WaterMarkGenerator(Tk):
def __init__(self):
Tk.__init__(self)
self._frame = None
self.switch_frame(MainFrame)
def switch_frame(self, frame_class, image=None):
# Destroys the current frame and replaces it with a new frame
new_frame = frame_class(self, image)
if self._frame is not None:
self._frame.destroy()
self._frame = new_frame
self._frame.pack()
class MainFrame(Frame):
def __init__(self, master, image):
Frame.__init__(self, master)
master.title("Watermark Generator")
Label(self, text="Please upload an image to watermark.").pack(pady=30)
Button(self, text='Upload a File', command=self.open_file).pack(expand=True)
def open_file(self):
self.file_path = filedialog.askopenfilename(
initialdir='/',
filetypes = (
('JPEG', '*.jpg'),
('PNF', '*.png'),
('All files', '*.*')
)
)
if self.file_path is not None:
try:
self.image = Image.open(self.file_path, mode='r')
self.tkinter_image = ImageTk.PhotoImage(self.image)
self.master.switch_frame(CheckImageFrame, image=self.tkinter_image)
except IOError:
pop_up_window()
class CheckImageFrame(Frame):
def __init__(self, master, image):
Frame.__init__(self, master)
Label(self, text="This is page one").pack(fill="x", pady=10)
Label(self, image=image).pack(fill='x', pady=50)
CodePudding user response:
You need to keep a reference to the image inside CheckImageFrame
so it is not collected by pythons garbage collector:
class CheckImageFrame(Frame):
def __init__(self, master, image):
Frame.__init__(self, master)
self.image = image # Keep reference
Label(self, text="This is page one").pack(fill="x", pady=10)
Label(self, image=image).pack(fill='x', pady=50)
I posted an answer even though this is a duplicate of the popular question, Why does Tkinter image not show up if created in a function?, because the implementation of that answer here could be tricky as the image seems to have reference in all the other classes except CheckImageFrame
.
Alternatively:
class WaterMarkGenerator(Tk):
def __init__(self):
...
...
def switch_frame(self, frame_class, image=None):
# Destroys the current frame and replaces it with a new frame
self.image = image # Hold a reference here itself
new_frame = frame_class(self, self.image)
...