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.