I want to make a GUI where I have two buttons: from one button I can select an image and from the other button I can show the image with cv2.imshow
. I want to use cv2.imshow
because later I want to process the image with cv2
. Here is my code:
import tkinter as tk
import tkinter.filedialog as fd
import cv2
def select(label):
filepath = fd.askopenfilename()
text = "Selected image: {}".format(filepath)
label.config(text=text)
return filepath
def show_image(image_path):
image = cv2.imread(image_path)
cv2.imshow("Image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
root = tk.Tk()
root.geometry("600x400")
frame = tk.Frame(root)
frame.pack()
label_frame = tk.LabelFrame(frame)
label_frame.grid()
label = tk.Label(frame, text="Label")
label.grid()
func1 = lambda: select(label)
button1 = tk.Button(frame, text="select", command=func1)
button1.grid()
func2 = lambda: show_image(func1)
button2 = tk.Button(frame, text="show", command=func2)
button2.grid()
root.mainloop()
I have tried many things, for example change command=func2
to command=show_image
, but nothing seems to work. I think that the image path variable in show_image(image_path)
is a function because it is defined with lambda. Could I somehow convert the output to a string, so that the function works properly? I need to use lambda because I need to pass arguments to button command.
It looks like you're passing the image_path
to the show_image
function through your func2
lambda. When you set func2 = lambda: show_image(func1)
, calling func1
inside show_image
doesn't return the filepath
string as you might expect. Instead, it calls select(label)
which returns the filepath
, but then you're not using this returned filepath
correctly as an argument to show_image. You're essentially trying to show func1
itself, not its result.
To fix this, you can modify your approach to ensure that func2
receives the filepath
as a string from select(label)
and then passes it correctly to show_image
. You can try something like this:
import tkinter as tk
import tkinter.filedialog as fd
import cv2
def select(label):
filepath = fd.askopenfilename()
text = "Selected image: {}".format(filepath)
label.config(text=text)
return filepath
def show_image(image_path):
image = cv2.imread(image_path)
cv2.imshow("Image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
root = tk.Tk()
root.geometry("600x400")
frame = tk.Frame(root)
frame.pack()
label_frame = tk.LabelFrame(frame)
label_frame.grid()
label = tk.Label(frame, text="Label")
label.grid()
# Use a global variable to store the selected filepath
selected_filepath = None
def update_filepath():
global selected_filepath
selected_filepath = select(label)
def display_image():
global selected_filepath
if selected_filepath:
show_image(selected_filepath)
button1 = tk.Button(frame, text="select", command=update_filepath)
button1.grid()
button2 = tk.Button(frame, text="show", command=display_image)
button2.grid()
root.mainloop()