an introduction to tkinter c 1997 by fredrik lundh this applies to dialog askinteger askfloat and asktring fredrikpythonware com http www pythonware com this modules handles dialog boxes it contains the following public symbols simpledialog a simple but flexible modal dialog box dialog a base class for dialogs askinteger get an integer from the user askfloat get a float from the user askstring get a string from the user class to open dialogs this class is intended as a base class for custom dialogs initialize a dialog arguments parent a parent window the application window title the dialog title if the parent is not viewable don t make the child transient or else it would be opened withdrawn wait for window to appear on screen before calling grabset destroy the window self initialfocus none toplevel destroyself destroytemprootself master construction hooks def bodyself master pass def buttonboxself box frameself w buttonbox textok width10 commandself ok defaultactive w packsideleft padx5 pady5 w buttonbox textcancel width10 commandself cancel w packsideleft padx5 pady5 self bindreturn self ok self bindescape self cancel box pack standard button semantics def okself eventnone if not self validate self initialfocus focusset put focus back return self withdraw self updateidletasks try self apply finally self cancel def cancelself eventnone put focus back to the parent window if self parent is not none self parent focusset self destroy command hooks def validateself return 1 override def applyself pass override place a toplevel window at the center of parent or screen it is a python implementation of tk placewindow def placewindoww parentnone w wmwithdraw remain invisible while we figure out the geometry w updateidletasks actualize geometry information minwidth w winforeqwidth minheight w winforeqheight maxwidth w winfovrootwidth maxheight w winfovrootheight if parent is not none and parent winfoismapped x parent winforootx parent winfowidth minwidth 2 y parent winforooty parent winfoheight minheight 2 vrootx w winfovrootx vrooty w winfovrooty x minx vrootx maxwidth minwidth x maxx vrootx y miny vrooty maxheight minheight y maxy vrooty if w windowingsystem aqua avoid the native menu bar which sits on top of everything y maxy 22 else x w winfoscreenwidth minwidth 2 y w winfoscreenheight minheight 2 w wmmaxsizemaxwidth maxheight w wmgeometry dd x y w wmdeiconify become visible at the desired location def setupdialogw if w windowingsystem aqua w tk call tk unsupported macwindowstyle style w moveablemodal elif w windowingsystem x11 w wmattributestype dialog convenience dialogues class querydialogdialog def initself title prompt initialvaluenone minvalue none maxvalue none parent none self prompt prompt self minvalue minvalue self maxvalue maxvalue self initialvalue initialvalue dialog initself parent title def destroyself self entry none dialog destroyself def bodyself master w labelmaster textself prompt justifyleft w gridrow0 padx5 stickyw self entry entrymaster nameentry self entry gridrow1 padx5 stickywe if self initialvalue is not none self entry insert0 self initialvalue self entry selectrange0 end return self entry def validateself try result self getresult except valueerror messagebox showwarning illegal value self errormessage nplease try again parent self return 0 if self minvalue is not none and result self minvalue messagebox showwarning too small the allowed minimum value is s please try again self minvalue parent self return 0 if self maxvalue is not none and result self maxvalue messagebox showwarning too large the allowed maximum value is s please try again self maxvalue parent self return 0 self result result return 1 class queryintegerquerydialog errormessage not an integer def getresultself return self getintself entry get def askintegertitle prompt kw d queryintegertitle prompt kw return d result class queryfloatquerydialog errormessage not a floating point value def getresultself return self getdoubleself entry get def askfloattitle prompt kw d queryfloattitle prompt kw return d result class querystringquerydialog def initself args kw if show in kw self show kwshow del kwshow else self show none querydialog initself args kw def bodyself master entry querydialog bodyself master if self show is not none entry configureshowself show return entry def getresultself return self entry get def askstringtitle prompt kw d querystringtitle prompt kw return d result if name main def test root tk def doitrootroot d simpledialogroot textthis is a test dialog would this have been an actual dialog the buttons below would have been glowing in soft pink light n do you believe this buttonsyes no cancel default0 cancel2 titletest dialog printd go printaskintegerspam egg count initialvalue1212 printaskfloatspam egg weightnin tons minvalue1 maxvalue100 printaskstringspam egg label t buttonroot text test commanddoit t pack q buttonroot text quit commandt quit q pack t mainloop test an introduction to tkinter c 1997 by fredrik lundh this applies to dialog askinteger askfloat and asktring fredrik pythonware com http www pythonware com this modules handles dialog boxes it contains the following public symbols simpledialog a simple but flexible modal dialog box dialog a base class for dialogs askinteger get an integer from the user askfloat get a float from the user askstring get a string from the user class to open dialogs this class is intended as a base class for custom dialogs initialize a dialog arguments parent a parent window the application window title the dialog title remain invisible for now if the parent is not viewable don t make the child transient or else it would be opened withdrawn wait for window to appear on screen before calling grab_set destroy the window construction hooks create dialog body return widget that should have initial focus this method should be overridden and is called by the __init__ method add standard button box override if you do not want the standard buttons standard button semantics put focus back put focus back to the parent window command hooks validate the data this method is called automatically to validate the data before the dialog is destroyed by default it always validates ok override process the data this method is called automatically to process the data after the dialog is destroyed by default it does nothing override place a toplevel window at the center of parent or screen it is a python implementation of tk placewindow remain invisible while we figure out the geometry actualize geometry information avoid the native menu bar which sits on top of everything become visible at the desired location convenience dialogues get an integer from the user arguments title the dialog title prompt the label text kw see simpledialog class return value is an integer get a float from the user arguments title the dialog title prompt the label text kw see simpledialog class return value is a float get a string from the user arguments title the dialog title prompt the label text kw see simpledialog class return value is a string
from tkinter import *
from tkinter import _get_temp_root, _destroy_temp_root
from tkinter import messagebox


