home *** CD-ROM | disk | FTP | other *** search
/ PC World 2001 April / PCWorld_2001-04_cd.bin / Software / TemaCD / webclean / !!!python!!! / BeOpen-Python-2.0.exe / TKSIMPLEDIALOG.PY < prev    next >
Encoding:
Python Source  |  2000-09-28  |  7.0 KB  |  301 lines

  1. #
  2. # An Introduction to Tkinter
  3. # tkSimpleDialog.py
  4. #
  5. # Copyright (c) 1997 by Fredrik Lundh
  6. #
  7. # fredrik@pythonware.com
  8. # http://www.pythonware.com
  9. #
  10.  
  11. # --------------------------------------------------------------------
  12. # dialog base class
  13.  
  14. '''Dialog boxes
  15.  
  16. This module handles dialog boxes. It contains the following
  17. public symbols:
  18.  
  19. Dialog -- a base class for dialogs
  20.  
  21. askinteger -- get an integer from the user
  22.  
  23. askfloat -- get a float from the user
  24.  
  25. askstring -- get a string from the user
  26. '''
  27.  
  28. from Tkinter import *
  29. import os
  30.  
  31. class Dialog(Toplevel):
  32.  
  33.     '''Class to open dialogs.
  34.  
  35.     This class is intended as a base class for custom dialogs
  36.     '''
  37.  
  38.     def __init__(self, parent, title = None):
  39.  
  40.         '''Initialize a dialog.
  41.  
  42.         Arguments:
  43.  
  44.             parent -- a parent window (the application window)
  45.  
  46.             title -- the dialog title
  47.         '''
  48.         Toplevel.__init__(self, parent)
  49.         self.transient(parent)
  50.  
  51.         if title:
  52.             self.title(title)
  53.  
  54.         self.parent = parent
  55.  
  56.         self.result = None
  57.  
  58.         body = Frame(self)
  59.         self.initial_focus = self.body(body)
  60.         body.pack(padx=5, pady=5)
  61.  
  62.         self.buttonbox()
  63.  
  64.         self.grab_set()
  65.  
  66.         if not self.initial_focus:
  67.             self.initial_focus = self
  68.  
  69.         self.protocol("WM_DELETE_WINDOW", self.cancel)
  70.  
  71.         self.geometry("+%d+%d" % (parent.winfo_rootx()+50,
  72.                                   parent.winfo_rooty()+50))
  73.  
  74.         self.initial_focus.focus_set()
  75.  
  76.         self.wait_window(self)
  77.  
  78.     def destroy(self):
  79.         '''Destroy the window'''
  80.         self.initial_focus = None
  81.         Toplevel.destroy(self)
  82.  
  83.     #
  84.     # construction hooks
  85.  
  86.     def body(self, master):
  87.         '''create dialog body.
  88.  
  89.         return widget that should have initial focus. 
  90.         This method should be overridden, and is called
  91.         by the __init__ method.
  92.         '''
  93.         pass
  94.  
  95.     def buttonbox(self):
  96.         '''add standard button box. 
  97.  
  98.         override if you don't want the standard buttons
  99.         '''
  100.         
  101.         box = Frame(self)
  102.  
  103.         w = Button(box, text="OK", width=10, command=self.ok, default=ACTIVE)
  104.         w.pack(side=LEFT, padx=5, pady=5)
  105.         w = Button(box, text="Cancel", width=10, command=self.cancel)
  106.         w.pack(side=LEFT, padx=5, pady=5)
  107.  
  108.         self.bind("<Return>", self.ok)
  109.         self.bind("<Escape>", self.cancel)
  110.  
  111.         box.pack()
  112.  
  113.     #
  114.     # standard button semantics
  115.  
  116.     def ok(self, event=None):
  117.  
  118.         if not self.validate():
  119.             self.initial_focus.focus_set() # put focus back
  120.             return
  121.  
  122.         self.withdraw()
  123.         self.update_idletasks()
  124.  
  125.         self.apply()
  126.  
  127.         self.cancel()
  128.  
  129.     def cancel(self, event=None):
  130.  
  131.         # put focus back to the parent window
  132.         self.parent.focus_set()
  133.         self.destroy()
  134.  
  135.     #
  136.     # command hooks
  137.  
  138.     def validate(self):
  139.         '''validate the data
  140.  
  141.         This method is called automatically to validate the data before the 
  142.         dialog is destroyed. By default, it always validates OK.
  143.         '''
  144.  
  145.         return 1 # override
  146.  
  147.     def apply(self):
  148.         '''process the data
  149.  
  150.         This method is called automatically to process the data, *after*
  151.         the dialog is destroyed. By default, it does nothing.
  152.         '''
  153.  
  154.         pass # override
  155.  
  156.  
  157. # --------------------------------------------------------------------
  158. # convenience dialogues
  159.  
  160. import string
  161.  
  162. class _QueryDialog(Dialog):
  163.  
  164.     def __init__(self, title, prompt,
  165.                  initialvalue=None,
  166.                  minvalue = None, maxvalue = None,
  167.                  parent = None):
  168.  
  169.         if not parent:
  170.             import Tkinter
  171.             parent = Tkinter._default_root
  172.  
  173.         self.prompt   = prompt
  174.         self.minvalue = minvalue
  175.         self.maxvalue = maxvalue
  176.  
  177.         self.initialvalue = initialvalue
  178.  
  179.         Dialog.__init__(self, parent, title)
  180.  
  181.     def destroy(self):
  182.         self.entry = None
  183.         Dialog.destroy(self)
  184.  
  185.     def body(self, master):
  186.  
  187.         w = Label(master, text=self.prompt, justify=LEFT)
  188.         w.grid(row=0, padx=5, sticky=W)
  189.  
  190.         self.entry = Entry(master, name="entry")
  191.         self.entry.grid(row=1, padx=5, sticky=W+E)
  192.  
  193.         if self.initialvalue:
  194.             self.entry.insert(0, self.initialvalue)
  195.             self.entry.select_range(0, END)
  196.  
  197.         return self.entry
  198.  
  199.     def validate(self):
  200.  
  201.         import tkMessageBox
  202.  
  203.         try:
  204.             result = self.getresult()
  205.         except ValueError:
  206.             tkMessageBox.showwarning(
  207.                 "Illegal value",
  208.                 self.errormessage + "\nPlease try again",
  209.                 parent = self
  210.             )
  211.             return 0
  212.  
  213.         if self.minvalue is not None and result < self.minvalue:
  214.             tkMessageBox.showwarning(
  215.                 "Too small",
  216.                 "The allowed minimum value is %s. "
  217.                 "Please try again." % self.minvalue,
  218.                 parent = self
  219.             )
  220.             return 0
  221.  
  222.         if self.maxvalue is not None and result > self.maxvalue:
  223.             tkMessageBox.showwarning(
  224.                 "Too large",
  225.                 "The allowed maximum value is %s. "
  226.                 "Please try again." % self.maxvalue,
  227.                 parent = self
  228.             )
  229.             return 0
  230.                 
  231.         self.result = result
  232.  
  233.         return 1
  234.  
  235.  
  236. class _QueryInteger(_QueryDialog):
  237.     errormessage = "Not an integer."
  238.     def getresult(self):
  239.         return string.atoi(self.entry.get())
  240.  
  241. def askinteger(title, prompt, **kw):
  242.     '''get an integer from the user
  243.  
  244.     Arguments:
  245.  
  246.         title -- the dialog title
  247.         prompt -- the label text
  248.         **kw -- see SimpleDialog class
  249.  
  250.     Return value is an integer
  251.     '''
  252.     d = apply(_QueryInteger, (title, prompt), kw)
  253.     return d.result
  254.  
  255. class _QueryFloat(_QueryDialog):
  256.     errormessage = "Not a floating point value."
  257.     def getresult(self):
  258.         return string.atof(self.entry.get())
  259.  
  260. def askfloat(title, prompt, **kw):
  261.     '''get a float from the user
  262.  
  263.     Arguments:
  264.  
  265.         title -- the dialog title
  266.         prompt -- the label text
  267.         **kw -- see SimpleDialog class
  268.  
  269.     Return value is a float
  270.     '''
  271.     d = apply(_QueryFloat, (title, prompt), kw)
  272.     return d.result
  273.  
  274. class _QueryString(_QueryDialog):
  275.     def getresult(self):
  276.         return self.entry.get()
  277.  
  278. def askstring(title, prompt, **kw):
  279.     '''get a string from the user
  280.  
  281.     Arguments:
  282.  
  283.         title -- the dialog title
  284.         prompt -- the label text
  285.         **kw -- see SimpleDialog class
  286.  
  287.     Return value is a string
  288.     '''
  289.     d = apply(_QueryString, (title, prompt), kw)
  290.     return d.result
  291.  
  292. if __name__ == "__main__": 
  293.  
  294.     root = Tk()
  295.     root.update()
  296.  
  297.     print askinteger("Spam", "Egg count", initialvalue=12*12)
  298.     print askfloat("Spam", "Egg weight\n(in tons)", minvalue=1, maxvalue=100)
  299.     print askstring("Spam", "Egg label")
  300.  
  301.