I’m working on a little gui app that will eventually (hopefully) add a watermark to a photo. But right now I’m focused on just messing around with tkinter and trying to get some basic functionality down.
I’ve managed to display an image. Now I want to change the image to whatever is in the Entry widget (ideally, the user would put an absolute path to an image and nothing else). When I click the button, it makes the image disappear. I made it also create a plain text label to see if that would show up. It did.
Okay, time to break out the big guns. Add a breakpoint. py -m pdb main.py
. it works. wtf?
def change_image():
new_image = Image.open(image_path.get()).resize((480, 270))
new_tk_image = ImageTk.PhotoImage(new_image)
test_image_label.configure(image=new_tk_image)
breakpoint()
with the breakpoint, the button that calls change_image works as expected. But without the breakpoint, it just makes the original image disappear. Please help me understand what is happening!
edit: all the code
import io
import tkinter as tk
from pathlib import Path
from tkinter import ttk
from PIL import ImageTk
from PIL import Image
from LocalImage import Localimage
from Layout import Layout
class State:
def __init__(self) -> None:
self.chosen_image_path = ""
def update_image_path(self):
self.chosen_image_path = image_path.get()
def change_image():
new_image = Image.open(image_path.get()).resize((480, 270))
new_tk_image = ImageTk.PhotoImage(new_image)
test_image_label.configure(image=new_tk_image)
breakpoint()
TEST_PHOTO_PATH = "/home/me/bg/space.png"
PIL_TEST_PHOTO_PATH = "/home/me/bg/cyberpunkcity.jpg"
pil_test_img = Image.open(PIL_TEST_PHOTO_PATH).resize((480,270))
# why does the resize method call behave differently when i inline it
# instead of doing pil_test_img.resize() on a separate line?
root = tk.Tk()
root.title("Watermark Me")
mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky="NWES")
layout = Layout(mainframe)
image_path = tk.StringVar()
tk_image = ImageTk.PhotoImage(pil_test_img)
test_image_label = ttk.Label(image=tk_image)
entry_label = ttk.Label(mainframe, text="Choose an image to watermark:")
image_path_entry = ttk.Entry(mainframe, textvariable=image_path)
select_button = ttk.Button(mainframe, text="Select",
command=change_image)
hide_button = ttk.Button(mainframe, text="Hide", command= lambda x=test_image_label:
layout.hide_image(x))
test_text_label = ttk.Label(mainframe, text="here i am")
empty_label = ttk.Label(mainframe, text="")
for child in mainframe.winfo_children():
child.grid_configure(padx=5, pady=5)
entry_label.grid(column=0, row=0)
image_path_entry.grid(column=1, row=0)
hide_button.grid(column=0, row=3)
select_button.grid(column=0, row=4)
test_image_label.grid(column=0, row=5)
empty_label.grid(column=0, row=6)
image_path_entry.insert(0,TEST_PHOTO_PATH)
image_path_entry.focus()
breakpoint()
root.mainloop()
That was it! I moved the two lines above the
.configure()
call into the outermost scope, and it works now.Should probably just bite the bullet and OOP it out. I was putting that off until I figured out how I wanted the whole thing to work, but it will probably be easier to just do it and change it as I go instead of trying to raw dog it for too long.
Splendid! Glad I was able to help. I know I’ve hit this same problem in some other context? Maybe it was font-handling or something? And it was the same thing. You change the font and it disappears. So I got into the habit of subclassing some higher level object like
Frame
or whatever and making all these things into methods that storeself.current_font
etc. to make sure I don’t let that last reference go bye-bye!