Home > Software engineering >  Tkinter Entry textvariable not working after call to filedialog.askopenfilename
Tkinter Entry textvariable not working after call to filedialog.askopenfilename

Time:12-09

I'm using Tkinter to sometimes show a dialog in my application. I destroy and quit Tkinter (the toplevel widget) after the dialog got closed, since I don't know if another dialog will be opened later. However, if I call open_simple_value_dialog after open_file_dialog, open_simple_value_dialog does show an empty input field instead of the default value. If the value is changed and confirmed (click on Ok button), the result returned by the dialog is still the default value. open_simple_value_dialog does work as expected (shows default value and returns entered value) if open_file_dialog is not called before it. How to fix this issue?

def open_file_dialog():
    from tkinter import Tk, filedialog

    root = Tk()
    root.withdraw()
    file_name = filedialog.askopenfilename(title='Select input file')
    root.quit()
    return file_name


def open_simple_value_dialog(default_input_value):
    from tkinter import Tk, IntVar, StringVar, Label, Entry, Button

    root = Tk()

    if isinstance(default_input_value, str):
        input_variable = StringVar()
    elif isinstance(default_input_value, int):
        input_variable = IntVar()
    else:
        raise ValueError('expected string or integer as default input value')
    input_variable.set(default_input_value)
    result = None

    def close_dialog():
        nonlocal root
        root.destroy()
        root.quit()

    def on_ok():
        nonlocal result
        result = input_variable.get()
        close_dialog()

    Label(root, text='enter something').pack()
    Entry(root, textvariable=input_variable).pack()
    Button(root, text='Ok', command=on_ok).pack()
    Button(root, text='Cancel', command=close_dialog).pack()
    root.mainloop()
    return result


def main():
    print(open_file_dialog())
    print(open_simple_value_dialog('text'))
    value = open_simple_value_dialog(0)
    if isinstance(value, int):
        print(value)
    else:
        print('Dialog has been canceled')


if __name__ == '__main__':
    main()

CodePudding user response:

Since you use root.quit() inside open_file_dialog(), it just terminates the tkinter .mainloop(), but not the underlying TCL interpreter and tkinter widgets (see explanation in this question). So there is still issue on multiple instances of Tk() when open_simple_value_dialog() is executed.

You need to use root.destroy() inside open_file_dialog() instead.

  • Related