Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
simpledialog.py442 linesDownload Raw Back to tkinter
1#2# An Introduction to Tkinter3#4# Copyright (c) 1997 by Fredrik Lundh5#6# This copyright applies to Dialog, askinteger, askfloat and asktring7#8# fredrik@pythonware.com9# http://www.pythonware.com10#11"""This modules handles dialog boxes.12 13It contains the following public symbols:14 15SimpleDialog -- A simple but flexible modal dialog box16 17Dialog -- a base class for dialogs18 19askinteger -- get an integer from the user20 21askfloat -- get a float from the user22 23askstring -- get a string from the user24"""25 26from tkinter import *27from tkinter import _get_temp_root, _destroy_temp_root28from tkinter import messagebox29 30 31class SimpleDialog:32 33    def __init__(self, master,34                 text='', buttons=[], default=None, cancel=None,35                 title=None, class_=None):36        if class_:37            self.root = Toplevel(master, class_=class_)38        else:39            self.root = Toplevel(master)40        if title:41            self.root.title(title)42            self.root.iconname(title)43 44        _setup_dialog(self.root)45 46        self.message = Message(self.root, text=text, aspect=400)47        self.message.pack(expand=1, fill=BOTH)48        self.frame = Frame(self.root)49        self.frame.pack()50        self.num = default51        self.cancel = cancel52        self.default = default53        self.root.bind('<Return>', self.return_event)54        for num in range(len(buttons)):55            s = buttons[num]56            b = Button(self.frame, text=s,57                       command=(lambda self=self, num=num: self.done(num)))58            if num == default:59                b.config(relief=RIDGE, borderwidth=8)60            b.pack(side=LEFT, fill=BOTH, expand=1)61        self.root.protocol('WM_DELETE_WINDOW', self.wm_delete_window)62        self.root.transient(master)63        _place_window(self.root, master)64 65    def go(self):66        self.root.wait_visibility()67        self.root.grab_set()68        self.root.mainloop()69        self.root.destroy()70        return self.num71 72    def return_event(self, event):73        if self.default is None:74            self.root.bell()75        else:76            self.done(self.default)77 78    def wm_delete_window(self):79        if self.cancel is None:80            self.root.bell()81        else:82            self.done(self.cancel)83 84    def done(self, num):85        self.num = num86        self.root.quit()87 88 89class Dialog(Toplevel):90 91    '''Class to open dialogs.92 93    This class is intended as a base class for custom dialogs94    '''95 96    def __init__(self, parent, title = None):97        '''Initialize a dialog.98 99        Arguments:100 101            parent -- a parent window (the application window)102 103            title -- the dialog title104        '''105        master = parent106        if master is None:107            master = _get_temp_root()108 109        Toplevel.__init__(self, master)110 111        self.withdraw() # remain invisible for now112        # If the parent is not viewable, don't113        # make the child transient, or else it114        # would be opened withdrawn115        if parent is not None and parent.winfo_viewable():116            self.transient(parent)117 118        if title:119            self.title(title)120 121        _setup_dialog(self)122 123        self.parent = parent124 125        self.result = None126 127        body = Frame(self)128        self.initial_focus = self.body(body)129        body.pack(padx=5, pady=5)130 131        self.buttonbox()132 133        if self.initial_focus is None:134            self.initial_focus = self135 136        self.protocol("WM_DELETE_WINDOW", self.cancel)137 138        _place_window(self, parent)139 140        self.initial_focus.focus_set()141 142        # wait for window to appear on screen before calling grab_set143        self.wait_visibility()144        self.grab_set()145        self.wait_window(self)146 147    def destroy(self):148        '''Destroy the window'''149        self.initial_focus = None150        Toplevel.destroy(self)151        _destroy_temp_root(self.master)152 153    #154    # construction hooks155 156    def body(self, master):157        '''create dialog body.158 159        return widget that should have initial focus.160        This method should be overridden, and is called161        by the __init__ method.162        '''163        pass164 165    def buttonbox(self):166        '''add standard button box.167 168        override if you do not want the standard buttons169        '''170 171        box = Frame(self)172 173        w = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE)174        w.pack(side=LEFT, padx=5, pady=5)175        w = Button(box, text="Cancel", width=10, command=self.cancel)176        w.pack(side=LEFT, padx=5, pady=5)177 178        self.bind("<Return>", self.ok)179        self.bind("<Escape>", self.cancel)180 181        box.pack()182 183    #184    # standard button semantics185 186    def ok(self, event=None):187 188        if not self.validate():189            self.initial_focus.focus_set() # put focus back190            return191 192        self.withdraw()193        self.update_idletasks()194 195        try:196            self.apply()197        finally:198            self.cancel()199 200    def cancel(self, event=None):201 202        # put focus back to the parent window203        if self.parent is not None:204            self.parent.focus_set()205        self.destroy()206 207    #208    # command hooks209 210    def validate(self):211        '''validate the data212 213        This method is called automatically to validate the data before the214        dialog is destroyed. By default, it always validates OK.215        '''216 217        return 1 # override218 219    def apply(self):220        '''process the data221 222        This method is called automatically to process the data, *after*223        the dialog is destroyed. By default, it does nothing.224        '''225 226        pass # override227 228 229# Place a toplevel window at the center of parent or screen230# It is a Python implementation of ::tk::PlaceWindow.231def _place_window(w, parent=None):232    w.wm_withdraw() # Remain invisible while we figure out the geometry233    w.update_idletasks() # Actualize geometry information234 235    minwidth = w.winfo_reqwidth()236    minheight = w.winfo_reqheight()237    maxwidth = w.winfo_vrootwidth()238    maxheight = w.winfo_vrootheight()239    if parent is not None and parent.winfo_ismapped():240        x = parent.winfo_rootx() + (parent.winfo_width() - minwidth) // 2241        y = parent.winfo_rooty() + (parent.winfo_height() - minheight) // 2242        vrootx = w.winfo_vrootx()243        vrooty = w.winfo_vrooty()244        x = min(x, vrootx + maxwidth - minwidth)245        x = max(x, vrootx)246        y = min(y, vrooty + maxheight - minheight)247        y = max(y, vrooty)248        if w._windowingsystem == 'aqua':249            # Avoid the native menu bar which sits on top of everything.250            y = max(y, 22)251    else:252        x = (w.winfo_screenwidth() - minwidth) // 2253        y = (w.winfo_screenheight() - minheight) // 2254 255    w.wm_maxsize(maxwidth, maxheight)256    w.wm_geometry('+%d+%d' % (x, y))257    w.wm_deiconify() # Become visible at the desired location258 259 260def _setup_dialog(w):261    if w._windowingsystem == "aqua":262        w.tk.call("::tk::unsupported::MacWindowStyle", "style",263                  w, "moveableModal", "")264    elif w._windowingsystem == "x11":265        w.wm_attributes(type="dialog")266 267# --------------------------------------------------------------------268# convenience dialogues269 270class _QueryDialog(Dialog):271 272    def __init__(self, title, prompt,273                 initialvalue=None,274                 minvalue = None, maxvalue = None,275                 parent = None):276 277        self.prompt   = prompt278        self.minvalue = minvalue279        self.maxvalue = maxvalue280 281        self.initialvalue = initialvalue282 283        Dialog.__init__(self, parent, title)284 285    def destroy(self):286        self.entry = None287        Dialog.destroy(self)288 289    def body(self, master):290 291        w = Label(master, text=self.prompt, justify=LEFT)292        w.grid(row=0, padx=5, sticky=W)293 294        self.entry = Entry(master, name="entry")295        self.entry.grid(row=1, padx=5, sticky=W+E)296 297        if self.initialvalue is not None:298            self.entry.insert(0, self.initialvalue)299            self.entry.select_range(0, END)300 301        return self.entry302 303    def validate(self):304        try:305            result = self.getresult()306        except ValueError:307            messagebox.showwarning(308                "Illegal value",309                self.errormessage + "\nPlease try again",310                parent = self311            )312            return 0313 314        if self.minvalue is not None and result < self.minvalue:315            messagebox.showwarning(316                "Too small",317                "The allowed minimum value is %s. "318                "Please try again." % self.minvalue,319                parent = self320            )321            return 0322 323        if self.maxvalue is not None and result > self.maxvalue:324            messagebox.showwarning(325                "Too large",326                "The allowed maximum value is %s. "327                "Please try again." % self.maxvalue,328                parent = self329            )330            return 0331 332        self.result = result333 334        return 1335 336 337class _QueryInteger(_QueryDialog):338    errormessage = "Not an integer."339 340    def getresult(self):341        return self.getint(self.entry.get())342 343 344def askinteger(title, prompt, **kw):345    '''get an integer from the user346 347    Arguments:348 349        title -- the dialog title350        prompt -- the label text351        **kw -- see SimpleDialog class352 353    Return value is an integer354    '''355    d = _QueryInteger(title, prompt, **kw)356    return d.result357 358 359class _QueryFloat(_QueryDialog):360    errormessage = "Not a floating-point value."361 362    def getresult(self):363        return self.getdouble(self.entry.get())364 365 366def askfloat(title, prompt, **kw):367    '''get a float from the user368 369    Arguments:370 371        title -- the dialog title372        prompt -- the label text373        **kw -- see SimpleDialog class374 375    Return value is a float376    '''377    d = _QueryFloat(title, prompt, **kw)378    return d.result379 380 381class _QueryString(_QueryDialog):382    def __init__(self, *args, **kw):383        if "show" in kw:384            self.__show = kw["show"]385            del kw["show"]386        else:387            self.__show = None388        _QueryDialog.__init__(self, *args, **kw)389 390    def body(self, master):391        entry = _QueryDialog.body(self, master)392        if self.__show is not None:393            entry.configure(show=self.__show)394        return entry395 396    def getresult(self):397        return self.entry.get()398 399 400def askstring(title, prompt, **kw):401    '''get a string from the user402 403    Arguments:404 405        title -- the dialog title406        prompt -- the label text407        **kw -- see SimpleDialog class408 409    Return value is a string410    '''411    d = _QueryString(title, prompt, **kw)412    return d.result413 414 415if __name__ == '__main__':416 417    def test():418        root = Tk()419        def doit(root=root):420            d = SimpleDialog(root,421                         text="This is a test dialog.  "422                              "Would this have been an actual dialog, "423                              "the buttons below would have been glowing "424                              "in soft pink light.\n"425                              "Do you believe this?",426                         buttons=["Yes", "No", "Cancel"],427                         default=0,428                         cancel=2,429                         title="Test Dialog")430            print(d.go())431            print(askinteger("Spam", "Egg count", initialvalue=12*12))432            print(askfloat("Spam", "Egg weight\n(in tons)", minvalue=1,433                           maxvalue=100))434            print(askstring("Spam", "Egg label"))435        t = Button(root, text='Test', command=doit)436        t.pack()437        q = Button(root, text='Quit', command=t.quit)438        q.pack()439        t.mainloop()440 441    test()442 
codekingpro/portable-devtools · Team Ai