class SimpleDialog:

    def __init__(self, master,
                 text='', buttons=[], default=None, cancel=None,
                 title=None, class_=None):
        if class_:
            self.root = Toplevel(master, class_=class_)
        else:
            self.root = Toplevel(master)
        if title:
            self.root.title(title)
            self.root.iconname(title)

        _setup_dialog(self.root)

        self.message = Message(self.root, text=text, aspect=400)
        self.message.pack(expand=1, fill=BOTH)
        self.frame = Frame(self.root)
        self.frame.pack()
        self.num = default
        self.cancel = cancel
        self.default = default
        self.root.bind('<Return>', self.return_event)
        for num in range(len(buttons)):
            s = buttons[num]
            b = Button(self.frame, text=s,
                       command=(lambda self=self, num=num: self.done(num)))
            if num == default:
                b.config(relief=RIDGE, borderwidth=8)
            b.pack(side=LEFT, fill=BOTH, expand=1)
        self.root.protocol('WM_DELETE_WINDOW', self.wm_delete_window)
        self.root.transient(master)
        _place_window(self.root, master)

    def go(self):
        self.root.wait_visibility()
        self.root.grab_set()
        self.root.mainloop()
        self.root.destroy()
        return self.num

    def return_event(self, event):
        if self.default is None:
            self.root.bell()
        else:
            self.done(self.default)

    def wm_delete_window(self):
        if self.cancel is None:
            self.root.bell()
        else:
            self.done(self.cancel)

    def done(self, num):
        self.num = num
        self.root.quit()


class Dialog(Toplevel):

    

    def __init__(self, parent, title = None):
        
        master = parent
        if master is None:
            master = _get_temp_root()

        Toplevel.__init__(self, master)

        self.withdraw() 
        
        
        
        if parent is not None and parent.winfo_viewable():
            self.transient(parent)

        if title:
            self.title(title)

        _setup_dialog(self)

        self.parent = parent

        self.result = None

        body = Frame(self)
        self.initial_focus = self.body(body)
        body.pack(padx=5, pady=5)

        self.buttonbox()

        if self.initial_focus is None:
            self.initial_focus = self

        self.protocol("WM_DELETE_WINDOW", self.cancel)

        _place_window(self, parent)

        self.initial_focus.focus_set()

        
        self.wait_visibility()
        self.grab_set()
        self.wait_window(self)

    def destroy(self):
        
        self.initial_focus = None
        Toplevel.destroy(self)
        _destroy_temp_root(self.master)

    
    

    def body(self, master):
        
        pass

    def buttonbox(self):
        

        box = Frame(self)

        w = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE)
        w.pack(side=LEFT, padx=5, pady=5)
        w = Button(box, text="Cancel", width=10, command=self.cancel)
        w.pack(side=LEFT, padx=5, pady=5)

        self.bind("<Return>", self.ok)
        self.bind("<Escape>", self.cancel)

        box.pack()

    
    

    def ok(self, event=None):

        if not self.validate():
            self.initial_focus.focus_set() 
            return

        self.withdraw()
        self.update_idletasks()

        try:
            self.apply()
        finally:
            self.cancel()

    def cancel(self, event=None):

        
        if self.parent is not None:
            self.parent.focus_set()
        self.destroy()

    
    

    def validate(self):
        

        return 1 

    def apply(self):
        

        pass 




