I'm writing a small program in python that consists of a backend that processes some data, and a frontend using tkinter. To process the data, the backend may sometimes need userinput. My idea was to call the backend data processing function from the frontend, giving it as input a function from the frontend that opens a pop-up window asking for input and returns it once the user clicks a "Submit" button. However, I'm having trouble returning only once the button is clicked. The following is a dummy example of what I've tried.
import tkinter as tk
def backend_function(func):
#some data processing function
user_input = func()
print(user_input)
def pop_up(master):
#opens pop-up window asking for inout and return the input once "submit" is clicked
top = tk.Toplevel(master=master)
entry = tk.Entry(top)
entry.pack()
submit = tk.Button(top, text='Submit', command = None)
submit.pack()
return entry.get() #should return only on click...
root = tk.Tk()
#start data processing from interface
call_backend = tk.Button(root, text = 'Backend',
command = lambda: backend_function(lambda: pop_up(master=root)))
call_backend.pack()
root.mainloop()
The problem is, that I'd like to have the return statement of pop_up as a command of the button, which is not possible. I thought about setting a nested function as command of the button, but then again, the nested function can't give a return value of the original function either.
Is it even possible to solve the problem this way, or would I have to delve deeper into tkinter defining some new Toplevel class or what not? Still fairly new to tkinter. Thanks!
You can use top.wait_window()
to wait for the closing of the toplevel window and then get the input value via a StringVar
associated with entry
:
def pop_up(master):
#opens pop-up window asking for inout and return the input once "submit" is clicked
top = tk.Toplevel(master=master)
my_var = tk.StringVar() # used to return the input value
entry = tk.Entry(top, textvariable=my_var)
entry.pack()
submit = tk.Button(top, text='Submit', command=top.destroy) # close top when clicked
submit.pack()
top.grab_set() # grab the input focus
top.wait_window() # wait for the window close
# use my_var.get() instead of entry.get() because entry is destroyed
return my_var.get() #should return only on click...
If you just want to open a dialog to input something, simply use simpledialog.askstring()
:
...
from tkinter.simpledialog import askstring
...
def pop_up(master):
return askstring(title="Input", prompt="Enter something", parent=master)