Search code examples
pythontkintertkinter-entry

No input possible after tk


If have this piece of code:

import Tkinter as tk
import tkFileDialog

menu = tk.Tk()
res = tkFileDialog.askopenfilename() # un-/comment this line
label = tk.Label(None, text="abc")
label.grid(row=0, column=0, sticky=tk.W)
entry = tk.Entry(None)
entry.grid(row=0, column=1, sticky=tk.EW)

res = menu.mainloop()

Note: the askopenfilename is just a dummy input. So Just close it to get to the (now blocked) main window of TK.

When I comment the askopenfilename everything works fine. But with the it, I can not enter data in the entry.

This only happens with Windoze environments. The askopenfilename seems to steal the focus for the main TK window. After clicking a totally different window and back again in the TK window, input is possible.


Solution

  • I've seen reports of this before, I think it's a known bug on windows. You need to let mainloop start before you open a dialog.

    If you want the dialog to appear when the app first starts up you can use after or after_idle to have it run after mainloop starts up.

    For example:

    menu = tk.Tk()
    ...
    def on_startup():
        res = tkFileDialog.askopenfilename()
    
    menu.after_idle(on_startup)
    menu.mainloop()
    

    If you don't want any other GUI code to execute until after the dialog, move all your code except for the creation of the root window and call to mainloop into on_startup or some other function.

    For example:

    def main(filename):
        label = tk.Label(None, text="abc")
        label.grid(row=0, column=0, sticky=tk.W)
        entry = tk.Entry(None)
        entry.grid(row=0, column=1, sticky=tk.EW)
    
    def on_startup():
        res = tkFileDialog.askopenfilename()
        main(filename)
    
    root = Tk()
    root.after_idle(on_startup)