Using Tkinter's askopenfilename() with matplotlib not working in GUI

Question:

I am creating a GUI for my program and I would like the first step be that the user selects an image, which is then displayed on the GUI. The program works if I put a file path directly into it, but when I use askopenfilename(), the other buttons and places for user input no longer work. I had a full working GUI before askopenfilename(). Here is the part of the code that’s giving me trouble:

from tkinter import *
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.lines import Line2D
from PIL import Image
from tkinter.filedialog import askopenfilename
from PIL import ImageTk
from tkinter import filedialog

window = Tk()
window.geometry('600x600')

#since I added askopenfilename() I can no longer type in these boxes
e = Entry(window)
e.pack()
ee = Entry(window)
ee.pack()

#path = 'image.png'   #this was working fine
path = filedialog.askopenfilename()
img_arr = plt.imread(path)
img = Image.open(path)

I think it’s an issue with matplotlib trying to read it, because the image opens, but I can’t do anything with it. I believe the main issue is that I have created 2 dialog boxes that I can no longer type in. Has anyone ever had this issue?

Asked By: lordclyborne

||

Answers:

askopenfilename starts tk.mainloop early, if it wasn’t already running, which messes up any created Tk object.

the solution to this is to either

  1. create a hidden Tk object then call askopenfilename,then destroy it before creating your application’s main Tk object.
  2. or use askopenfilename after you start your application’s mainloop, you can delay the calling of a function using window.after or by tying the logic to a button on the screen that the user presses.
import tkinter as tk
from tkinter import filedialog

dummy_window = tk.Tk()
dummy_window.withdraw()
path = filedialog.askopenfilename()
dummy_window.destroy()

window = tk.Tk()
entry = tk.Entry(master=window)
entry.insert("0", path)
entry.pack()
window.mainloop()
Answered By: Ahmed AEK