I have a system, where there is a popup window that requests input from the user, and then returns that input to the main body of code for processing. I have the window popping up correctly, using transient to ensure it stays on top, however I cannot find a way to make the window return data to the place it was called from. Current:
from tkinter import *
class LoginWindow(object):
def __init__(self, parent):
self.parent=parent
self.data=None #Default value, to say its not been set yet
self.root=Toplevel(self.parent)
self.root.transient(self.parent)
self.username=Entry(self.root)
self.password=Entry(self.root, show="*")
self.ok=Button(self.root, text="Continue", command=self.check_pass); self.ok.grid(row=5, column=2, sticky="ew")
self.cancel=Button(self.root, text="Cancel", command=self.cancel_pass); self.cancel.grid(row=5, column=1, sticky="ew")
def check_pass(self):
self.data=(self.username.get(), self.password.get())
self.root.quit()
def cancel_pass(self):
self.data=False
self.root.quit()
parent=Tk()
pass_window=LoginWindow(parent)
#....? how do I get pass_window.data from the window, considering it will only be defined
#to be something besides None once the user has clicked the continue button
I have tried loops to wait for the value of pass_window.data
to change from None
, however that leads to LoginWindow
not appearing, or the script locking up. Ideally I want to keep transient
there as it prevents the user clicking off the window, but I know that transient
is the cause of the window not appearing (works fine without)
Any ideas?
You're kinda asking two questions in one, one about passing a value from a popup window to the main window, one about transient
not working correctly. My answer to the first question is below, for the second one I don't really know what the problem you're experiencing is. As far as I can see, transient
works as intended the way you use it.
You can use wait_window
to let the Tkinter mainloop wait for a window to close before continuing. If you place the popup window creation in a function that is called after the parent's mainloop is started, you can use pass_window.wait_window()
to "pause" further execution of the function before continuing with executing rest of the lines. After the window has closed, the desired data can then be found in pass_window.data
class LoginWindow(object):
def __init__(self, parent):
self.parent=parent
self.data=None #Default value, to say its not been set yet
self.root=Toplevel(self.parent)
self.root.transient(self.parent)
self.username=Entry(self.root); self.username.pack()
self.password=Entry(self.root, show="*"); self.password.pack()
self.ok=Button(self.root, text="Continue", command=self.check_pass); self.ok.pack()
self.cancel=Button(self.root, text="Cancel", command=self.cancel_pass); self.cancel.pack()
def check_pass(self):
self.data=(self.username.get(), self.password.get())
self.root.destroy()
def cancel_pass(self):
self.data=False
self.root.destroy()
def popup():
pass_window=LoginWindow(parent)
pass_window.parent.wait_window(pass_window.root)
print(pass_window.data)
parent=Tk()
Button(parent, text='popup', command=popup).pack()
parent.mainloop()