I created a function called "brewerInfo" which is supposed to ask for number of brewers, get user input(entry1), and then after submitting the button(button10) it will trigger the callback function "return_value" which is supposed to keep the entry value inside a global variable called val
. I want the "brewerInfo" function to return that val(user input/entry) so that way I can call "brewerInfo" function every time, I need to get a user input and store that value for later use outside of the function.
It seems Tkinter can only print the val
INSIDE the return_value function but I can't seem to call the value outside of it, let alone return that value.
I really need to re-use this function and have it return the value so I can use that value in other functions where I call brewerInfo. Is there any way to work around this?
Here's my code:
from tkinter import *
from tkinter import messagebox
# setting root window:
root = Tk()
root.title("Creator.py GUI")
root.config(bg="#17173c")
root.geometry("800x400")
#global val
val = ''
def brewerInfo():
global val
#Creates a new Tkinter window popup
new_window = Toplevel(root)
new_window.geometry("400x60")
new_window.title("Brewer Info")
new_window.config(bg="#17173c")
#Label text
label2 = Label(new_window, text="Number of brewers? (1-4): ")
label2.grid(row=0, column=0)
#return_value is a callback function that gets called after submitting the button
#return_value gets the entry input
def return_value():
global val
val = entry1.get()
#prompts an entry
entry1 = Entry(new_window)
entry1.grid(row=0, column=1)
#submit the button and call return_value as callback function to get the entry value
button10 = Button(new_window, text="Ok", width = 10, font="System 20", bg="green", fg="black", activebackground="black", activeforeground="red", borderwidth=5, cursor="hand2", highlightthickness=0, highlightcolor="black", highlightbackground="black", command=lambda: [return_value(), new_window.destroy()])
button10.grid(row=1, column=0)
#return return_value()
return val
#print(val) #doesnt work :(
#print("test if print works!") #works
#brewerInfo()
#print(val)
print(brewerInfo()) #print the return val
#IGNORE FOR NOW!!!!!!!!!
#button1 calls callback function brewerInfo
button1 = Button(root, text="Enter brewer INFO", width = 40, font="System 20", bg="red", fg="black", activebackground="black", activeforeground="red", borderwidth=5, cursor="hand2", highlightthickness=0, highlightcolor="black", highlightbackground="black", command= brewerInfo)
button1.pack()
# window in mainloop:
root.mainloop()
CodePudding user response:
If I understand you correctly, you want the code inside the function to pause until the user has interacted with the dialog. You can do this in a couple of different ways. You can either wait for the window to be destroyed, or wait until a given tkinter variable is set.
In your case, I recommend waiting until the window is destroyed. You do that with the wait_window
method. You will also want to associate a variable with the entry so that you can retrieve the value once the window has been destroyed. You won't be able to get it directly from the entry widget since it is destroyed when the window is destroyed.
Start by creating a StringVar
in your function, and associate that with your entry:
def brewerInfo():
var = StringVar()
...
entry1 = Entry(new_window, textvariable=var)
You've already set up the button to destroy the window, so all you need to do is wait for the window to be destroyed before returning the value:
def brewerInfo():
...
new_window.wait_window()
return var.get()
The wait_window
function will not return until new_window
has been destroyed. At that point you can get the value from the entry widget's StringVar
and then return it.
CodePudding user response:
Problem: When we call the function "brewerInfo" we have to wait to get the value from the user in entry1
(Entry).
Solution: So, we have to create a variable that helps us to wait, as long as that variable's value is not set. We created a var
variable and we set its value then only when we click button. and return that var
value.
Here's the code that implements above idea:
from tkinter import *
from tkinter import messagebox
root = Tk()
root.title("Creator.py GUI")
root.config(bg="#17173c")
root.geometry("800x400")
var = StringVar()
def brewerInfo(v=None):
new_window = Toplevel(root)
new_window.geometry("400x60")
new_window.title("Brewer Info")
new_window.config(bg="#17173c")
label2 = Label(new_window, text="Number of brewers? (1-4): ")
label2.grid(row=0, column=0)
def return_value():
var.set(entry1.get())
entry1 = Entry(new_window)
entry1.grid(row=0, column=1)
button10 = Button(new_window, text="Ok", width = 10, font="System 20", bg="green", fg="black", activebackground="black", activeforeground="red", borderwidth=5, cursor="hand2", highlightthickness=0, highlightcolor="black", highlightbackground="black", command=lambda: [return_value(), new_window.destroy()])
button10.grid(row=1, column=0)
new_window.wait_variable(var)
return var.get()
print(brewerInfo())
print(brewerInfo())
button1 = Button(root, text="Enter brewer INFO", width = 40, font="System 20", bg="red", fg="black", activebackground="black", activeforeground="red", borderwidth=5, cursor="hand2", highlightthickness=0, highlightcolor="black", highlightbackground="black", command= brewerInfo)
button1.pack()
root.mainloop()