Returning a value from a tkinter popup

I need to ask the user for an arbitrarily long list of key-folder pairs, so I use Toplevel to create a popup where i lay out a growable list pairs of custom buttons (one to bind the key and one to select the folder).
I’d then like to wait til the user closes the window and read the status on the widgets, but wait_window() waits until it’s too late and the widgets are already deconstructed

Is there an easy way to do something like popup.wait_window() and access the attributes in the widgets?

EDIT: My ideal solution would be a single function like popup_bindings() that creates the popup and returns the value, so I could assign a variable directly with bindings = popup_bindings()
EDIT 2: Right now I’m focusing on the popup return value aspect, I will build the actual dialog after I’ve figured that out

I’ve come up with a relatively inelegant solution: I use a list as a mutable “callback” variable that’s preserved when the object is destroyed, and I use the protocol method to ensure that the value is saved when the window is closed.

import tkinter as tk

class EntryPopup(tk.Frame):
    def __init__(self,out_value:list,parent,*args,**kwargs):
        self.value = out_value
        super().__init__(master=parent,*args,**kwargs)
        self.toplevel = tk.Toplevel(parent)
        self.entry = tk.Entry(master=self.toplevel)
        self.entry.pack()
        tk.Button(text="Quit",master=self.toplevel,command=self.save_and_destroy).pack()
        self.toplevel.protocol("WM_DELETE_WINDOW",self.save_and_destroy)
    def save_value(self):
        self.value.append(self.entry.get())
    def save_and_destroy(self):
        self.save_value()
        self.toplevel.destroy()

##############

def show_popup() -> str:
    val = []
    x = EntryPopup(val,window)
    x.toplevel.wait_window()
    return val[-1]

def set_label():
    lab["text"] = show_popup()

##############

window = tk.Tk()
lab = tk.Label(text="Your text here")
lab.pack()
tk.Button(command=set_label,text="Set label text").pack()

window.mainloop()
1 Like

Thank you for sharing this. I’m sure that as I learn and develop my Tk interface skills, your solution will come in handy.

Enjoy your day.

1 Like