3

I have created a dialog, everything is fine, except when I have in some way to return the result. The problem of getting a user's choice from a dialog is that we don't know when he/she will click for example ok or cancel.

I have tried to see how standard dialogs are implemented, in order to do something similar. I have notice that all functions that open a dialog, like askdirectory or askopenfile call Dialog's method show. So I decided to have a look at this method, but I am not exactly seeing the relationship between this method and the fact of being able to wait for the user's answer/action to return some value.

How exactly can we return some values from a dialog?

nbro
  • 15,395
  • 32
  • 113
  • 196

1 Answers1

9

The basic mechanism is to have a function that create the window (or causes it to be visible), waits for it to be destroyed (using wait_window), fetches the value from the window, and then returns the value. You'll want to use a StringVar or something similar which doesn't get destroyed along with the window.

Here's an example of a dialog that asks you to type in a string. You can dismiss the dialog by pressing the return key, clicking on the "OK" button, or killing the window with the window manager button. When you dismiss the dialog, the string will be displayed in the main window.

import Tkinter as tk

class CustomDialog(tk.Toplevel):
    def __init__(self, parent, prompt):
        tk.Toplevel.__init__(self, parent)

        self.var = tk.StringVar()

        self.label = tk.Label(self, text=prompt)
        self.entry = tk.Entry(self, textvariable=self.var)
        self.ok_button = tk.Button(self, text="OK", command=self.on_ok)

        self.label.pack(side="top", fill="x")
        self.entry.pack(side="top", fill="x")
        self.ok_button.pack(side="right")

        self.entry.bind("<Return>", self.on_ok)

    def on_ok(self, event=None):
        self.destroy()

    def show(self):
        self.wm_deiconify()
        self.entry.focus_force()
        self.wait_window()
        return self.var.get()

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.button = tk.Button(self, text="Get Input", command=self.on_button)
        self.label = tk.Label(self, text="", width=20)
        self.button.pack(padx=8, pady=8)
        self.label.pack(side="bottom", fill="both", expand=True)

    def on_button(self):
        string = CustomDialog(self, "Enter something:").show()
        self.label.configure(text="You entered:\n" + string)


if __name__ == "__main__":
    root = tk.Tk()
    root.wm_geometry("400x200")
    Example(root).pack(fill="both", expand=True)
    root.mainloop()

Screenshots:

Entering input

You entered: Hello, world!

Stevoisiak
  • 23,794
  • 27
  • 122
  • 225
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685