How to get the value from tkinter toplevel in side a 0 attribute function? How to get the value from tkinter toplevel in side a 0 attribute function? tkinter tkinter

How to get the value from tkinter toplevel in side a 0 attribute function?


The short answer to your question is that you can use wait_window() to wait for the window to be dismissed, and then you can return whatever you want from your function. You would then hook up your "Task complete" button to simply destroy the window.

You have to be very careful here -- wait_window creates a new, nested event loop. Most often this is done in conjunction with a window grab to prevent events in other windows from being processed. When you do this, you are creating a modal dialog.

Here's a working example; I had to tweak your code a little, and I took the liberty of removing some unnecessary variables (such as references to the radiobuttons, since you never do anything with the references)

import Tkinter as tk # python 2.7 class Example(tk.Frame):    def __init__(self, *args, **kwargs):        tk.Frame.__init__(self, *args, **kwargs)        button = tk.Button(self, text="Open window", command=self.on_button)        button.pack()    def on_button(self):        var, note = Update()        a = var.get()        b = note.get()        print "a: '%s' b: '%s'" % (a,b)def Update():    Up = tk.Toplevel()    Up.title("Update")    tk.Label(Up, text ="Update", font=('Times', 20)).grid(row=0)    var = tk.IntVar()    tk.Radiobutton(Up, text="Fully", variable=var, value=1).grid(row=2, sticky="w")    tk.Radiobutton(Up, text="Partly", variable=var, value=2).grid(row=3, sticky="w")    tk.Radiobutton(Up, text="Un", variable=var, value=3).grid(row=4, sticky="w")    evar = tk.StringVar()    note = tk.Entry(Up, width=30, font=('Arial', 12,), textvariable=evar)    note.grid(row=6)    Button = tk.Button(Up, text ="Task Complete and Send Invoice", command = Up.destroy).grid(row =7)    Up.wait_window()    print "done waiting..."    return (var, evar)if __name__ == "__main__":    root = tk.Tk()    Example(root).pack(side="top", fill="both", expand=True)    root.mainloop()

To see why you must be careful when using this function, try the following scenarios:

  1. click on the "Open Window" button, fill in the form and click on the "Task Complete" button. Notice that it probably works the way you expect (it prints to stdout, so make sure you're running from a console window)

  2. click on the "Open Window" button, then click on it again. You now have two windows. Fill in the second window, click on "Task Complete" and notice it works like you expect. Now fill in the first window and click on "Task Complete" and it still works just fine. In both cases it prints the correct values to the screen when you click the button.

  3. click on the "Open Window" button, then click on it again. You now have two windows. This time, fill in the first window and click "Task Complete". Notice that it does not print the results to the screen. This is because the nested event loop of the first window can't complete until the nested event loop of the third window completes. Fill in the form of this second window and click on "Task Complete" and you'll see that the two nested event loops unwind, but not in the order that you clicked on "Task Complete" but rather in the order that the windows were created.

This is why you need to be careful when using wait_window - you should prevent this recursive nesting of event loops or your GUI may not behave the way you expect.