Search code examples
pythoncanvastkinterpython-imaging-libraryopenfiledialog

How to open the filedialog after pressing the button?


I would like to open the filedialog after pressing a button. Then I could choose an image and display it on a canvas. (My goal is to do a very simple image editor) Unfortunately, the filedialog open up automatically when I start the program. Is there a way for example to do something like this:

  • press a button to open the filedialog

  • choose an image

  • display the image on the canvas

Here is my code that I've done so far

from tkinter import *
from PIL import Image, ImageTk
from tkinter import filedialog

root = Tk()   
#function to select my image by using the filedialog
def select_image(): 
    file_path = filedialog.askopenfilename()
    return Image.open(file_path)

#button to press to open filedialog
select = Button(root, text="select an image", command=select_image)
select.pack()

#the canvas where the image will be display
canvas = Canvas(root, width= 400, height=400, bg="grey")
canvas.pack()

image_tk = ImageTk.PhotoImage(select_image())
canvas.create_image(200,200, image= image_tk)   
root.mainloop()

Solution

  • The filedialog opens because of this line:

    image_tk = ImageTk.PhotoImage(select_image())

    My Solution is:

    from tkinter import Tk, filedialog, Frame, Button, Canvas
    from PIL import Image, ImageTk
    
    class Gui:
        def __init__(self, master):
            self.master = master
            self.create_widgets()
    
        def create_widgets(self):
            self.select = Button(self.master, text="select an image", command=self.select_image)
            self.select.pack()
            self.canvas = Canvas(self.master, width= 400, height=400, bg="grey")
            self.canvas.pack()
    
        def select_image(self): 
            file_path = filedialog.askopenfilename()
            des = Image.open(file_path)
            bg_image = ImageTk.PhotoImage(des)
            self.canvas.bg_image = bg_image
            self.canvas.create_image(200,200, image=self.canvas.bg_image)
    
    if __name__ == "__main__":  
        root = Tk()
        my_gui = Gui(root)
        root.mainloop()