def _place_window(w, parent=None):
    w.wm_withdraw() 
    w.update_idletasks() 

    minwidth = w.winfo_reqwidth()
    minheight = w.winfo_reqheight()
    maxwidth = w.winfo_vrootwidth()
    maxheight = w.winfo_vrootheight()
    if parent is not None and parent.winfo_ismapped():
        x = parent.winfo_rootx() + (parent.winfo_width() - minwidth) // 2
        y = parent.winfo_rooty() + (parent.winfo_height() - minheight) // 2
        vrootx = w.winfo_vrootx()
        vrooty = w.winfo_vrooty()
        x = min(x, vrootx + maxwidth - minwidth)
        x = max(x, vrootx)
        y = min(y, vrooty + maxheight - minheight)
        y = max(y, vrooty)
        if w._windowingsystem == 'aqua':
            
            y = max(y, 22)
    else:
        x = (w.winfo_screenwidth() - minwidth) // 2
        y = (w.winfo_screenheight() - minheight) // 2

    w.wm_maxsize(maxwidth, maxheight)
    w.wm_geometry('+%d+%d' % (x, y))
    w.wm_deiconify() 


def _setup_dialog(w):
    if w._windowingsystem == "aqua":
        w.tk.call("::tk::unsupported::MacWindowStyle", "style",
                  w, "moveableModal", "")
    elif w._windowingsystem == "x11":
        w.wm_attributes("-type", "dialog")




class _QueryDialog(Dialog):

    def __init__(self, title, prompt,
                 initialvalue=None,
                 minvalue = None, maxvalue = None,
                 parent = None):

        self.prompt   = prompt
        self.minvalue = minvalue
        self.maxvalue = maxvalue

        self.initialvalue = initialvalue

        Dialog.__init__(self, parent, title)

    def destroy(self):
        self.entry = None
        Dialog.destroy(self)

    def body(self, master):

        w = Label(master, text=self.prompt, justify=LEFT)
        w.grid(row=0, padx=5, sticky=W)

        self.entry = Entry(master, name="entry")
        self.entry.grid(row=1, padx=5, sticky=W+E)

        if self.initialvalue is not None:
            self.entry.insert(0, self.initialvalue)
            self.entry.select_range(0, END)

        return self.entry

    def validate(self):
        try:
            result = self.getresult()
        except ValueError:
            messagebox.showwarning(
                "Illegal value",
                self.errormessage + "\nPlease try again",
                parent = self
            )
            return 0

        if self.minvalue is not None and result < self.minvalue:
            messagebox.showwarning(
                "Too small",
                "The allowed minimum value is %s. "
                "Please try again." % self.minvalue,
                parent = self
            )
            return 0

        if self.maxvalue is not None and result > self.maxvalue:
            messagebox.showwarning(
                "Too large",
                "The allowed maximum value is %s. "
                "Please try again." % self.maxvalue,
                parent = self
            )
            return 0

        self.result = result

        return 1


class _QueryInteger(_QueryDialog):
    errormessage = "Not an integer."

    def getresult(self):
        return self.getint(self.entry.get())


def askinteger(title, prompt, **kw):
    
    d = _QueryInteger(title, prompt, **kw)
    return d.result


class _QueryFloat(_QueryDialog):
    errormessage = "Not a floating point value."

    def getresult(self):
        return self.getdouble(self.entry.get())


def askfloat(title, prompt, **kw):
    
    d = _QueryFloat(title, prompt, **kw)
    return d.result


class _QueryString(_QueryDialog):
    def __init__(self, *args, **kw):
        if "show" in kw:
            self.__show = kw["show"]
            del kw["show"]
        else:
            self.__show = None
        _QueryDialog.__init__(self, *args, **kw)

    def body(self, master):
        entry = _QueryDialog.body(self, master)
        if self.__show is not None:
            entry.configure(show=self.__show)
        return entry

    def getresult(self):
        return self.entry.get()


def askstring(title, prompt, **kw):
    
    d = _QueryString(title, prompt, **kw)
    return d.result


if __name__ == '__main__':

    def test():
        root = Tk()
        def doit(root=root):
            d = SimpleDialog(root,
                         text="This is a test dialog.  "
                              "Would this have been an actual dialog, "
                              "the buttons below would have been glowing "
                              "in soft pink light.\n"
                              "Do you believe this?",
                         buttons=["Yes", "No", "Cancel"],
                         default=0,
                         cancel=2,
                         title="Test Dialog")
            print(d.go())
            print(askinteger("Spam", "Egg count", initialvalue=12*12))
            print(askfloat("Spam", "Egg weight\n(in tons)", minvalue=1,
                           maxvalue=100))
            print(askstring("Spam", "Egg label"))
        t = Button(root, text='Test', command=doit)
        t.pack()
        q = Button(root, text='Quit', command=t.quit)
        q.pack()
        t.mainloop()

    test()