Skip to content
Advertisement

Transient input window

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 ontop, 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.checkPass); self.ok.grid(row=5, column=2, sticky="ew")
        self.cancel=Button(self.root, text="Cancel", command=self.cancelPass); self.cancel.grid(row=5, column=1, sticky="ew")


    def checkPass(self):
        self.data=(self.username.get(), self.password.get())
        self.root.quit()

    def cancelPass(self):
        self.data=False
        self.root.quit()

parent=Tk()
passWindow=loginwindow(parent)
#....? how do I get passWindow.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 passWindow.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?

Advertisement

Answer

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 passWindow.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 passWindow.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.checkPass); self.ok.pack()
        self.cancel=Button(self.root, text="Cancel", command=self.cancelPass); self.cancel.pack()

    def checkPass(self):
        self.data=(self.username.get(), self.password.get())
        self.root.destroy()

    def cancelPass(self):
        self.data=False
        self.root.destroy()


def popup():
    passWindow=loginwindow(parent)
    passWindow.parent.wait_window(passWindow.root)
    print passWindow.data

parent=Tk()
Button(parent, text='popup', command=popup).pack()
parent.mainloop()
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement