Index: Demo/tkinter/matt/canvas-w-widget-draw-el.py =================================================================== --- Demo/tkinter/matt/canvas-w-widget-draw-el.py (revision 63074) +++ Demo/tkinter/matt/canvas-w-widget-draw-el.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # this file demonstrates the creation of widgets as part of a canvas object Index: Demo/tkinter/matt/not-what-you-might-think-2.py =================================================================== --- Demo/tkinter/matt/not-what-you-might-think-2.py (revision 63074) +++ Demo/tkinter/matt/not-what-you-might-think-2.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * class Test(Frame): Index: Demo/tkinter/matt/menu-simple.py =================================================================== --- Demo/tkinter/matt/menu-simple.py (revision 63074) +++ Demo/tkinter/matt/menu-simple.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # some vocabulary to keep from getting confused. This terminology # is something I cooked up for this file, but follows the man pages Index: Demo/tkinter/matt/printing-coords-of-items.py =================================================================== --- Demo/tkinter/matt/printing-coords-of-items.py (revision 63074) +++ Demo/tkinter/matt/printing-coords-of-items.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # this file demonstrates the creation of widgets as part of a canvas object Index: Demo/tkinter/matt/canvas-moving-w-mouse.py =================================================================== --- Demo/tkinter/matt/canvas-moving-w-mouse.py (revision 63074) +++ Demo/tkinter/matt/canvas-moving-w-mouse.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # this file demonstrates the movement of a single canvas item under mouse control Index: Demo/tkinter/matt/00-HELLO-WORLD.py =================================================================== --- Demo/tkinter/matt/00-HELLO-WORLD.py (revision 63074) +++ Demo/tkinter/matt/00-HELLO-WORLD.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # note that there is no explicit call to start Tk. # Tkinter is smart enough to start the system if it's not already going. Index: Demo/tkinter/matt/canvas-mult-item-sel.py =================================================================== --- Demo/tkinter/matt/canvas-mult-item-sel.py (revision 63074) +++ Demo/tkinter/matt/canvas-mult-item-sel.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # allows moving dots with multiple selection. Index: Demo/tkinter/matt/window-creation-more.py =================================================================== --- Demo/tkinter/matt/window-creation-more.py (revision 63074) +++ Demo/tkinter/matt/window-creation-more.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # this shows how to create a new window with a button in it # that can create new windows Index: Demo/tkinter/matt/subclass-existing-widgets.py =================================================================== --- Demo/tkinter/matt/subclass-existing-widgets.py (revision 63074) +++ Demo/tkinter/matt/subclass-existing-widgets.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # This is a program that makes a simple two button application Index: Demo/tkinter/matt/animation-w-velocity-ctrl.py =================================================================== --- Demo/tkinter/matt/animation-w-velocity-ctrl.py (revision 63074) +++ Demo/tkinter/matt/animation-w-velocity-ctrl.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # this is the same as simple-demo-1.py, but uses # subclassing. Index: Demo/tkinter/matt/two-radio-groups.py =================================================================== --- Demo/tkinter/matt/two-radio-groups.py (revision 63074) +++ Demo/tkinter/matt/two-radio-groups.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # The way to think about this is that each radio button menu # controls a different variable -- clicking on one of the Index: Demo/tkinter/matt/window-creation-w-location.py =================================================================== --- Demo/tkinter/matt/window-creation-w-location.py (revision 63074) +++ Demo/tkinter/matt/window-creation-w-location.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * import sys ##sys.path.append("/users/mjc4y/projects/python/tkinter/utils") Index: Demo/tkinter/matt/canvas-demo-simple.py =================================================================== --- Demo/tkinter/matt/canvas-demo-simple.py (revision 63074) +++ Demo/tkinter/matt/canvas-demo-simple.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # this program creates a canvas and puts a single polygon on the canvas Index: Demo/tkinter/matt/canvas-reading-tag-info.py =================================================================== --- Demo/tkinter/matt/canvas-reading-tag-info.py (revision 63074) +++ Demo/tkinter/matt/canvas-reading-tag-info.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * class Test(Frame): Index: Demo/tkinter/matt/menu-all-types-of-entries.py =================================================================== --- Demo/tkinter/matt/menu-all-types-of-entries.py (revision 63074) +++ Demo/tkinter/matt/menu-all-types-of-entries.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # some vocabulary to keep from getting confused. This terminology # is something I cooked up for this file, but follows the man pages Index: Demo/tkinter/matt/packer-and-placer-together.py =================================================================== --- Demo/tkinter/matt/packer-and-placer-together.py (revision 63074) +++ Demo/tkinter/matt/packer-and-placer-together.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # This is a program that tests the placer geom manager in conjunction with # the packer. The background (green) is packed, while the widget inside is placed Index: Demo/tkinter/matt/canvas-with-scrollbars.py =================================================================== --- Demo/tkinter/matt/canvas-with-scrollbars.py (revision 63074) +++ Demo/tkinter/matt/canvas-with-scrollbars.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # This example program creates a scroling canvas, and demonstrates # how to tie scrollbars and canvses together. The mechanism Index: Demo/tkinter/matt/entry-simple.py =================================================================== --- Demo/tkinter/matt/entry-simple.py (revision 63074) +++ Demo/tkinter/matt/entry-simple.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * import string # This program shows how to use a simple type-in box Index: Demo/tkinter/matt/rubber-band-box-demo-1.py =================================================================== --- Demo/tkinter/matt/rubber-band-box-demo-1.py (revision 63074) +++ Demo/tkinter/matt/rubber-band-box-demo-1.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * class Test(Frame): def printit(self): Index: Demo/tkinter/matt/not-what-you-might-think-1.py =================================================================== --- Demo/tkinter/matt/not-what-you-might-think-1.py (revision 63074) +++ Demo/tkinter/matt/not-what-you-might-think-1.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * class Test(Frame): Index: Demo/tkinter/matt/packer-simple.py =================================================================== --- Demo/tkinter/matt/packer-simple.py (revision 63074) +++ Demo/tkinter/matt/packer-simple.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * class Test(Frame): Index: Demo/tkinter/matt/placer-simple.py =================================================================== --- Demo/tkinter/matt/placer-simple.py (revision 63074) +++ Demo/tkinter/matt/placer-simple.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # This is a program that tests the placer geom manager Index: Demo/tkinter/matt/canvas-gridding.py =================================================================== --- Demo/tkinter/matt/canvas-gridding.py (revision 63074) +++ Demo/tkinter/matt/canvas-gridding.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # this is the same as simple-demo-1.py, but uses # subclassing. Index: Demo/tkinter/matt/window-creation-simple.py =================================================================== --- Demo/tkinter/matt/window-creation-simple.py (revision 63074) +++ Demo/tkinter/matt/window-creation-simple.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # this shows how to spawn off new windows at a button press Index: Demo/tkinter/matt/entry-with-shared-variable.py =================================================================== --- Demo/tkinter/matt/entry-with-shared-variable.py (revision 63074) +++ Demo/tkinter/matt/entry-with-shared-variable.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * import string # This program shows how to make a typein box shadow a program variable. Index: Demo/tkinter/matt/slider-demo-1.py =================================================================== --- Demo/tkinter/matt/slider-demo-1.py (revision 63074) +++ Demo/tkinter/matt/slider-demo-1.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # shows how to make a slider, set and get its value under program control Index: Demo/tkinter/matt/animation-simple.py =================================================================== --- Demo/tkinter/matt/animation-simple.py (revision 63074) +++ Demo/tkinter/matt/animation-simple.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # This program shows how to use the "after" function to make animation. Index: Demo/tkinter/matt/bind-w-mult-calls-p-type.py =================================================================== --- Demo/tkinter/matt/bind-w-mult-calls-p-type.py (revision 63074) +++ Demo/tkinter/matt/bind-w-mult-calls-p-type.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * import string # This program shows how to use a simple type-in box Index: Demo/tkinter/matt/canvas-moving-or-creating.py =================================================================== --- Demo/tkinter/matt/canvas-moving-or-creating.py (revision 63074) +++ Demo/tkinter/matt/canvas-moving-or-creating.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # this file demonstrates a more sophisticated movement -- # move dots or create new ones if you click outside the dots Index: Demo/tkinter/matt/radiobutton-simple.py =================================================================== --- Demo/tkinter/matt/radiobutton-simple.py (revision 63074) +++ Demo/tkinter/matt/radiobutton-simple.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # This is a demo program that shows how to # create radio buttons and how to get other widgets to Index: Demo/tkinter/matt/pong-demo-1.py =================================================================== --- Demo/tkinter/matt/pong-demo-1.py (revision 63074) +++ Demo/tkinter/matt/pong-demo-1.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * import string Index: Demo/tkinter/matt/killing-window-w-wm.py =================================================================== --- Demo/tkinter/matt/killing-window-w-wm.py (revision 63074) +++ Demo/tkinter/matt/killing-window-w-wm.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * # This file shows how to trap the killing of a window # when the user uses window manager menus (typ. upper left hand corner Index: Demo/tkinter/matt/dialog-box.py =================================================================== --- Demo/tkinter/matt/dialog-box.py (revision 63074) +++ Demo/tkinter/matt/dialog-box.py (working copy) @@ -1,5 +1,5 @@ -from Tkinter import * -from Dialog import Dialog +from tkinter import * +from tkinter.dialog import Dialog # this shows how to create a new window with a button in it # that can create new windows Index: Demo/tkinter/matt/rubber-line-demo-1.py =================================================================== --- Demo/tkinter/matt/rubber-line-demo-1.py (revision 63074) +++ Demo/tkinter/matt/rubber-line-demo-1.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * class Test(Frame): def printit(self): Index: Demo/tkinter/guido/AttrDialog.py =================================================================== --- Demo/tkinter/guido/AttrDialog.py (revision 63074) +++ Demo/tkinter/guido/AttrDialog.py (working copy) @@ -12,7 +12,7 @@ # -- totally static, though different between PackDialog and WidgetDialog # (but even that could be unified) -from Tkinter import * +from tkinter import * class Option: Index: Demo/tkinter/guido/listtree.py =================================================================== --- Demo/tkinter/guido/listtree.py (revision 63074) +++ Demo/tkinter/guido/listtree.py (working copy) @@ -3,7 +3,7 @@ import sys import string -from Tkinter import * +from tkinter import * def listtree(master, app): list = Listbox(master, name='list') Index: Demo/tkinter/guido/kill.py =================================================================== --- Demo/tkinter/guido/kill.py (revision 63074) +++ Demo/tkinter/guido/kill.py (working copy) @@ -1,7 +1,7 @@ #! /usr/bin/env python # Tkinter interface to Linux `kill' command. -from Tkinter import * +from tkinter import * from string import splitfields from string import split import commands Index: Demo/tkinter/guido/solitaire.py =================================================================== --- Demo/tkinter/guido/solitaire.py (revision 63074) +++ Demo/tkinter/guido/solitaire.py (working copy) @@ -25,7 +25,7 @@ import math import random -from Tkinter import * +from tkinter import * from Canvas import Rectangle, CanvasText, Group, Window Index: Demo/tkinter/guido/optionmenu.py =================================================================== --- Demo/tkinter/guido/optionmenu.py (revision 63074) +++ Demo/tkinter/guido/optionmenu.py (working copy) @@ -1,6 +1,6 @@ # option menu sample (Fredrik Lundh, September 1997) -from Tkinter import * +from tkinter import * root = Tk() Index: Demo/tkinter/guido/hanoi.py =================================================================== --- Demo/tkinter/guido/hanoi.py (revision 63074) +++ Demo/tkinter/guido/hanoi.py (working copy) @@ -10,7 +10,7 @@ # background of the animation. Default is no bitmap. # This uses Steen Lumholt's Tk interface -from Tkinter import * +from tkinter import * # Basic Towers-of-Hanoi algorithm: move n pieces from a to b, using c Index: Demo/tkinter/guido/electrons.py =================================================================== --- Demo/tkinter/guido/electrons.py (revision 63074) +++ Demo/tkinter/guido/electrons.py (working copy) @@ -11,7 +11,7 @@ # /usr/include/X11/bitmaps for samples); it is displayed as the # background of the animation. Default is no bitmap. -from Tkinter import * +from tkinter import * import random Index: Demo/tkinter/guido/sortvisu.py =================================================================== --- Demo/tkinter/guido/sortvisu.py (revision 63074) +++ Demo/tkinter/guido/sortvisu.py (working copy) @@ -19,7 +19,7 @@ """ -from Tkinter import * +from tkinter import * from Canvas import Line, Rectangle import random Index: Demo/tkinter/guido/dialog.py =================================================================== --- Demo/tkinter/guido/dialog.py (revision 63074) +++ Demo/tkinter/guido/dialog.py (working copy) @@ -4,7 +4,7 @@ # optional bitmap, and any number of buttons. # Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.2-3, pp. 269-270. -from Tkinter import * +from tkinter import * import sys Index: Demo/tkinter/guido/ShellWindow.py =================================================================== --- Demo/tkinter/guido/ShellWindow.py (revision 63074) +++ Demo/tkinter/guido/ShellWindow.py (working copy) @@ -1,9 +1,9 @@ import os import sys import string -from Tkinter import * -from ScrolledText import ScrolledText -from Dialog import Dialog +from tkinter import * +from tkinter.scrolledtext import ScrolledText +from tkinter.dialog import Dialog import signal BUFSIZE = 512 Index: Demo/tkinter/guido/imagedraw.py =================================================================== --- Demo/tkinter/guido/imagedraw.py (revision 63074) +++ Demo/tkinter/guido/imagedraw.py (working copy) @@ -1,6 +1,6 @@ """Draw on top of an image""" -from Tkinter import * +from tkinter import * import sys def main(): Index: Demo/tkinter/guido/canvasevents.py =================================================================== --- Demo/tkinter/guido/canvasevents.py (revision 63074) +++ Demo/tkinter/guido/canvasevents.py (working copy) @@ -1,6 +1,6 @@ #! /usr/bin/env python -from Tkinter import * +from tkinter import * from Canvas import Oval, Group, CanvasText Index: Demo/tkinter/guido/brownian2.py =================================================================== --- Demo/tkinter/guido/brownian2.py (revision 63074) +++ Demo/tkinter/guido/brownian2.py (working copy) @@ -1,7 +1,7 @@ # Brownian motion -- an example of a NON multi-threaded Tkinter program ;) # By Michele Simoniato, inspired by brownian.py -from Tkinter import * +from tkinter import * import random import sys Index: Demo/tkinter/guido/switch.py =================================================================== --- Demo/tkinter/guido/switch.py (revision 63074) +++ Demo/tkinter/guido/switch.py (working copy) @@ -1,6 +1,6 @@ # Show how to do switchable panels. -from Tkinter import * +from tkinter import * class App: Index: Demo/tkinter/guido/rmt.py =================================================================== --- Demo/tkinter/guido/rmt.py (revision 63074) +++ Demo/tkinter/guido/rmt.py (working copy) @@ -11,7 +11,7 @@ # XXX This should be written in a more Python-like style!!! -from Tkinter import * +from tkinter import * import sys # 1. Create basic application structure: menu bar on top of Index: Demo/tkinter/guido/hello.py =================================================================== --- Demo/tkinter/guido/hello.py (revision 63074) +++ Demo/tkinter/guido/hello.py (working copy) @@ -1,7 +1,7 @@ # Display hello, world in a button; clicking it quits the program import sys -from Tkinter import * +from tkinter import * def main(): root = Tk() Index: Demo/tkinter/guido/svkill.py =================================================================== --- Demo/tkinter/guido/svkill.py (revision 63074) +++ Demo/tkinter/guido/svkill.py (working copy) @@ -2,7 +2,7 @@ # Tkinter interface to SYSV `ps' and `kill' commands. -from Tkinter import * +from tkinter import * if TkVersion < 4.0: raise ImportError("This version of svkill requires Tk 4.0 or later") Index: Demo/tkinter/guido/mbox.py =================================================================== --- Demo/tkinter/guido/mbox.py (revision 63074) +++ Demo/tkinter/guido/mbox.py (working copy) @@ -9,7 +9,7 @@ import string import mhlib -from Tkinter import * +from tkinter import * from dialog import dialog Index: Demo/tkinter/guido/ss1.py =================================================================== --- Demo/tkinter/guido/ss1.py (revision 63074) +++ Demo/tkinter/guido/ss1.py (working copy) @@ -485,7 +485,7 @@ s = chr(m+ord('A')) + s return s -import Tkinter as Tk +import tkinter as Tk class SheetGUI: Index: Demo/tkinter/guido/newmenubardemo.py =================================================================== --- Demo/tkinter/guido/newmenubardemo.py (revision 63074) +++ Demo/tkinter/guido/newmenubardemo.py (working copy) @@ -2,7 +2,7 @@ """Play with the new Tk 8.0 toplevel menu option.""" -from Tkinter import * +from tkinter import * class App: Index: Demo/tkinter/guido/ManPage.py =================================================================== --- Demo/tkinter/guido/ManPage.py (revision 63074) +++ Demo/tkinter/guido/ManPage.py (working copy) @@ -1,9 +1,9 @@ # Widget to display a man page import re -from Tkinter import * -from Tkinter import _tkinter -from ScrolledText import ScrolledText +from tkinter import * +from tkinter import _tkinter +from tkinter.scrolledtext import ScrolledText # XXX These fonts may have to be changed to match your system BOLDFONT = '*-Courier-Bold-R-Normal-*-120-*' Index: Demo/tkinter/guido/MimeViewer.py =================================================================== --- Demo/tkinter/guido/MimeViewer.py (revision 63074) +++ Demo/tkinter/guido/MimeViewer.py (working copy) @@ -5,8 +5,8 @@ import string from types import * -from Tkinter import * -from ScrolledText import ScrolledText +from tkinter import * +from tkinter.scrolledtext import ScrolledText class MimeViewer: def __init__(self, parent, title, msg): Index: Demo/tkinter/guido/tkman.py =================================================================== --- Demo/tkinter/guido/tkman.py (revision 63074) +++ Demo/tkinter/guido/tkman.py (working copy) @@ -6,7 +6,7 @@ import os import string import re -from Tkinter import * +from tkinter import * from ManPage import ManPage MANNDIRLIST = ['/depot/sundry/man/mann','/usr/local/man/mann'] Index: Demo/tkinter/guido/paint.py =================================================================== --- Demo/tkinter/guido/paint.py (revision 63074) +++ Demo/tkinter/guido/paint.py (working copy) @@ -20,7 +20,7 @@ davem@magnet.com """ -from Tkinter import * +from tkinter import * """paint.py: not exactly a paint program.. just a smooth line drawing demo.""" Index: Demo/tkinter/guido/imageview.py =================================================================== --- Demo/tkinter/guido/imageview.py (revision 63074) +++ Demo/tkinter/guido/imageview.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * import sys def main(): Index: Demo/tkinter/guido/brownian.py =================================================================== --- Demo/tkinter/guido/brownian.py (revision 63074) +++ Demo/tkinter/guido/brownian.py (working copy) @@ -1,6 +1,6 @@ # Brownian motion -- an example of a multi-threaded Tkinter program. -from Tkinter import * +from tkinter import * import random import threading import time Index: Demo/tix/tixwidgets.py =================================================================== --- Demo/tix/tixwidgets.py (revision 63074) +++ Demo/tix/tixwidgets.py (working copy) @@ -13,8 +13,9 @@ # import os, os.path, sys, Tix -from Tkconstants import * -import traceback, tkMessageBox +from tkinter.constants import * +import traceback +import tkinter.messagebox as tkMessageBox TCL_DONT_WAIT = 1<<1 TCL_WINDOW_EVENTS = 1<<2 Index: Demo/tix/samples/DirList.py =================================================================== --- Demo/tix/samples/DirList.py (revision 63074) +++ Demo/tix/samples/DirList.py (working copy) @@ -17,7 +17,7 @@ # import Tix, os, copy -from Tkconstants import * +from tkinter.constants import * TCL_ALL_EVENTS = 0 Index: Demo/tix/samples/DirTree.py =================================================================== --- Demo/tix/samples/DirTree.py (revision 63074) +++ Demo/tix/samples/DirTree.py (working copy) @@ -17,7 +17,7 @@ # import Tix, os, copy -from Tkconstants import * +from tkinter.constants import * TCL_ALL_EVENTS = 0 Index: Tools/pynche/TypeinViewer.py =================================================================== --- Tools/pynche/TypeinViewer.py (revision 63074) +++ Tools/pynche/TypeinViewer.py (working copy) @@ -12,7 +12,7 @@ you must hit Return or Tab to select the color. """ -from Tkinter import * +from tkinter import * Index: Tools/pynche/PyncheWidget.py =================================================================== --- Tools/pynche/PyncheWidget.py (revision 63074) +++ Tools/pynche/PyncheWidget.py (working copy) @@ -6,9 +6,9 @@ import sys import os -from Tkinter import * -import tkMessageBox -import tkFileDialog +from tkinter import * +import tkinter.messagebox as tkMessageBox +import tkinter.filedialog as tkFileDialog import ColorDB # Milliseconds between interrupt checks @@ -40,7 +40,7 @@ # import fails or _default_root is None. tkroot = None try: - from Tkinter import _default_root + from tkinter import _default_root tkroot = self.__tkroot = _default_root except ImportError: pass Index: Tools/pynche/ListViewer.py =================================================================== --- Tools/pynche/ListViewer.py (revision 63074) +++ Tools/pynche/ListViewer.py (working copy) @@ -15,7 +15,7 @@ given name, without selecting the color. """ -from Tkinter import * +from tkinter import * import ColorDB ADDTOVIEW = 'Color %List Window...' Index: Tools/pynche/ChipViewer.py =================================================================== --- Tools/pynche/ChipViewer.py (revision 63074) +++ Tools/pynche/ChipViewer.py (working copy) @@ -13,7 +13,7 @@ selected and nearest ChipWidgets. """ -from Tkinter import * +from tkinter import * import ColorDB Index: Tools/pynche/TextViewer.py =================================================================== --- Tools/pynche/TextViewer.py (revision 63074) +++ Tools/pynche/TextViewer.py (working copy) @@ -15,7 +15,7 @@ in the text window (which only has a background). """ -from Tkinter import * +from tkinter import * import ColorDB ADDTOVIEW = 'Text Window...' Index: Tools/pynche/DetailsViewer.py =================================================================== --- Tools/pynche/DetailsViewer.py (revision 63074) +++ Tools/pynche/DetailsViewer.py (working copy) @@ -52,7 +52,7 @@ Shift + Right == +25 """ -from Tkinter import * +from tkinter import * STOP = 'Stop' WRAP = 'Wrap Around' Index: Tools/pynche/pyColorChooser.py =================================================================== --- Tools/pynche/pyColorChooser.py (revision 63074) +++ Tools/pynche/pyColorChooser.py (working copy) @@ -31,7 +31,7 @@ if dbfile <> self.__databasefile: colordb = ColorDB.get_colordb(dbfile) if not self.__master: - from Tkinter import Tk + from tkinter import Tk self.__master = Tk() if not self.__pw: self.__pw, self.__sb = \ @@ -92,7 +92,7 @@ # test stuff if __name__ == '__main__': - from Tkinter import * + from tkinter import * class Tester: def __init__(self): Index: Tools/pynche/StripViewer.py =================================================================== --- Tools/pynche/StripViewer.py (revision 63074) +++ Tools/pynche/StripViewer.py (working copy) @@ -24,7 +24,7 @@ this can be slow. """ -from Tkinter import * +from tkinter import * import ColorDB # Load this script into the Tcl interpreter and call it in Index: Tools/scripts/redemo.py =================================================================== --- Tools/scripts/redemo.py (revision 63074) +++ Tools/scripts/redemo.py (working copy) @@ -1,6 +1,6 @@ """Basic regular expression demostration facility (Perl style syntax).""" -from Tkinter import * +from tkinter import * import re class ReDemo: Index: Tools/webchecker/wcgui.py =================================================================== --- Tools/webchecker/wcgui.py (revision 63074) +++ Tools/webchecker/wcgui.py (working copy) @@ -60,7 +60,7 @@ import sys import getopt -from Tkinter import * +from tkinter import * import tktools import webchecker Index: Tools/webchecker/wsgui.py =================================================================== --- Tools/webchecker/wsgui.py (revision 63074) +++ Tools/webchecker/wsgui.py (working copy) @@ -6,7 +6,7 @@ their respective text boxes, click GO or hit return, and presto. """ -from Tkinter import * +from tkinter import * import websucker import os import threading Index: Tools/webchecker/tktools.py =================================================================== --- Tools/webchecker/tktools.py (revision 63074) +++ Tools/webchecker/tktools.py (working copy) @@ -2,7 +2,7 @@ from types import * -from Tkinter import * +from tkinter import * def _clear_entry_widget(event): try: Index: Tools/modulator/ScrolledListbox.py =================================================================== --- Tools/modulator/ScrolledListbox.py (revision 63074) +++ Tools/modulator/ScrolledListbox.py (working copy) @@ -10,8 +10,8 @@ # Most methods calls are inherited from the List widget; Pack methods # are redirected to the Frame widget however. -from Tkinter import * -from Tkinter import _cnfmerge +from tkinter import * +from tkinter import _cnfmerge class ScrolledListbox(Listbox): def __init__(self, master=None, cnf={}): Index: Tools/modulator/Tkextra.py =================================================================== --- Tools/modulator/Tkextra.py (revision 63074) +++ Tools/modulator/Tkextra.py (working copy) @@ -4,7 +4,7 @@ # optional bitmap, and any number of buttons. # Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.2-3, pp. 269-270. -from Tkinter import * +from tkinter import * mainWidget = None Index: Tools/modulator/modulator.py =================================================================== --- Tools/modulator/modulator.py (revision 63074) +++ Tools/modulator/modulator.py (working copy) @@ -21,7 +21,7 @@ sys.path.append(os.path.join(os.environ['HOME'], 'src/python/Tools/modulator')) -from Tkinter import * +from tkinter import * from Tkextra import * from ScrolledListbox import ScrolledListbox import sys Index: PC/os2emx/getpathp.c =================================================================== --- PC/os2emx/getpathp.c (revision 63074) +++ PC/os2emx/getpathp.c (working copy) @@ -17,7 +17,7 @@ is set, we believe it. Otherwise, we use the path of our host .EXE's to try and locate our "landmark" (lib\\os.py) and deduce our home. - If we DO have a Python Home: The relevant sub-directories (Lib, - plat-win, lib-tk, etc) are based on the Python Home + plat-win, etc) are based on the Python Home - If we DO NOT have a Python Home, the core Python Path is loaded from the registry. This is the main PythonPath key, and both HKLM and HKCU are combined to form the path) Index: PC/os2vacpp/pyconfig.h =================================================================== --- PC/os2vacpp/pyconfig.h (revision 63074) +++ PC/os2vacpp/pyconfig.h (working copy) @@ -66,7 +66,7 @@ #define PYCC_VACPP /* Define Indicator of C Compiler */ /* Platform Filesystem */ -#define PYTHONPATH ".;.\\lib;.\\lib\\plat-win;.\\lib\\lib-tk" +#define PYTHONPATH ".;.\\lib;.\\lib\\plat-win" #define DOSFILESYS /* OS/2 Uses the DOS File Naming Conventions */ /* #define IMPORT_8x3_NAMES (let's move up to long filenames) */ Index: PC/getpathp.c =================================================================== --- PC/getpathp.c (revision 63074) +++ PC/getpathp.c (working copy) @@ -25,7 +25,7 @@ is set, we believe it. Otherwise, we use the path of our host .EXE's to try and locate our "landmark" (lib\\os.py) and deduce our home. - If we DO have a Python Home: The relevant sub-directories (Lib, - plat-win, lib-tk, etc) are based on the Python Home + plat-win, etc) are based on the Python Home - If we DO NOT have a Python Home, the core Python Path is loaded from the registry. This is the main PythonPath key, and both HKLM and HKCU are combined to form the path) Index: PC/pyconfig.h =================================================================== --- PC/pyconfig.h (revision 63074) +++ PC/pyconfig.h (working copy) @@ -80,7 +80,7 @@ #define MS_WIN32 /* only support win32 and greater. */ #define MS_WINDOWS #ifndef PYTHONPATH -# define PYTHONPATH L".\\DLLs;.\\lib;.\\lib\\plat-win;.\\lib\\lib-tk" +# define PYTHONPATH L".\\DLLs;.\\lib;.\\lib\\plat-win" #endif #define NT_THREADS #define WITH_THREAD Index: Doc/library/idle.rst =================================================================== --- Doc/library/idle.rst (revision 63129) +++ Doc/library/idle.rst (working copy) @@ -10,11 +10,11 @@ single: Python Editor single: Integrated Development Environment -IDLE is the Python IDE built with the :mod:`Tkinter` GUI toolkit. +IDLE is the Python IDE built with the :mod:`tkinter` GUI toolkit. IDLE has the following features: -* coded in 100% pure Python, using the :mod:`Tkinter` GUI toolkit +* coded in 100% pure Python, using the :mod:`tkinter` GUI toolkit * cross-platform: works on Windows and Unix (on Mac OS, there are currently problems with Tcl/Tk) Index: Doc/library/tkinter.rst =================================================================== --- Doc/library/tkinter.rst (revision 63129) +++ Doc/library/tkinter.rst (working copy) @@ -1,13 +1,13 @@ -:mod:`Tkinter` --- Python interface to Tcl/Tk +:mod:`tkinter` --- Python interface to Tcl/Tk ============================================= -.. module:: Tkinter +.. module:: tkinter :synopsis: Interface to Tcl/Tk for graphical user interfaces .. moduleauthor:: Guido van Rossum -The :mod:`Tkinter` module ("Tk interface") is the standard Python interface to -the Tk GUI toolkit. Both Tk and :mod:`Tkinter` are available on most Unix +The :mod:`tkinter` package ("Tk interface") is the standard Python interface to +the Tk GUI toolkit. Both Tk and :mod:`tkinter` are available on most Unix platforms, as well as on Windows and Macintosh systems. (Tk itself is not part of Python; it is maintained at ActiveState.) @@ -34,23 +34,23 @@ Tkinter Modules --------------- -Most of the time, the :mod:`Tkinter` module is all you really need, but a number +Most of the time, importing :mod:`tkinter` is all you really need, but a number of additional modules are available as well. The Tk interface is located in a binary module named :mod:`_tkinter`. This module contains the low-level interface to Tk, and should never be used directly by application programmers. It is usually a shared library (or DLL), but might in some cases be statically linked with the Python interpreter. -In addition to the Tk interface module, :mod:`Tkinter` includes a number of -Python modules. The two most important modules are the :mod:`Tkinter` module -itself, and a module called :mod:`Tkconstants`. The former automatically imports -the latter, so to use Tkinter, all you need to do is to import one module:: +In addition to the Tk interface module, :mod:`tkinter` includes a number +of Python modules, :mod:`tkinter.constants` being one of the most important. +Importing :mod:`tkinter` will automatically import :mod:`tkinter.constants`, +so, usually, to use Tkinter all you need is a simple import:: - import Tkinter + import tkinter Or, more often:: - from Tkinter import * + from tkinter import * .. class:: Tk(screenName=None, baseName=None, className='Tk', useTk=1) @@ -75,32 +75,32 @@ Other modules that provide Tk support include: -:mod:`ScrolledText` +:mod:`tkinter.scrolledtext` Text widget with a vertical scroll bar built in. -:mod:`tkColorChooser` +:mod:`tkinter.colorchooser` Dialog to let the user choose a color. -:mod:`tkCommonDialog` +:mod:`tkinter.commondialog` Base class for the dialogs defined in the other modules listed here. -:mod:`tkFileDialog` +:mod:`tkinter.filedialog` Common dialogs to allow the user to specify a file to open or save. -:mod:`tkFont` +:mod:`tkinter.font` Utilities to help work with fonts. -:mod:`tkMessageBox` +:mod:`tkinter.messagebox` Access to standard Tk dialog boxes. -:mod:`tkSimpleDialog` +:mod:`tkinter.simpledialog` Basic dialogs and convenience functions. -:mod:`Tkdnd` - Drag-and-drop support for :mod:`Tkinter`. This is experimental and should become - deprecated when it is replaced with the Tk DND. +:mod:`tkinter.dnd` + Drag-and-drop support for :mod:`tkinter`. This is experimental and should + become deprecated when it is replaced with the Tk DND. -:mod:`turtle` +:mod:`tkinter.turtle` Turtle graphics in a Tk window. @@ -141,7 +141,7 @@ When trying to answer questions of the form "how do I do blah", it is often best to find out how to do"blah" in straight Tk, and then convert this back into the -corresponding :mod:`Tkinter` call. Python programmers can often guess at the +corresponding :mod:`tkinter` call. Python programmers can often guess at the correct Python command by looking at the Tk documentation. This means that in order to use Tkinter, you will have to know a little bit about Tk. This document can't fulfill that role, so the best we can do is point you to the best @@ -157,8 +157,8 @@ the novice. The book is not exhaustive, and for many details it defers to the man pages. -* :file:`Tkinter.py` is a last resort for most, but can be a good place to go - when nothing else makes sense. +* :file:`tkinter/__init__.py` is a last resort for most, but can be a good + place to go when nothing else makes sense. .. seealso:: @@ -178,7 +178,7 @@ :: - from Tkinter import * + from tkinter import * class Application(Frame): def say_hi(self): @@ -232,7 +232,7 @@ To make use of this reference material, there will be times when you will need to know how to read short passages of Tk and how to identify the various parts of a Tk command. (See section :ref:`tkinter-basic-mapping` for the -:mod:`Tkinter` equivalents of what's below.) +:mod:`tkinter` equivalents of what's below.) Tk scripts are Tcl programs. Like all Tcl programs, Tk scripts are just lists of tokens separated by spaces. A Tk widget is just its *class*, the *options* @@ -320,9 +320,9 @@ To give a widget to the packer (geometry manager), you call pack with optional arguments. In Tkinter, the Pack class holds all this functionality, and the various forms of the pack command are implemented as methods. All widgets in -:mod:`Tkinter` are subclassed from the Packer, and so inherit all the packing -methods. See the :mod:`Tix` module documentation for additional information on -the Form geometry manager. :: +:mod:`tkinter` are subclassed from the Packer, and so inherit all the packing +methods. See the :mod:`tkinter.tix` module documentation for additional +information on the Form geometry manager. :: pack .fred -side left =====> fred.pack(side = "left") @@ -333,11 +333,11 @@ From the top down: Your App Here (Python) - A Python application makes a :mod:`Tkinter` call. + A Python application makes a :mod:`tkinter` call. -Tkinter (Python Module) +tkinter (Python Package) This call (say, for example, creating a button widget), is implemented in the - *Tkinter* module, which is written in Python. This Python function will parse + *tkinter* package, which is written in Python. This Python function will parse the commands and the arguments and convert them into a form that makes them look as if they had come from a Tk script instead of a Python script. @@ -349,8 +349,8 @@ This C function is able to make calls into other C modules, including the C functions that make up the Tk library. Tk is implemented in C and some Tcl. The Tcl part of the Tk widgets is used to bind certain default behaviors to - widgets, and is executed once at the point where the Python :mod:`Tkinter` - module is imported. (The user never sees this stage). + widgets, and is executed once at the point where the Python :mod:`tkinter` + package is imported. (The user never sees this stage). Tk (C) The Tk part of the Tk Widgets implement the final mapping to ... @@ -506,11 +506,11 @@ ``value``. This connection works both ways: if the variable changes for any reason, the widget it's connected to will be updated to reflect the new value. -Unfortunately, in the current implementation of :mod:`Tkinter` it is not +Unfortunately, in the current implementation of :mod:`tkinter` it is not possible to hand over an arbitrary Python variable to a widget through a ``variable`` or ``textvariable`` option. The only kinds of variables for which this works are variables that are subclassed from a class called Variable, -defined in the :mod:`Tkinter` module. +defined in the :mod:`tkinter` package. There are many useful subclasses of Variable already defined: :class:`StringVar`, :class:`IntVar`, :class:`DoubleVar`, and @@ -554,7 +554,7 @@ In Tk, there is a utility command, ``wm``, for interacting with the window manager. Options to the ``wm`` command allow you to control things like titles, -placement, icon bitmaps, and the like. In :mod:`Tkinter`, these commands have +placement, icon bitmaps, and the like. In :mod:`tkinter`, these commands have been implemented as methods on the :class:`Wm` class. Toplevel widgets are subclassed from the :class:`Wm` class, and so can call the :class:`Wm` methods directly. @@ -568,7 +568,7 @@ Here are some examples of typical usage:: - from Tkinter import * + from tkinter import * class App(Frame): def __init__(self, master=None): Frame.__init__(self, master) @@ -729,7 +729,7 @@ Entry widget indexes (index, view index, etc.) Entry widgets have options that refer to character positions in the text being - displayed. You can use these :mod:`Tkinter` functions to access these special + displayed. You can use these :mod:`tkinter` functions to access these special points in text widgets: AtEnd() @@ -781,7 +781,7 @@ ^^^^^^ Bitmap/Pixelmap images can be created through the subclasses of -:class:`Tkinter.Image`: +:class:`tkinter.Image`: * :class:`BitmapImage` can be used for X11 bitmap data. Index: Doc/library/tk.rst =================================================================== --- Doc/library/tk.rst (revision 63129) +++ Doc/library/tk.rst (working copy) @@ -12,16 +12,17 @@ Tk/Tcl has long been an integral part of Python. It provides a robust and platform independent windowing toolkit, that is available to Python programmers -using the :mod:`Tkinter` module, and its extension, the :mod:`Tix` module. +using the :mod:`tkinter` package, and its extension, the :mod:`tkinter.tix` +module. -The :mod:`Tkinter` module is a thin object-oriented layer on top of Tcl/Tk. To -use :mod:`Tkinter`, you don't need to write Tcl code, but you will need to +The :mod:`tkinter` package is a thin object-oriented layer on top of Tcl/Tk. To +use :mod:`tkinter`, you don't need to write Tcl code, but you will need to consult the Tk documentation, and occasionally the Tcl documentation. -:mod:`Tkinter` is a set of wrappers that implement the Tk widgets as Python +:mod:`tkinter` is a set of wrappers that implement the Tk widgets as Python classes. In addition, the internal module :mod:`_tkinter` provides a threadsafe mechanism which allows Python and Tcl to interact. -:mod:`Tkinter`'s chief virtues are that it is fast, and that it usually comes +:mod:`tkinter`'s chief virtues are that it is fast, and that it usually comes bundled with Python. Although it has been used to create some very good applications, including IDLE, it has weak documentation and an outdated look and feel. For more modern, better documented, and much more extensive GUI Index: Doc/library/turtle.rst =================================================================== --- Doc/library/turtle.rst (revision 63074) +++ Doc/library/turtle.rst (working copy) @@ -1,289 +0,0 @@ - -:mod:`turtle` --- Turtle graphics for Tk -======================================== - -.. module:: turtle - :platform: Tk - :synopsis: An environment for turtle graphics. -.. moduleauthor:: Guido van Rossum - - -.. sectionauthor:: Moshe Zadka - - -The :mod:`turtle` module provides turtle graphics primitives, in both an -object-oriented and procedure-oriented ways. Because it uses :mod:`Tkinter` for -the underlying graphics, it needs a version of python installed with Tk support. - -The procedural interface uses a pen and a canvas which are automagically created -when any of the functions are called. - -The :mod:`turtle` module defines the following functions: - - -.. function:: degrees() - - Set angle measurement units to degrees. - - -.. function:: radians() - - Set angle measurement units to radians. - - -.. function:: setup(**kwargs) - - Sets the size and position of the main window. Keywords are: - - * ``width``: either a size in pixels or a fraction of the screen. The default is - 50% of the screen. - - * ``height``: either a size in pixels or a fraction of the screen. The default - is 50% of the screen. - - * ``startx``: starting position in pixels from the left edge of the screen. - ``None`` is the default value and centers the window horizontally on screen. - - * ``starty``: starting position in pixels from the top edge of the screen. - ``None`` is the default value and centers the window vertically on screen. - - Examples:: - - # Uses default geometry: 50% x 50% of screen, centered. - setup() - - # Sets window to 200x200 pixels, in upper left of screen - setup (width=200, height=200, startx=0, starty=0) - - # Sets window to 75% of screen by 50% of screen, and centers it. - setup(width=.75, height=0.5, startx=None, starty=None) - - -.. function:: title(title_str) - - Set the window's title to *title*. - - -.. function:: done() - - Enters the Tk main loop. The window will continue to be displayed until the - user closes it or the process is killed. - - -.. function:: reset() - - Clear the screen, re-center the pen, and set variables to the default values. - - -.. function:: clear() - - Clear the screen. - - -.. function:: tracer(flag) - - Set tracing on/off (according to whether flag is true or not). Tracing means - line are drawn more slowly, with an animation of an arrow along the line. - - -.. function:: speed(speed) - - Set the speed of the turtle. Valid values for the parameter *speed* are - ``'fastest'`` (no delay), ``'fast'``, (delay 5ms), ``'normal'`` (delay 10ms), - ``'slow'`` (delay 15ms), and ``'slowest'`` (delay 20ms). - - -.. function:: delay(delay) - - Set the speed of the turtle to *delay*, which is given in ms. - - -.. function:: forward(distance) - - Go forward *distance* steps. - - -.. function:: backward(distance) - - Go backward *distance* steps. - - -.. function:: left(angle) - - Turn left *angle* units. Units are by default degrees, but can be set via the - :func:`degrees` and :func:`radians` functions. - - -.. function:: right(angle) - - Turn right *angle* units. Units are by default degrees, but can be set via the - :func:`degrees` and :func:`radians` functions. - - -.. function:: up() - - Move the pen up --- stop drawing. - - -.. function:: down() - - Move the pen down --- draw when moving. - - -.. function:: width(width) - - Set the line width to *width*. - - -.. function:: color(s) - color((r, g, b)) - color(r, g, b) - - Set the pen color. In the first form, the color is specified as a Tk color - specification as a string. The second form specifies the color as a tuple of - the RGB values, each in the range [0..1]. For the third form, the color is - specified giving the RGB values as three separate parameters (each in the range - [0..1]). - - -.. function:: write(text[, move]) - - Write *text* at the current pen position. If *move* is true, the pen is moved to - the bottom-right corner of the text. By default, *move* is false. - - -.. function:: fill(flag) - - The complete specifications are rather complex, but the recommended usage is: - call ``fill(1)`` before drawing a path you want to fill, and call ``fill(0)`` - when you finish to draw the path. - - -.. function:: begin_fill() - - Switch turtle into filling mode; Must eventually be followed by a corresponding - end_fill() call. Otherwise it will be ignored. - - -.. function:: end_fill() - - End filling mode, and fill the shape; equivalent to ``fill(0)``. - - -.. function:: circle(radius[, extent]) - - Draw a circle with radius *radius* whose center-point is *radius* units left of - the turtle. *extent* determines which part of a circle is drawn: if not given it - defaults to a full circle. - - If *extent* is not a full circle, one endpoint of the arc is the current pen - position. The arc is drawn in a counter clockwise direction if *radius* is - positive, otherwise in a clockwise direction. In the process, the direction of - the turtle is changed by the amount of the *extent*. - - -.. function:: goto(x, y) - goto((x, y)) - - Go to co-ordinates *x*, *y*. The co-ordinates may be specified either as two - separate arguments or as a 2-tuple. - - -.. function:: towards(x, y) - - Return the angle of the line from the turtle's position to the point *x*, *y*. - The co-ordinates may be specified either as two separate arguments, as a - 2-tuple, or as another pen object. - - -.. function:: heading() - - Return the current orientation of the turtle. - - -.. function:: setheading(angle) - - Set the orientation of the turtle to *angle*. - - -.. function:: position() - - Return the current location of the turtle as an ``(x,y)`` pair. - - -.. function:: setx(x) - - Set the x coordinate of the turtle to *x*. - - -.. function:: sety(y) - - Set the y coordinate of the turtle to *y*. - - -.. function:: window_width() - - Return the width of the canvas window. - - -.. function:: window_height() - - Return the height of the canvas window. - - -This module also does ``from math import *``, so see the documentation for the -:mod:`math` module for additional constants and functions useful for turtle -graphics. - - -.. function:: demo() - - Exercise the module a bit. - - -.. exception:: Error - - Exception raised on any error caught by this module. - -For examples, see the code of the :func:`demo` function. - -This module defines the following classes: - - -.. class:: Pen() - - Define a pen. All above functions can be called as a methods on the given pen. - The constructor automatically creates a canvas do be drawn on. - - -.. class:: Turtle() - - Define a pen. This is essentially a synonym for ``Pen()``; :class:`Turtle` is an - empty subclass of :class:`Pen`. - - -.. class:: RawPen(canvas) - - Define a pen which draws on a canvas *canvas*. This is useful if you want to - use the module to create graphics in a "real" program. - - -.. _pen-rawpen-objects: - -Turtle, Pen and RawPen Objects ------------------------------- - -Most of the global functions available in the module are also available as -methods of the :class:`Turtle`, :class:`Pen` and :class:`RawPen` classes, -affecting only the state of the given pen. - -The only method which is more powerful as a method is :func:`degrees`, which -takes an optional argument letting you specify the number of units -corresponding to a full circle: - - -.. method:: Turtle.degrees([fullcircle]) - - *fullcircle* is by default 360. This can cause the pen to have any angular units - whatever: give *fullcircle* ``2*pi`` for radians, or 400 for gradians. - Index: Doc/library/scrolledtext.rst =================================================================== --- Doc/library/scrolledtext.rst (revision 63074) +++ Doc/library/scrolledtext.rst (working copy) @@ -1,32 +0,0 @@ -:mod:`ScrolledText` --- Scrolled Text Widget -============================================ - -.. module:: ScrolledText - :platform: Tk - :synopsis: Text widget with a vertical scroll bar. -.. sectionauthor:: Fred L. Drake, Jr. - - -The :mod:`ScrolledText` module provides a class of the same name which -implements a basic text widget which has a vertical scroll bar configured to do -the "right thing." Using the :class:`ScrolledText` class is a lot easier than -setting up a text widget and scroll bar directly. The constructor is the same -as that of the :class:`Tkinter.Text` class. - -The text widget and scrollbar are packed together in a :class:`Frame`, and the -methods of the :class:`Grid` and :class:`Pack` geometry managers are acquired -from the :class:`Frame` object. This allows the :class:`ScrolledText` widget to -be used directly to achieve most normal geometry management behavior. - -Should more specific control be necessary, the following attributes are -available: - - -.. attribute:: ScrolledText.frame - - The frame which surrounds the text and scroll bar widgets. - - -.. attribute:: ScrolledText.vbar - - The scroll bar widget. Index: Doc/library/tkinter.tix.rst =================================================================== --- Doc/library/tkinter.tix.rst (revision 63129) +++ Doc/library/tkinter.tix.rst (working copy) @@ -1,20 +1,21 @@ -:mod:`Tix` --- Extension widgets for Tk -======================================= +:mod:`tkinter.tix` --- Extension widgets for Tk +=============================================== -.. module:: Tix +.. module:: tkinter.tix :synopsis: Tk Extension Widgets for Tkinter .. sectionauthor:: Mike Clarkson -.. index:: single: Tix +.. index:: single: tkinter.tix -The :mod:`Tix` (Tk Interface Extension) module provides an additional rich set -of widgets. Although the standard Tk library has many useful widgets, they are -far from complete. The :mod:`Tix` library provides most of the commonly needed -widgets that are missing from standard Tk: :class:`HList`, :class:`ComboBox`, -:class:`Control` (a.k.a. SpinBox) and an assortment of scrollable widgets. -:mod:`Tix` also includes many more widgets that are generally useful in a wide -range of applications: :class:`NoteBook`, :class:`FileEntry`, +The :mod:`tkinter.tix` (Tk Interface Extension) module provides an additional +rich set of widgets. Although the standard Tk library has many useful widgets, +they are far from complete. The :mod:`tkinter.tix` library provides most of the +commonly needed widgets that are missing from standard Tk: :class:`HList`, +:class:`ComboBox`, :class:`Control` (a.k.a. SpinBox) and an assortment of +scrollable widgets. +:mod:`tkinter.tix` also includes many more widgets that are generally useful in +a wide range of applications: :class:`NoteBook`, :class:`FileEntry`, :class:`PanedWindow`, etc; there are more than 40 of them. With all these new widgets, you can introduce new interaction techniques into @@ -50,28 +51,28 @@ Toplevel widget of Tix which represents mostly the main window of an application. It has an associated Tcl interpreter. - Classes in the :mod:`Tix` module subclasses the classes in the :mod:`Tkinter` - module. The former imports the latter, so to use :mod:`Tix` with Tkinter, all - you need to do is to import one module. In general, you can just import - :mod:`Tix`, and replace the toplevel call to :class:`Tkinter.Tk` with - :class:`Tix.Tk`:: + Classes in the :mod:`tkinter.tix` module subclasses the classes in the + :mod:`tkinter` package. The former imports the latter, so to use + :mod:`tkinter.tix` with Tkinter, all you need to do is to import one module. + In general, you can just import :mod:`tkinter.tix`, and replace the toplevel + call to :class:`tkinter.Tk` with :class:`tix.Tk`:: - import Tix - from Tkconstants import * - root = Tix.Tk() + from tkinter import tix + from tkinter.constants import * + root = tix.Tk() -To use :mod:`Tix`, you must have the :mod:`Tix` widgets installed, usually -alongside your installation of the Tk widgets. To test your installation, try +To use :mod:`tkinter.tix`, you must have the Tix widgets installed, usually +alongside your installation of the Tk widgets. To test your installation, try the following:: - import Tix - root = Tix.Tk() + import tkinter.tix + root = tix.Tk() root.tk.eval('package require Tix') If this fails, you have a Tk installation problem which must be resolved before proceeding. Use the environment variable :envvar:`TIX_LIBRARY` to point to the -installed :mod:`Tix` library directory, and make sure you have the dynamic -object library (:file:`tix8183.dll` or :file:`libtix8183.so`) in the same +installed Tix library directory, and make sure you have the dynamic object +library (:file:`tix8183.dll` or :file:`libtix8183.so`) in the same directory that contains your Tk dynamic object library (:file:`tk8183.dll` or :file:`libtk8183.so`). The directory with the dynamic object library should also have a file called :file:`pkgIndex.tcl` (case sensitive), which contains the @@ -84,8 +85,8 @@ ----------- `Tix `_ -introduces over 40 widget classes to the :mod:`Tkinter` repertoire. There is a -demo of all the :mod:`Tix` widgets in the :file:`Demo/tix` directory of the +introduces over 40 widget classes to the :mod:`tkinter` repertoire. There is +a demo of all the Tix widgets in the :file:`Demo/tix` directory of the standard distribution. .. The Python sample code is still being added to Python, hence commented out @@ -434,11 +435,11 @@ Image Types ^^^^^^^^^^^ -The :mod:`Tix` module adds: +The :mod:`tkinter.tix` module adds: * `pixmap `_ - capabilities to all :mod:`Tix` and :mod:`Tkinter` widgets to create color images - from XPM files. + capabilities to all :mod:`tkinter.tix` and :mod:`tkinter` widgets to create + color images from XPM files. .. Python Demo of: .. \ulink{XPM Image In Button}{http://tix.sourceforge.net/dist/current/demos/samples/Xpm.tcl} @@ -478,7 +479,7 @@ Form Geometry Manager ^^^^^^^^^^^^^^^^^^^^^ -In addition, :mod:`Tix` augments :mod:`Tkinter` by providing: +In addition, :mod:`tkinter.tix` augments :mod:`tkinter` by providing: .. class:: Form() Index: Doc/library/othergui.rst =================================================================== --- Doc/library/othergui.rst (revision 63129) +++ Doc/library/othergui.rst (working copy) @@ -3,13 +3,13 @@ Other Graphical User Interface Packages ======================================= -There are an number of extension widget sets to :mod:`Tkinter`. +There are an number of extension widget sets to :mod:`tkinter`. .. seealso:: `Python megawidgets `_ is a toolkit for building high-level compound widgets in Python using the - :mod:`Tkinter` module. It consists of a set of base classes and a library of + :mod:`tkinter` package. It consists of a set of base classes and a library of flexible and extensible megawidgets built on this foundation. These megawidgets include notebooks, comboboxes, selection widgets, paned widgets, scrolled widgets, dialog windows, etc. Also, with the Pmw.Blt interface to BLT, the Index: Doc/library/tkinter.scrolledtext.rst =================================================================== --- Doc/library/tkinter.scrolledtext.rst (revision 63129) +++ Doc/library/tkinter.scrolledtext.rst (working copy) @@ -1,17 +1,17 @@ -:mod:`ScrolledText` --- Scrolled Text Widget -============================================ +:mod:`tkinter.scrolledtext` --- Scrolled Text Widget +==================================================== -.. module:: ScrolledText +.. module:: tkinter.scrolledtext :platform: Tk :synopsis: Text widget with a vertical scroll bar. .. sectionauthor:: Fred L. Drake, Jr. -The :mod:`ScrolledText` module provides a class of the same name which +The :mod:`tkinter.scrolledtext` module provides a class of the same name which implements a basic text widget which has a vertical scroll bar configured to do the "right thing." Using the :class:`ScrolledText` class is a lot easier than setting up a text widget and scroll bar directly. The constructor is the same -as that of the :class:`Tkinter.Text` class. +as that of the :class:`tkinter.Text` class. The text widget and scrollbar are packed together in a :class:`Frame`, and the methods of the :class:`Grid` and :class:`Pack` geometry managers are acquired Index: Doc/library/tix.rst =================================================================== --- Doc/library/tix.rst (revision 63074) +++ Doc/library/tix.rst (working copy) @@ -1,590 +0,0 @@ -:mod:`Tix` --- Extension widgets for Tk -======================================= - -.. module:: Tix - :synopsis: Tk Extension Widgets for Tkinter -.. sectionauthor:: Mike Clarkson - - -.. index:: single: Tix - -The :mod:`Tix` (Tk Interface Extension) module provides an additional rich set -of widgets. Although the standard Tk library has many useful widgets, they are -far from complete. The :mod:`Tix` library provides most of the commonly needed -widgets that are missing from standard Tk: :class:`HList`, :class:`ComboBox`, -:class:`Control` (a.k.a. SpinBox) and an assortment of scrollable widgets. -:mod:`Tix` also includes many more widgets that are generally useful in a wide -range of applications: :class:`NoteBook`, :class:`FileEntry`, -:class:`PanedWindow`, etc; there are more than 40 of them. - -With all these new widgets, you can introduce new interaction techniques into -applications, creating more useful and more intuitive user interfaces. You can -design your application by choosing the most appropriate widgets to match the -special needs of your application and users. - - -.. seealso:: - - `Tix Homepage `_ - The home page for :mod:`Tix`. This includes links to additional documentation - and downloads. - - `Tix Man Pages `_ - On-line version of the man pages and reference material. - - `Tix Programming Guide `_ - On-line version of the programmer's reference material. - - `Tix Development Applications `_ - Tix applications for development of Tix and Tkinter programs. Tide applications - work under Tk or Tkinter, and include :program:`TixInspect`, an inspector to - remotely modify and debug Tix/Tk/Tkinter applications. - - -Using Tix ---------- - - -.. class:: Tix(screenName[, baseName[, className]]) - - Toplevel widget of Tix which represents mostly the main window of an - application. It has an associated Tcl interpreter. - - Classes in the :mod:`Tix` module subclasses the classes in the :mod:`Tkinter` - module. The former imports the latter, so to use :mod:`Tix` with Tkinter, all - you need to do is to import one module. In general, you can just import - :mod:`Tix`, and replace the toplevel call to :class:`Tkinter.Tk` with - :class:`Tix.Tk`:: - - import Tix - from Tkconstants import * - root = Tix.Tk() - -To use :mod:`Tix`, you must have the :mod:`Tix` widgets installed, usually -alongside your installation of the Tk widgets. To test your installation, try -the following:: - - import Tix - root = Tix.Tk() - root.tk.eval('package require Tix') - -If this fails, you have a Tk installation problem which must be resolved before -proceeding. Use the environment variable :envvar:`TIX_LIBRARY` to point to the -installed :mod:`Tix` library directory, and make sure you have the dynamic -object library (:file:`tix8183.dll` or :file:`libtix8183.so`) in the same -directory that contains your Tk dynamic object library (:file:`tk8183.dll` or -:file:`libtk8183.so`). The directory with the dynamic object library should also -have a file called :file:`pkgIndex.tcl` (case sensitive), which contains the -line:: - - package ifneeded Tix 8.1 [list load "[file join $dir tix8183.dll]" Tix] - - -Tix Widgets ------------ - -`Tix `_ -introduces over 40 widget classes to the :mod:`Tkinter` repertoire. There is a -demo of all the :mod:`Tix` widgets in the :file:`Demo/tix` directory of the -standard distribution. - -.. The Python sample code is still being added to Python, hence commented out - - -Basic Widgets -^^^^^^^^^^^^^ - - -.. class:: Balloon() - - A `Balloon - `_ that - pops up over a widget to provide help. When the user moves the cursor inside a - widget to which a Balloon widget has been bound, a small pop-up window with a - descriptive message will be shown on the screen. - -.. Python Demo of: -.. \ulink{Balloon}{http://tix.sourceforge.net/dist/current/demos/samples/Balloon.tcl} - - -.. class:: ButtonBox() - - The `ButtonBox - `_ - widget creates a box of buttons, such as is commonly used for ``Ok Cancel``. - -.. Python Demo of: -.. \ulink{ButtonBox}{http://tix.sourceforge.net/dist/current/demos/samples/BtnBox.tcl} - - -.. class:: ComboBox() - - The `ComboBox - `_ - widget is similar to the combo box control in MS Windows. The user can select a - choice by either typing in the entry subwdget or selecting from the listbox - subwidget. - -.. Python Demo of: -.. \ulink{ComboBox}{http://tix.sourceforge.net/dist/current/demos/samples/ComboBox.tcl} - - -.. class:: Control() - - The `Control - `_ - widget is also known as the :class:`SpinBox` widget. The user can adjust the - value by pressing the two arrow buttons or by entering the value directly into - the entry. The new value will be checked against the user-defined upper and - lower limits. - -.. Python Demo of: -.. \ulink{Control}{http://tix.sourceforge.net/dist/current/demos/samples/Control.tcl} - - -.. class:: LabelEntry() - - The `LabelEntry - `_ - widget packages an entry widget and a label into one mega widget. It can be used - be used to simplify the creation of "entry-form" type of interface. - -.. Python Demo of: -.. \ulink{LabelEntry}{http://tix.sourceforge.net/dist/current/demos/samples/LabEntry.tcl} - - -.. class:: LabelFrame() - - The `LabelFrame - `_ - widget packages a frame widget and a label into one mega widget. To create - widgets inside a LabelFrame widget, one creates the new widgets relative to the - :attr:`frame` subwidget and manage them inside the :attr:`frame` subwidget. - -.. Python Demo of: -.. \ulink{LabelFrame}{http://tix.sourceforge.net/dist/current/demos/samples/LabFrame.tcl} - - -.. class:: Meter() - - The `Meter - `_ widget - can be used to show the progress of a background job which may take a long time - to execute. - -.. Python Demo of: -.. \ulink{Meter}{http://tix.sourceforge.net/dist/current/demos/samples/Meter.tcl} - - -.. class:: OptionMenu() - - The `OptionMenu - `_ - creates a menu button of options. - -.. Python Demo of: -.. \ulink{OptionMenu}{http://tix.sourceforge.net/dist/current/demos/samples/OptMenu.tcl} - - -.. class:: PopupMenu() - - The `PopupMenu - `_ - widget can be used as a replacement of the ``tk_popup`` command. The advantage - of the :mod:`Tix` :class:`PopupMenu` widget is it requires less application code - to manipulate. - -.. Python Demo of: -.. \ulink{PopupMenu}{http://tix.sourceforge.net/dist/current/demos/samples/PopMenu.tcl} - - -.. class:: Select() - - The `Select - `_ widget - is a container of button subwidgets. It can be used to provide radio-box or - check-box style of selection options for the user. - -.. Python Demo of: -.. \ulink{Select}{http://tix.sourceforge.net/dist/current/demos/samples/Select.tcl} - - -.. class:: StdButtonBox() - - The `StdButtonBox - `_ - widget is a group of standard buttons for Motif-like dialog boxes. - -.. Python Demo of: -.. \ulink{StdButtonBox}{http://tix.sourceforge.net/dist/current/demos/samples/StdBBox.tcl} - - -File Selectors -^^^^^^^^^^^^^^ - - -.. class:: DirList() - - The `DirList - `_ - widget displays a list view of a directory, its previous directories and its - sub-directories. The user can choose one of the directories displayed in the - list or change to another directory. - -.. Python Demo of: -.. \ulink{DirList}{http://tix.sourceforge.net/dist/current/demos/samples/DirList.tcl} - - -.. class:: DirTree() - - The `DirTree - `_ - widget displays a tree view of a directory, its previous directories and its - sub-directories. The user can choose one of the directories displayed in the - list or change to another directory. - -.. Python Demo of: -.. \ulink{DirTree}{http://tix.sourceforge.net/dist/current/demos/samples/DirTree.tcl} - - -.. class:: DirSelectDialog() - - The `DirSelectDialog - `_ - widget presents the directories in the file system in a dialog window. The user - can use this dialog window to navigate through the file system to select the - desired directory. - -.. Python Demo of: -.. \ulink{DirSelectDialog}{http://tix.sourceforge.net/dist/current/demos/samples/DirDlg.tcl} - - -.. class:: DirSelectBox() - - The :class:`DirSelectBox` is similar to the standard Motif(TM) - directory-selection box. It is generally used for the user to choose a - directory. DirSelectBox stores the directories mostly recently selected into - a ComboBox widget so that they can be quickly selected again. - - -.. class:: ExFileSelectBox() - - The `ExFileSelectBox - `_ - widget is usually embedded in a tixExFileSelectDialog widget. It provides an - convenient method for the user to select files. The style of the - :class:`ExFileSelectBox` widget is very similar to the standard file dialog on - MS Windows 3.1. - -.. Python Demo of: -.. \ulink{ExFileSelectDialog}{http://tix.sourceforge.net/dist/current/demos/samples/EFileDlg.tcl} - - -.. class:: FileSelectBox() - - The `FileSelectBox - `_ - is similar to the standard Motif(TM) file-selection box. It is generally used - for the user to choose a file. FileSelectBox stores the files mostly recently - selected into a :class:`ComboBox` widget so that they can be quickly selected - again. - -.. Python Demo of: -.. \ulink{FileSelectDialog}{http://tix.sourceforge.net/dist/current/demos/samples/FileDlg.tcl} - - -.. class:: FileEntry() - - The `FileEntry - `_ - widget can be used to input a filename. The user can type in the filename - manually. Alternatively, the user can press the button widget that sits next to - the entry, which will bring up a file selection dialog. - -.. Python Demo of: -.. \ulink{FileEntry}{http://tix.sourceforge.net/dist/current/demos/samples/FileEnt.tcl} - - -Hierachical ListBox -^^^^^^^^^^^^^^^^^^^ - - -.. class:: HList() - - The `HList - `_ widget - can be used to display any data that have a hierarchical structure, for example, - file system directory trees. The list entries are indented and connected by - branch lines according to their places in the hierarchy. - -.. Python Demo of: -.. \ulink{HList}{http://tix.sourceforge.net/dist/current/demos/samples/HList1.tcl} - - -.. class:: CheckList() - - The `CheckList - `_ - widget displays a list of items to be selected by the user. CheckList acts - similarly to the Tk checkbutton or radiobutton widgets, except it is capable of - handling many more items than checkbuttons or radiobuttons. - -.. Python Demo of: -.. \ulink{ CheckList}{http://tix.sourceforge.net/dist/current/demos/samples/ChkList.tcl} -.. Python Demo of: -.. \ulink{ScrolledHList (1)}{http://tix.sourceforge.net/dist/current/demos/samples/SHList.tcl} -.. Python Demo of: -.. \ulink{ScrolledHList (2)}{http://tix.sourceforge.net/dist/current/demos/samples/SHList2.tcl} - - -.. class:: Tree() - - The `Tree - `_ widget - can be used to display hierarchical data in a tree form. The user can adjust the - view of the tree by opening or closing parts of the tree. - -.. Python Demo of: -.. \ulink{Tree}{http://tix.sourceforge.net/dist/current/demos/samples/Tree.tcl} -.. Python Demo of: -.. \ulink{Tree (Dynamic)}{http://tix.sourceforge.net/dist/current/demos/samples/DynTree.tcl} - - -Tabular ListBox -^^^^^^^^^^^^^^^ - - -.. class:: TList() - - The `TList - `_ widget - can be used to display data in a tabular format. The list entries of a - :class:`TList` widget are similar to the entries in the Tk listbox widget. The - main differences are (1) the :class:`TList` widget can display the list entries - in a two dimensional format and (2) you can use graphical images as well as - multiple colors and fonts for the list entries. - -.. Python Demo of: -.. \ulink{ScrolledTList (1)}{http://tix.sourceforge.net/dist/current/demos/samples/STList1.tcl} -.. Python Demo of: -.. \ulink{ScrolledTList (2)}{http://tix.sourceforge.net/dist/current/demos/samples/STList2.tcl} -.. Grid has yet to be added to Python -.. \subsubsection{Grid Widget} -.. Python Demo of: -.. \ulink{Simple Grid}{http://tix.sourceforge.net/dist/current/demos/samples/SGrid0.tcl} -.. Python Demo of: -.. \ulink{ScrolledGrid}{http://tix.sourceforge.net/dist/current/demos/samples/SGrid1.tcl} -.. Python Demo of: -.. \ulink{Editable Grid}{http://tix.sourceforge.net/dist/current/demos/samples/EditGrid.tcl} - - -Manager Widgets -^^^^^^^^^^^^^^^ - - -.. class:: PanedWindow() - - The `PanedWindow - `_ - widget allows the user to interactively manipulate the sizes of several panes. - The panes can be arranged either vertically or horizontally. The user changes - the sizes of the panes by dragging the resize handle between two panes. - -.. Python Demo of: -.. \ulink{PanedWindow}{http://tix.sourceforge.net/dist/current/demos/samples/PanedWin.tcl} - - -.. class:: ListNoteBook() - - The `ListNoteBook - `_ - widget is very similar to the :class:`TixNoteBook` widget: it can be used to - display many windows in a limited space using a notebook metaphor. The notebook - is divided into a stack of pages (windows). At one time only one of these pages - can be shown. The user can navigate through these pages by choosing the name of - the desired page in the :attr:`hlist` subwidget. - -.. Python Demo of: -.. \ulink{ListNoteBook}{http://tix.sourceforge.net/dist/current/demos/samples/ListNBK.tcl} - - -.. class:: NoteBook() - - The `NoteBook - `_ - widget can be used to display many windows in a limited space using a notebook - metaphor. The notebook is divided into a stack of pages. At one time only one of - these pages can be shown. The user can navigate through these pages by choosing - the visual "tabs" at the top of the NoteBook widget. - -.. Python Demo of: -.. \ulink{NoteBook}{http://tix.sourceforge.net/dist/current/demos/samples/NoteBook.tcl} - -.. \subsubsection{Scrolled Widgets} -.. Python Demo of: -.. \ulink{ScrolledListBox}{http://tix.sourceforge.net/dist/current/demos/samples/SListBox.tcl} -.. Python Demo of: -.. \ulink{ScrolledText}{http://tix.sourceforge.net/dist/current/demos/samples/SText.tcl} -.. Python Demo of: -.. \ulink{ScrolledWindow}{http://tix.sourceforge.net/dist/current/demos/samples/SWindow.tcl} -.. Python Demo of: -.. \ulink{Canvas Object View}{http://tix.sourceforge.net/dist/current/demos/samples/CObjView.tcl} - - -Image Types -^^^^^^^^^^^ - -The :mod:`Tix` module adds: - -* `pixmap `_ - capabilities to all :mod:`Tix` and :mod:`Tkinter` widgets to create color images - from XPM files. - - .. Python Demo of: - .. \ulink{XPM Image In Button}{http://tix.sourceforge.net/dist/current/demos/samples/Xpm.tcl} - .. Python Demo of: - .. \ulink{XPM Image In Menu}{http://tix.sourceforge.net/dist/current/demos/samples/Xpm1.tcl} - -* `Compound - `_ image - types can be used to create images that consists of multiple horizontal lines; - each line is composed of a series of items (texts, bitmaps, images or spaces) - arranged from left to right. For example, a compound image can be used to - display a bitmap and a text string simultaneously in a Tk :class:`Button` - widget. - - .. Python Demo of: - .. \ulink{Compound Image In Buttons}{http://tix.sourceforge.net/dist/current/demos/samples/CmpImg.tcl} - .. Python Demo of: - .. \ulink{Compound Image In NoteBook}{http://tix.sourceforge.net/dist/current/demos/samples/CmpImg2.tcl} - .. Python Demo of: - .. \ulink{Compound Image Notebook Color Tabs}{http://tix.sourceforge.net/dist/current/demos/samples/CmpImg4.tcl} - .. Python Demo of: - .. \ulink{Compound Image Icons}{http://tix.sourceforge.net/dist/current/demos/samples/CmpImg3.tcl} - - -Miscellaneous Widgets -^^^^^^^^^^^^^^^^^^^^^ - - -.. class:: InputOnly() - - The `InputOnly - `_ - widgets are to accept inputs from the user, which can be done with the ``bind`` - command (Unix only). - - -Form Geometry Manager -^^^^^^^^^^^^^^^^^^^^^ - -In addition, :mod:`Tix` augments :mod:`Tkinter` by providing: - - -.. class:: Form() - - The `Form - `_ geometry - manager based on attachment rules for all Tk widgets. - - -Tix Commands ------------- - - -.. class:: tixCommand() - - The `tix commands - `_ provide - access to miscellaneous elements of :mod:`Tix`'s internal state and the - :mod:`Tix` application context. Most of the information manipulated by these - methods pertains to the application as a whole, or to a screen or display, - rather than to a particular window. - - To view the current settings, the common usage is:: - - import Tix - root = Tix.Tk() - print(root.tix_configure()) - - -.. method:: tixCommand.tix_configure([cnf,] **kw) - - Query or modify the configuration options of the Tix application context. If no - option is specified, returns a dictionary all of the available options. If - option is specified with no value, then the method returns a list describing the - one named option (this list will be identical to the corresponding sublist of - the value returned if no option is specified). If one or more option-value - pairs are specified, then the method modifies the given option(s) to have the - given value(s); in this case the method returns an empty string. Option may be - any of the configuration options. - - -.. method:: tixCommand.tix_cget(option) - - Returns the current value of the configuration option given by *option*. Option - may be any of the configuration options. - - -.. method:: tixCommand.tix_getbitmap(name) - - Locates a bitmap file of the name ``name.xpm`` or ``name`` in one of the bitmap - directories (see the :meth:`tix_addbitmapdir` method). By using - :meth:`tix_getbitmap`, you can avoid hard coding the pathnames of the bitmap - files in your application. When successful, it returns the complete pathname of - the bitmap file, prefixed with the character ``@``. The returned value can be - used to configure the ``bitmap`` option of the Tk and Tix widgets. - - -.. method:: tixCommand.tix_addbitmapdir(directory) - - Tix maintains a list of directories under which the :meth:`tix_getimage` and - :meth:`tix_getbitmap` methods will search for image files. The standard bitmap - directory is :file:`$TIX_LIBRARY/bitmaps`. The :meth:`tix_addbitmapdir` method - adds *directory* into this list. By using this method, the image files of an - applications can also be located using the :meth:`tix_getimage` or - :meth:`tix_getbitmap` method. - - -.. method:: tixCommand.tix_filedialog([dlgclass]) - - Returns the file selection dialog that may be shared among different calls from - this application. This method will create a file selection dialog widget when - it is called the first time. This dialog will be returned by all subsequent - calls to :meth:`tix_filedialog`. An optional dlgclass parameter can be passed - as a string to specified what type of file selection dialog widget is desired. - Possible options are ``tix``, ``FileSelectDialog`` or ``tixExFileSelectDialog``. - - -.. method:: tixCommand.tix_getimage(self, name) - - Locates an image file of the name :file:`name.xpm`, :file:`name.xbm` or - :file:`name.ppm` in one of the bitmap directories (see the - :meth:`tix_addbitmapdir` method above). If more than one file with the same name - (but different extensions) exist, then the image type is chosen according to the - depth of the X display: xbm images are chosen on monochrome displays and color - images are chosen on color displays. By using :meth:`tix_getimage`, you can - avoid hard coding the pathnames of the image files in your application. When - successful, this method returns the name of the newly created image, which can - be used to configure the ``image`` option of the Tk and Tix widgets. - - -.. method:: tixCommand.tix_option_get(name) - - Gets the options maintained by the Tix scheme mechanism. - - -.. method:: tixCommand.tix_resetoptions(newScheme, newFontSet[, newScmPrio]) - - Resets the scheme and fontset of the Tix application to *newScheme* and - *newFontSet*, respectively. This affects only those widgets created after this - call. Therefore, it is best to call the resetoptions method before the creation - of any widgets in a Tix application. - - The optional parameter *newScmPrio* can be given to reset the priority level of - the Tk options set by the Tix schemes. - - Because of the way Tk handles the X option database, after Tix has been has - imported and inited, it is not possible to reset the color schemes and font sets - using the :meth:`tix_config` method. Instead, the :meth:`tix_resetoptions` - method must be used. Index: Doc/library/tkinter.turtle.rst =================================================================== --- Doc/library/tkinter.turtle.rst (revision 63129) +++ Doc/library/tkinter.turtle.rst (working copy) @@ -1,8 +1,7 @@ +:mod:`tkinter.turtle` --- Turtle graphics for Tk +================================================ -:mod:`turtle` --- Turtle graphics for Tk -======================================== - -.. module:: turtle +.. module:: tkinter.turtle :platform: Tk :synopsis: An environment for turtle graphics. .. moduleauthor:: Guido van Rossum @@ -11,14 +10,15 @@ .. sectionauthor:: Moshe Zadka -The :mod:`turtle` module provides turtle graphics primitives, in both an -object-oriented and procedure-oriented ways. Because it uses :mod:`Tkinter` for -the underlying graphics, it needs a version of python installed with Tk support. +The :mod:`tkinter.turtle` module provides turtle graphics primitives, in both +an object-oriented and procedure-oriented ways. Because it uses :mod:`tkinter` +for the underlying graphics, it needs a version of python installed with Tk +support. The procedural interface uses a pen and a canvas which are automagically created when any of the functions are called. -The :mod:`turtle` module defines the following functions: +The :mod:`tkinter.turtle` module defines the following functions: .. function:: degrees() Index: Lib/idlelib/AutoCompleteWindow.py =================================================================== --- Lib/idlelib/AutoCompleteWindow.py (revision 63077) +++ Lib/idlelib/AutoCompleteWindow.py (working copy) @@ -1,7 +1,7 @@ """ An auto-completion window for IDLE, used by the AutoComplete extension """ -from Tkinter import * +from tkinter import * from idlelib.MultiCall import MC_SHIFT from idlelib.AutoComplete import COMPLETE_FILES, COMPLETE_ATTRIBUTES Index: Lib/idlelib/ToolTip.py =================================================================== --- Lib/idlelib/ToolTip.py (revision 63077) +++ Lib/idlelib/ToolTip.py (working copy) @@ -3,7 +3,7 @@ # may be useful for some purposes in (or almost in ;) the current project scope # Ideas gleaned from PySol -from Tkinter import * +from tkinter import * class ToolTipBase: Index: Lib/idlelib/UndoDelegator.py =================================================================== --- Lib/idlelib/UndoDelegator.py (revision 63077) +++ Lib/idlelib/UndoDelegator.py (working copy) @@ -1,5 +1,5 @@ import string -from Tkinter import * +from tkinter import * from idlelib.Delegator import Delegator Index: Lib/idlelib/ColorDelegator.py =================================================================== --- Lib/idlelib/ColorDelegator.py (revision 63077) +++ Lib/idlelib/ColorDelegator.py (working copy) @@ -2,7 +2,7 @@ import re import keyword import builtins -from Tkinter import * +from tkinter import * from idlelib.Delegator import Delegator from idlelib.configHandler import idleConf Index: Lib/idlelib/ObjectBrowser.py =================================================================== --- Lib/idlelib/ObjectBrowser.py (revision 63077) +++ Lib/idlelib/ObjectBrowser.py (working copy) @@ -123,7 +123,7 @@ def _test(): import sys - from Tkinter import Tk + from tkinter import Tk root = Tk() root.configure(bd=0, bg="yellow") root.focus_set() Index: Lib/idlelib/configSectionNameDialog.py =================================================================== --- Lib/idlelib/configSectionNameDialog.py (revision 63077) +++ Lib/idlelib/configSectionNameDialog.py (working copy) @@ -2,8 +2,8 @@ Dialog that allows user to specify a new config file section name. Used to get new highlight theme and keybinding set names. """ -from Tkinter import * -import tkMessageBox +from tkinter import * +import tkinter.messagebox as tkMessageBox class GetCfgSectionNameDialog(Toplevel): def __init__(self,parent,title,message,usedNames): Index: Lib/idlelib/PyShell.py =================================================================== --- Lib/idlelib/PyShell.py (revision 63077) +++ Lib/idlelib/PyShell.py (working copy) @@ -15,12 +15,12 @@ from code import InteractiveInterpreter try: - from Tkinter import * + from tkinter import * except ImportError: - print("** IDLE can't import Tkinter. " \ + print("** IDLE can't import tkinter. " \ "Your Python may not be configured for Tk. **", file=sys.__stderr__) sys.exit(1) -import tkMessageBox +import tkinter.messagebox as tkMessageBox from idlelib.EditorWindow import EditorWindow, fixwordbreaks from idlelib.FileList import FileList @@ -983,8 +983,8 @@ (sys.version, sys.platform, self.COPYRIGHT, self.firewallmessage, idlever.IDLE_VERSION, nosub)) self.showprompt() - import Tkinter - Tkinter._default_root = None # 03Jan04 KBK What's this? + import tkinter + tkinter._default_root = None # 03Jan04 KBK What's this? return True def readline(self): Index: Lib/idlelib/Debugger.py =================================================================== --- Lib/idlelib/Debugger.py (revision 63077) +++ Lib/idlelib/Debugger.py (working copy) @@ -1,7 +1,7 @@ import os import bdb import types -from Tkinter import * +from tkinter import * from idlelib.WindowList import ListedToplevel from idlelib.ScrolledList import ScrolledList from idlelib import macosxSupport Index: Lib/idlelib/configDialog.py =================================================================== --- Lib/idlelib/configDialog.py (revision 63077) +++ Lib/idlelib/configDialog.py (working copy) @@ -9,8 +9,10 @@ Refer to comments in EditorWindow autoindent code for details. """ -from Tkinter import * -import tkMessageBox, tkColorChooser, tkFont +from tkinter import * +import tkinter.messagebox as tkMessageBox +import tkinter.colorchooser as tkColorChooser +import tkinter.font as tkFont import copy from idlelib.configHandler import idleConf Index: Lib/idlelib/StackViewer.py =================================================================== --- Lib/idlelib/StackViewer.py (revision 63077) +++ Lib/idlelib/StackViewer.py (working copy) @@ -7,7 +7,7 @@ def StackBrowser(root, flist=None, tb=None, top=None): if top is None: - from Tkinter import Toplevel + from tkinter import Toplevel top = Toplevel(root) sc = ScrolledCanvas(top, bg="white", highlightthickness=0) sc.frame.pack(expand=1, fill="both") Index: Lib/idlelib/SearchEngine.py =================================================================== --- Lib/idlelib/SearchEngine.py (revision 63077) +++ Lib/idlelib/SearchEngine.py (working copy) @@ -1,6 +1,6 @@ import re -from Tkinter import * -import tkMessageBox +from tkinter import * +import tkinter.messagebox def get(root): if not hasattr(root, "_searchengine"): Index: Lib/idlelib/ReplaceDialog.py =================================================================== --- Lib/idlelib/ReplaceDialog.py (revision 63077) +++ Lib/idlelib/ReplaceDialog.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * from idlelib import SearchEngine from idlelib.SearchDialogBase import SearchDialogBase Index: Lib/idlelib/ScriptBinding.py =================================================================== --- Lib/idlelib/ScriptBinding.py (revision 63077) +++ Lib/idlelib/ScriptBinding.py (working copy) @@ -22,7 +22,7 @@ import string import tabnanny import tokenize -import tkMessageBox +import tkinter.messagebox as tkMessageBox from idlelib.EditorWindow import EditorWindow from idlelib import PyShell Index: Lib/idlelib/tabbedpages.py =================================================================== --- Lib/idlelib/tabbedpages.py (revision 63077) +++ Lib/idlelib/tabbedpages.py (working copy) @@ -7,7 +7,7 @@ TabSet -- A widget containing tabs (buttons) in one or more rows. """ -from Tkinter import * +from tkinter import * class InvalidNameError(Exception): pass class AlreadyExistsError(Exception): pass Index: Lib/idlelib/keybindingDialog.py =================================================================== --- Lib/idlelib/keybindingDialog.py (revision 63077) +++ Lib/idlelib/keybindingDialog.py (working copy) @@ -1,8 +1,8 @@ """ Dialog for building Tkinter accelerator key bindings """ -from Tkinter import * -import tkMessageBox +from tkinter import * +import tkinter.messagebox as tkMessageBox import string class GetKeysDialog(Toplevel): Index: Lib/idlelib/configHelpSourceEdit.py =================================================================== --- Lib/idlelib/configHelpSourceEdit.py (revision 63077) +++ Lib/idlelib/configHelpSourceEdit.py (working copy) @@ -3,9 +3,9 @@ import os import sys -from Tkinter import * -import tkMessageBox -import tkFileDialog +from tkinter import * +import tkinter.messagebox as tkMessageBox +import tkinter.filedialog as tkFileDialog class GetHelpSourceDialog(Toplevel): def __init__(self, parent, title, menuItem='', filePath=''): Index: Lib/idlelib/WidgetRedirector.py =================================================================== --- Lib/idlelib/WidgetRedirector.py (revision 63077) +++ Lib/idlelib/WidgetRedirector.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * class WidgetRedirector: Index: Lib/idlelib/GrepDialog.py =================================================================== --- Lib/idlelib/GrepDialog.py (revision 63077) +++ Lib/idlelib/GrepDialog.py (working copy) @@ -1,7 +1,7 @@ import os import fnmatch import sys -from Tkinter import * +from tkinter import * from idlelib import SearchEngine from idlelib.SearchDialogBase import SearchDialogBase Index: Lib/idlelib/EditorWindow.py =================================================================== --- Lib/idlelib/EditorWindow.py (revision 63077) +++ Lib/idlelib/EditorWindow.py (working copy) @@ -4,9 +4,9 @@ import string import imp from itertools import count -from Tkinter import * -import tkSimpleDialog -import tkMessageBox +from tkinter import * +import tkinter.simpledialog as tkSimpleDialog +import tkinter.messagebox as tkMessageBox import traceback import webbrowser @@ -47,7 +47,7 @@ from idlelib.UndoDelegator import UndoDelegator from idlelib.IOBinding import IOBinding, filesystemencoding, encoding from idlelib import Bindings - from Tkinter import Toplevel + from tkinter import Toplevel from idlelib.MultiStatusBar import MultiStatusBar help_url = None Index: Lib/idlelib/OutputWindow.py =================================================================== --- Lib/idlelib/OutputWindow.py (revision 63077) +++ Lib/idlelib/OutputWindow.py (working copy) @@ -1,7 +1,7 @@ -from Tkinter import * +from tkinter import * from idlelib.EditorWindow import EditorWindow import re -import tkMessageBox +import tkinter.messagebox as tkMessageBox from idlelib import IOBinding class OutputWindow(EditorWindow): Index: Lib/idlelib/aboutDialog.py =================================================================== --- Lib/idlelib/aboutDialog.py (revision 63077) +++ Lib/idlelib/aboutDialog.py (working copy) @@ -2,7 +2,7 @@ """ -from Tkinter import * +from tkinter import * import os from idlelib import textView Index: Lib/idlelib/IOBinding.py =================================================================== --- Lib/idlelib/IOBinding.py (revision 63077) +++ Lib/idlelib/IOBinding.py (working copy) @@ -3,11 +3,11 @@ import sys import codecs import tempfile -import tkFileDialog -import tkMessageBox +import tkinter.filedialog as tkFileDialog +import tkinter.messagebox as tkMessageBox import re -from Tkinter import * -from SimpleDialog import SimpleDialog +from tkinter import * +from tkinter.simpledialog import SimpleDialog from idlelib.configHandler import idleConf Index: Lib/idlelib/WindowList.py =================================================================== --- Lib/idlelib/WindowList.py (revision 63077) +++ Lib/idlelib/WindowList.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * class WindowList: Index: Lib/idlelib/ScrolledList.py =================================================================== --- Lib/idlelib/ScrolledList.py (revision 63077) +++ Lib/idlelib/ScrolledList.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * class ScrolledList: Index: Lib/idlelib/FileList.py =================================================================== --- Lib/idlelib/FileList.py (revision 63077) +++ Lib/idlelib/FileList.py (working copy) @@ -1,6 +1,6 @@ import os -from Tkinter import * -import tkMessageBox +from tkinter import * +import tkinter.messagebox as tkMessageBox class FileList: Index: Lib/idlelib/CodeContext.py =================================================================== --- Lib/idlelib/CodeContext.py (revision 63077) +++ Lib/idlelib/CodeContext.py (working copy) @@ -9,8 +9,8 @@ not open blocks are not shown in the context hints pane. """ -import Tkinter -from Tkconstants import TOP, LEFT, X, W, SUNKEN +import tkinter +from tkinter.constants import TOP, LEFT, X, W, SUNKEN import re from sys import maxsize as INFINITY from idlelib.configHandler import idleConf @@ -69,7 +69,7 @@ border = 0 for widget in widgets: border += int(str( widget.cget('border') )) - self.label = Tkinter.Label(self.editwin.top, + self.label = tkinter.Label(self.editwin.top, text="\n" * (self.context_depth - 1), anchor=W, justify=LEFT, font=self.textfont, Index: Lib/idlelib/textView.py =================================================================== --- Lib/idlelib/textView.py (revision 63077) +++ Lib/idlelib/textView.py (working copy) @@ -2,8 +2,8 @@ """ -from Tkinter import * -import tkMessageBox +from tkinter import * +import tkinter.messagebox as tkMessageBox class TextViewer(Toplevel): """A simple text viewer dialog for IDLE @@ -68,7 +68,7 @@ else: textFile = open(filename, 'r') except IOError: - import tkMessageBox + import tkinter.messagebox as tkMessageBox tkMessageBox.showerror(title='File Load Error', message='Unable to load file %r .' % filename, parent=parent) Index: Lib/idlelib/SearchDialogBase.py =================================================================== --- Lib/idlelib/SearchDialogBase.py (revision 63077) +++ Lib/idlelib/SearchDialogBase.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * class SearchDialogBase: Index: Lib/idlelib/CallTipWindow.py =================================================================== --- Lib/idlelib/CallTipWindow.py (revision 63077) +++ Lib/idlelib/CallTipWindow.py (working copy) @@ -4,7 +4,7 @@ Used by the CallTips IDLE extension. """ -from Tkinter import * +from tkinter import * HIDE_VIRTUAL_EVENT_NAME = "<>" HIDE_SEQUENCES = ("", "") Index: Lib/idlelib/SearchDialog.py =================================================================== --- Lib/idlelib/SearchDialog.py (revision 63077) +++ Lib/idlelib/SearchDialog.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * from idlelib import SearchEngine from idlelib.SearchDialogBase import SearchDialogBase Index: Lib/idlelib/TreeWidget.py =================================================================== --- Lib/idlelib/TreeWidget.py (revision 63077) +++ Lib/idlelib/TreeWidget.py (working copy) @@ -15,7 +15,7 @@ # - optimize tree redraw after expand of subnode import os -from Tkinter import * +from tkinter import * import imp from idlelib import ZoomHeight Index: Lib/idlelib/run.py =================================================================== --- Lib/idlelib/run.py (revision 63077) +++ Lib/idlelib/run.py (working copy) @@ -127,9 +127,9 @@ server.handle_request() # A single request only def show_socket_error(err, address): - import Tkinter - import tkMessageBox - root = Tkinter.Tk() + import tkinter + import tkinter.messagebox as tkMessageBox + root = tkinter.Tk() root.withdraw() if err.args[0] == 61: # connection refused msg = "IDLE's subprocess can't connect to %s:%d. This may be due "\ Index: Lib/idlelib/Percolator.py =================================================================== --- Lib/idlelib/Percolator.py (revision 63077) +++ Lib/idlelib/Percolator.py (working copy) @@ -52,7 +52,7 @@ filter.setdelegate(None) def main(): - import Tkinter as Tk + import tkinter as Tk class Tracer(Delegator): def __init__(self, name): self.name = name Index: Lib/idlelib/dynOptionMenuWidget.py =================================================================== --- Lib/idlelib/dynOptionMenuWidget.py (revision 63077) +++ Lib/idlelib/dynOptionMenuWidget.py (working copy) @@ -2,8 +2,8 @@ OptionMenu widget modified to allow dynamic menu reconfiguration and setting of highlightthickness """ -from Tkinter import OptionMenu -from Tkinter import _setit +from tkinter import OptionMenu +from tkinter import _setit import copy class DynOptionMenu(OptionMenu): Index: Lib/idlelib/MultiStatusBar.py =================================================================== --- Lib/idlelib/MultiStatusBar.py (revision 63077) +++ Lib/idlelib/MultiStatusBar.py (working copy) @@ -1,4 +1,4 @@ -from Tkinter import * +from tkinter import * class MultiStatusBar(Frame): Index: Lib/idlelib/MultiCall.py =================================================================== --- Lib/idlelib/MultiCall.py (revision 63077) +++ Lib/idlelib/MultiCall.py (working copy) @@ -31,7 +31,7 @@ import sys import re -import Tkinter +import tkinter # the event type constants, which define the meaning of mc_type MC_KEYPRESS=0; MC_KEYRELEASE=1; MC_BUTTONPRESS=2; MC_BUTTONRELEASE=3; @@ -297,14 +297,14 @@ _multicall_dict = {} def MultiCallCreator(widget): """Return a MultiCall class which inherits its methods from the - given widget class (for example, Tkinter.Text). This is used + given widget class (for example, tkinter.Text). This is used instead of a templating mechanism. """ if widget in _multicall_dict: return _multicall_dict[widget] class MultiCall (widget): - assert issubclass(widget, Tkinter.Misc) + assert issubclass(widget, tkinter.Misc) def __init__(self, *args, **kwargs): widget.__init__(self, *args, **kwargs) @@ -396,8 +396,8 @@ if __name__ == "__main__": # Test - root = Tkinter.Tk() - text = MultiCallCreator(Tkinter.Text)(root) + root = tkinter.Tk() + text = MultiCallCreator(tkinter.Text)(root) text.pack() def bindseq(seq, n=[0]): def handler(event): Index: Lib/idlelib/macosxSupport.py =================================================================== --- Lib/idlelib/macosxSupport.py (revision 63077) +++ Lib/idlelib/macosxSupport.py (working copy) @@ -3,7 +3,7 @@ GUI application (as opposed to an X11 application). """ import sys -import Tkinter +import tkinter def runningAsOSXApp(): """ Returns True iff running from the IDLE.app bundle on OSX """ @@ -26,7 +26,7 @@ def hideTkConsole(root): try: root.tk.call('console', 'hide') - except Tkinter.TclError: + except tkinter.TclError: # Some versions of the Tk framework don't have a console object pass @@ -46,7 +46,7 @@ # # Due to a (mis-)feature of TkAqua the user will also see an empty Help # menu. - from Tkinter import Menu, Text, Text + from tkinter import Menu, Text, Text from idlelib.EditorWindow import prepstr, get_accelerator from idlelib import Bindings from idlelib import WindowList Index: Lib/tkinter/commondialog.py =================================================================== --- Lib/tkinter/commondialog.py (revision 0) +++ Lib/tkinter/commondialog.py (revision 0) @@ -0,0 +1,60 @@ +# base class for tk common dialogues +# +# this module provides a base class for accessing the common +# dialogues available in Tk 4.2 and newer. use tkFileDialog, +# tkColorChooser, and tkMessageBox to access the individual +# dialogs. +# +# written by Fredrik Lundh, May 1997 +# + +from tkinter import * + +class Dialog: + + command = None + + def __init__(self, master=None, **options): + + # FIXME: should this be placed on the module level instead? + if TkVersion < 4.2: + raise TclError("this module requires Tk 4.2 or newer") + + self.master = master + self.options = options + if not master and options.get('parent'): + self.master = options['parent'] + + def _fixoptions(self): + pass # hook + + def _fixresult(self, widget, result): + return result # hook + + def show(self, **options): + + # update instance options + for k, v in options.items(): + self.options[k] = v + + self._fixoptions() + + # we need a dummy widget to properly process the options + # (at least as long as we use Tkinter 1.63) + w = Frame(self.master) + + try: + + s = w.tk.call(self.command, *w._options(self.options)) + + s = self._fixresult(w, s) + + finally: + + try: + # get rid of the widget + w.destroy() + except: + pass + + return s Index: Lib/tkinter/simpledialog.py =================================================================== --- Lib/tkinter/simpledialog.py (revision 0) +++ Lib/tkinter/simpledialog.py (revision 0) @@ -0,0 +1,431 @@ +"""A simple but flexible modal dialog box.""" + + +from tkinter import * + + +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) + 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('', 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._set_transient(master) + + def _set_transient(self, master, relx=0.5, rely=0.3): + widget = self.root + widget.withdraw() # Remain invisible while we figure out the geometry + widget.transient(master) + widget.update_idletasks() # Actualize geometry information + if master.winfo_ismapped(): + m_width = master.winfo_width() + m_height = master.winfo_height() + m_x = master.winfo_rootx() + m_y = master.winfo_rooty() + else: + m_width = master.winfo_screenwidth() + m_height = master.winfo_screenheight() + m_x = m_y = 0 + w_width = widget.winfo_reqwidth() + w_height = widget.winfo_reqheight() + x = m_x + (m_width - w_width) * relx + y = m_y + (m_height - w_height) * rely + if x+w_width > master.winfo_screenwidth(): + x = master.winfo_screenwidth() - w_width + elif x < 0: + x = 0 + if y+w_height > master.winfo_screenheight(): + y = master.winfo_screenheight() - w_height + elif y < 0: + y = 0 + widget.geometry("+%d+%d" % (x, y)) + widget.deiconify() # Become visible at the desired location + + 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() + + +# +# The rest of this module has been merged from tkSimpleDialog.py +# +# An Introduction to Tkinter +# tkSimpleDialog.py +# +# Copyright (c) 1997 by Fredrik Lundh +# +# fredrik@pythonware.com +# http://www.pythonware.com +# + +# -------------------------------------------------------------------- +# dialog base class + +'''Dialog boxes + +This module handles dialog boxes. It contains the following +public symbols: + +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 Dialog(Toplevel): + + '''Class to open dialogs. + + This class is intended as a base class for custom dialogs + ''' + + def __init__(self, parent, title = None): + + '''Initialize a dialog. + + Arguments: + + parent -- a parent window (the application window) + + title -- the dialog title + ''' + Toplevel.__init__(self, parent) + + # If the master is not viewable, don't + # make the child transient, or else it + # would be opened withdrawn + if parent.winfo_viewable(): + self.transient(parent) + + if title: + self.title(title) + + self.parent = parent + + self.result = None + + body = Frame(self) + self.initial_focus = self.body(body) + body.pack(padx=5, pady=5) + + self.buttonbox() + + self.wait_visibility() # window needs to be visible for the grab + self.grab_set() + + if not self.initial_focus: + self.initial_focus = self + + self.protocol("WM_DELETE_WINDOW", self.cancel) + + if self.parent is not None: + self.geometry("+%d+%d" % (parent.winfo_rootx()+50, + parent.winfo_rooty()+50)) + + self.initial_focus.focus_set() + + self.wait_window(self) + + def destroy(self): + '''Destroy the window''' + self.initial_focus = None + Toplevel.destroy(self) + + # + # construction hooks + + def body(self, master): + '''create dialog body. + + return widget that should have initial focus. + This method should be overridden, and is called + by the __init__ method. + ''' + pass + + def buttonbox(self): + '''add standard button box. + + override if you do not want the standard buttons + ''' + + 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("", self.ok) + self.bind("", self.cancel) + + box.pack() + + # + # standard button semantics + + def ok(self, event=None): + + if not self.validate(): + self.initial_focus.focus_set() # put focus back + return + + self.withdraw() + self.update_idletasks() + + try: + self.apply() + finally: + self.cancel() + + def cancel(self, event=None): + + # put focus back to the parent window + if self.parent is not None: + self.parent.focus_set() + self.destroy() + + # + # command hooks + + def validate(self): + '''validate the data + + This method is called automatically to validate the data before the + dialog is destroyed. By default, it always validates OK. + ''' + + return 1 # override + + def apply(self): + '''process the data + + This method is called automatically to process the data, *after* + the dialog is destroyed. By default, it does nothing. + ''' + + pass # override + + +# -------------------------------------------------------------------- +# convenience dialogues + +class _QueryDialog(Dialog): + + def __init__(self, title, prompt, + initialvalue=None, + minvalue = None, maxvalue = None, + parent = None): + + if not parent: + import tkinter + parent = tkinter._default_root + + 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: + self.entry.insert(0, self.initialvalue) + self.entry.select_range(0, END) + + return self.entry + + def validate(self): + + import tkinter.messagebox as tkMessageBox + + try: + result = self.getresult() + except ValueError: + tkMessageBox.showwarning( + "Illegal value", + self.errormessage + "\nPlease try again", + parent = self + ) + return 0 + + if self.minvalue is not None and result < self.minvalue: + tkMessageBox.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: + tkMessageBox.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 int(self.entry.get()) + +def askinteger(title, prompt, **kw): + '''get an integer from the user + + Arguments: + + title -- the dialog title + prompt -- the label text + **kw -- see SimpleDialog class + + Return value is an integer + ''' + d = _QueryInteger(title, prompt, **kw) + return d.result + +class _QueryFloat(_QueryDialog): + errormessage = "Not a floating point value." + def getresult(self): + return float(self.entry.get()) + +def askfloat(title, prompt, **kw): + '''get a float from the user + + Arguments: + + title -- the dialog title + prompt -- the label text + **kw -- see SimpleDialog class + + Return value is a float + ''' + 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): + '''get a string from the user + + Arguments: + + title -- the dialog title + prompt -- the label text + **kw -- see SimpleDialog class + + Return value is a string + ''' + 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()) + t = Button(root, text='Test', command=doit) + t.pack() + q = Button(root, text='Quit', command=t.quit) + q.pack() + t.mainloop() + + # tkSimpleDialog.py tests + root.update() + 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")) + + test() Index: Lib/tkinter/constants.py =================================================================== --- Lib/tkinter/constants.py (revision 0) +++ Lib/tkinter/constants.py (revision 0) @@ -0,0 +1,110 @@ +# Symbolic constants for Tk + +# Booleans +NO=FALSE=OFF=0 +YES=TRUE=ON=1 + +# -anchor and -sticky +N='n' +S='s' +W='w' +E='e' +NW='nw' +SW='sw' +NE='ne' +SE='se' +NS='ns' +EW='ew' +NSEW='nsew' +CENTER='center' + +# -fill +NONE='none' +X='x' +Y='y' +BOTH='both' + +# -side +LEFT='left' +TOP='top' +RIGHT='right' +BOTTOM='bottom' + +# -relief +RAISED='raised' +SUNKEN='sunken' +FLAT='flat' +RIDGE='ridge' +GROOVE='groove' +SOLID = 'solid' + +# -orient +HORIZONTAL='horizontal' +VERTICAL='vertical' + +# -tabs +NUMERIC='numeric' + +# -wrap +CHAR='char' +WORD='word' + +# -align +BASELINE='baseline' + +# -bordermode +INSIDE='inside' +OUTSIDE='outside' + +# Special tags, marks and insert positions +SEL='sel' +SEL_FIRST='sel.first' +SEL_LAST='sel.last' +END='end' +INSERT='insert' +CURRENT='current' +ANCHOR='anchor' +ALL='all' # e.g. Canvas.delete(ALL) + +# Text widget and button states +NORMAL='normal' +DISABLED='disabled' +ACTIVE='active' +# Canvas state +HIDDEN='hidden' + +# Menu item types +CASCADE='cascade' +CHECKBUTTON='checkbutton' +COMMAND='command' +RADIOBUTTON='radiobutton' +SEPARATOR='separator' + +# Selection modes for list boxes +SINGLE='single' +BROWSE='browse' +MULTIPLE='multiple' +EXTENDED='extended' + +# Activestyle for list boxes +# NONE='none' is also valid +DOTBOX='dotbox' +UNDERLINE='underline' + +# Various canvas styles +PIESLICE='pieslice' +CHORD='chord' +ARC='arc' +FIRST='first' +LAST='last' +BUTT='butt' +PROJECTING='projecting' +ROUND='round' +BEVEL='bevel' +MITER='miter' + +# Arguments to xview/yview +MOVETO='moveto' +SCROLL='scroll' +UNITS='units' +PAGES='pages' Index: Lib/tkinter/scrolledtext.py =================================================================== --- Lib/tkinter/scrolledtext.py (revision 0) +++ Lib/tkinter/scrolledtext.py (revision 0) @@ -0,0 +1,43 @@ +# A ScrolledText widget feels like a text widget but also has a +# vertical scroll bar on its right. (Later, options may be added to +# add a horizontal bar as well, to make the bars disappear +# automatically when not needed, to move them to the other side of the +# window, etc.) +# +# Configuration options are passed to the Text widget. +# A Frame widget is inserted between the master and the text, to hold +# the Scrollbar widget. +# Most methods calls are inherited from the Text widget; Pack methods +# are redirected to the Frame widget however. + +from tkinter import * +from tkinter import _cnfmerge + +class ScrolledText(Text): + def __init__(self, master=None, cnf=None, **kw): + if cnf is None: + cnf = {} + if kw: + cnf = _cnfmerge((cnf, kw)) + fcnf = {} + for k in cnf.keys(): + if isinstance(k, type) or k == 'name': + fcnf[k] = cnf[k] + del cnf[k] + self.frame = Frame(master, **fcnf) + self.vbar = Scrollbar(self.frame, name='vbar') + self.vbar.pack(side=RIGHT, fill=Y) + cnf['name'] = 'text' + Text.__init__(self, self.frame, **cnf) + self.pack(side=LEFT, fill=BOTH, expand=1) + self['yscrollcommand'] = self.vbar.set + self.vbar['command'] = self.yview + + # Copy geometry methods of self.frame -- hack! + methods = Pack.__dict__.keys() + methods = methods + Grid.__dict__.keys() + methods = methods + Place.__dict__.keys() + + for m in methods: + if m[0] != '_' and m != 'config' and m != 'configure': + setattr(self, m, getattr(self.frame, m)) Index: Lib/tkinter/messagebox.py =================================================================== --- Lib/tkinter/messagebox.py (revision 0) +++ Lib/tkinter/messagebox.py (revision 0) @@ -0,0 +1,132 @@ +# tk common message boxes +# +# this module provides an interface to the native message boxes +# available in Tk 4.2 and newer. +# +# written by Fredrik Lundh, May 1997 +# + +# +# options (all have default values): +# +# - default: which button to make default (one of the reply codes) +# +# - icon: which icon to display (see below) +# +# - message: the message to display +# +# - parent: which window to place the dialog on top of +# +# - title: dialog title +# +# - type: dialog type; that is, which buttons to display (see below) +# + +from tkinter.commondialog import Dialog + +# +# constants + +# icons +ERROR = "error" +INFO = "info" +QUESTION = "question" +WARNING = "warning" + +# types +ABORTRETRYIGNORE = "abortretryignore" +OK = "ok" +OKCANCEL = "okcancel" +RETRYCANCEL = "retrycancel" +YESNO = "yesno" +YESNOCANCEL = "yesnocancel" + +# replies +ABORT = "abort" +RETRY = "retry" +IGNORE = "ignore" +OK = "ok" +CANCEL = "cancel" +YES = "yes" +NO = "no" + + +# +# message dialog class + +class Message(Dialog): + "A message box" + + command = "tk_messageBox" + + +# +# convenience stuff + +# Rename _icon and _type options to allow overriding them in options +def _show(title=None, message=None, _icon=None, _type=None, **options): + if _icon and "icon" not in options: options["icon"] = _icon + if _type and "type" not in options: options["type"] = _type + if title: options["title"] = title + if message: options["message"] = message + res = Message(**options).show() + # In some Tcl installations, Tcl converts yes/no into a boolean + if isinstance(res, bool): + if res: return YES + return NO + return res + +def showinfo(title=None, message=None, **options): + "Show an info message" + return _show(title, message, INFO, OK, **options) + +def showwarning(title=None, message=None, **options): + "Show a warning message" + return _show(title, message, WARNING, OK, **options) + +def showerror(title=None, message=None, **options): + "Show an error message" + return _show(title, message, ERROR, OK, **options) + +def askquestion(title=None, message=None, **options): + "Ask a question" + return _show(title, message, QUESTION, YESNO, **options) + +def askokcancel(title=None, message=None, **options): + "Ask if operation should proceed; return true if the answer is ok" + s = _show(title, message, QUESTION, OKCANCEL, **options) + return s == OK + +def askyesno(title=None, message=None, **options): + "Ask a question; return true if the answer is yes" + s = _show(title, message, QUESTION, YESNO, **options) + return s == YES + +def askyesnocancel(title=None, message=None, **options): + "Ask a question; return true if the answer is yes, None if cancelled." + s = _show(title, message, QUESTION, YESNOCANCEL, **options) + # s might be a Tcl index object, so convert it to a string + s = str(s) + if s == CANCEL: + return None + return s == YES + +def askretrycancel(title=None, message=None, **options): + "Ask if operation should be retried; return true if the answer is yes" + s = _show(title, message, WARNING, RETRYCANCEL, **options) + return s == RETRY + + +# -------------------------------------------------------------------- +# test stuff + +if __name__ == "__main__": + + print("info", showinfo("Spam", "Egg Information")) + print("warning", showwarning("Spam", "Egg Warning")) + print("error", showerror("Spam", "Egg Alert")) + print("question", askquestion("Spam", "Question?")) + print("proceed", askokcancel("Spam", "Proceed?")) + print("yes/no", askyesno("Spam", "Got it?")) + print("yes/no/cancel", askyesnocancel("Spam", "Want it?")) + print("try again", askretrycancel("Spam", "Try again?")) Index: Lib/tkinter/__init__.py =================================================================== --- Lib/tkinter/__init__.py (revision 0) +++ Lib/tkinter/__init__.py (revision 0) @@ -0,0 +1,3747 @@ +"""Wrapper functions for Tcl/Tk. + +Tkinter provides classes which allow the display, positioning and +control of widgets. Toplevel widgets are Tk and Toplevel. Other +widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton, +Checkbutton, Scale, Listbox, Scrollbar, OptionMenu, Spinbox +LabelFrame and PanedWindow. + +Properties of the widgets are specified with keyword arguments. +Keyword arguments have the same name as the corresponding resource +under Tk. + +Widgets are positioned with one of the geometry managers Place, Pack +or Grid. These managers can be called with methods place, pack, grid +available in every Widget. + +Actions are bound to events by resources (e.g. keyword argument +command) or with the method bind. + +Example (Hello, World): +import tkinter +from tkinter.constants import * +tk = tkinter.Tk() +frame = tkinter.Frame(tk, relief=RIDGE, borderwidth=2) +frame.pack(fill=BOTH,expand=1) +label = tkinter.Label(frame, text="Hello, World") +label.pack(fill=X, expand=1) +button = tkinter.Button(frame,text="Exit",command=tk.destroy) +button.pack(side=BOTTOM) +tk.mainloop() +""" + +__version__ = "$Revision: 62069 $" + +import sys +if sys.platform == "win32": + import _fix # Attempt to configure Tcl/Tk without requiring PATH +import _tkinter # If this fails your Python may not be configured for Tk +tkinter = _tkinter # b/w compat for export +TclError = _tkinter.TclError +from tkinter.constants import * +try: + import MacOS; _MacOS = MacOS; del MacOS +except ImportError: + _MacOS = None + +wantobjects = 1 + +TkVersion = float(_tkinter.TK_VERSION) +TclVersion = float(_tkinter.TCL_VERSION) + +READABLE = _tkinter.READABLE +WRITABLE = _tkinter.WRITABLE +EXCEPTION = _tkinter.EXCEPTION + +# These are not always defined, e.g. not on Win32 with Tk 8.0 :-( +try: _tkinter.createfilehandler +except AttributeError: _tkinter.createfilehandler = None +try: _tkinter.deletefilehandler +except AttributeError: _tkinter.deletefilehandler = None + + +def _flatten(seq): + """Internal function.""" + res = () + for item in seq: + if isinstance(item, (tuple, list)): + res = res + _flatten(item) + elif item is not None: + res = res + (item,) + return res + +try: _flatten = _tkinter._flatten +except AttributeError: pass + +def _cnfmerge(cnfs): + """Internal function.""" + if isinstance(cnfs, dict): + return cnfs + elif isinstance(cnfs, (type(None), str)): + return cnfs + else: + cnf = {} + for c in _flatten(cnfs): + try: + cnf.update(c) + except (AttributeError, TypeError) as msg: + print("_cnfmerge: fallback due to:", msg) + for k, v in c.items(): + cnf[k] = v + return cnf + +try: _cnfmerge = _tkinter._cnfmerge +except AttributeError: pass + +class Event: + """Container for the properties of an event. + + Instances of this type are generated if one of the following events occurs: + + KeyPress, KeyRelease - for keyboard events + ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events + Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate, + Colormap, Gravity, Reparent, Property, Destroy, Activate, + Deactivate - for window events. + + If a callback function for one of these events is registered + using bind, bind_all, bind_class, or tag_bind, the callback is + called with an Event as first argument. It will have the + following attributes (in braces are the event types for which + the attribute is valid): + + serial - serial number of event + num - mouse button pressed (ButtonPress, ButtonRelease) + focus - whether the window has the focus (Enter, Leave) + height - height of the exposed window (Configure, Expose) + width - width of the exposed window (Configure, Expose) + keycode - keycode of the pressed key (KeyPress, KeyRelease) + state - state of the event as a number (ButtonPress, ButtonRelease, + Enter, KeyPress, KeyRelease, + Leave, Motion) + state - state as a string (Visibility) + time - when the event occurred + x - x-position of the mouse + y - y-position of the mouse + x_root - x-position of the mouse on the screen + (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) + y_root - y-position of the mouse on the screen + (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) + char - pressed character (KeyPress, KeyRelease) + send_event - see X/Windows documentation + keysym - keysym of the event as a string (KeyPress, KeyRelease) + keysym_num - keysym of the event as a number (KeyPress, KeyRelease) + type - type of the event as a number + widget - widget in which the event occurred + delta - delta of wheel movement (MouseWheel) + """ + pass + +_support_default_root = 1 +_default_root = None + +def NoDefaultRoot(): + """Inhibit setting of default root window. + + Call this function to inhibit that the first instance of + Tk is used for windows without an explicit parent window. + """ + global _support_default_root + _support_default_root = 0 + global _default_root + _default_root = None + del _default_root + +def _tkerror(err): + """Internal function.""" + pass + +def _exit(code='0'): + """Internal function. Calling it will throw the exception SystemExit.""" + raise SystemExit(code) + +_varnum = 0 +class Variable: + """Class to define value holders for e.g. buttons. + + Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations + that constrain the type of the value returned from get().""" + _default = "" + def __init__(self, master=None, value=None, name=None): + """Construct a variable + + MASTER can be given as master widget. + VALUE is an optional value (defaults to "") + NAME is an optional Tcl name (defaults to PY_VARnum). + + If NAME matches an existing variable and VALUE is omitted + then the existing value is retained. + """ + global _varnum + if not master: + master = _default_root + self._master = master + self._tk = master.tk + if name: + self._name = name + else: + self._name = 'PY_VAR' + repr(_varnum) + _varnum += 1 + if value is not None: + self.set(value) + elif not self._tk.call("info", "exists", self._name): + self.set(self._default) + def __del__(self): + """Unset the variable in Tcl.""" + self._tk.globalunsetvar(self._name) + def __str__(self): + """Return the name of the variable in Tcl.""" + return self._name + def set(self, value): + """Set the variable to VALUE.""" + return self._tk.globalsetvar(self._name, value) + def get(self): + """Return value of variable.""" + return self._tk.globalgetvar(self._name) + def trace_variable(self, mode, callback): + """Define a trace callback for the variable. + + MODE is one of "r", "w", "u" for read, write, undefine. + CALLBACK must be a function which is called when + the variable is read, written or undefined. + + Return the name of the callback. + """ + cbname = self._master._register(callback) + self._tk.call("trace", "variable", self._name, mode, cbname) + return cbname + trace = trace_variable + def trace_vdelete(self, mode, cbname): + """Delete the trace callback for a variable. + + MODE is one of "r", "w", "u" for read, write, undefine. + CBNAME is the name of the callback returned from trace_variable or trace. + """ + self._tk.call("trace", "vdelete", self._name, mode, cbname) + self._master.deletecommand(cbname) + def trace_vinfo(self): + """Return all trace callback information.""" + return map(self._tk.split, self._tk.splitlist( + self._tk.call("trace", "vinfo", self._name))) + def __eq__(self, other): + """Comparison for equality (==). + + Note: if the Variable's master matters to behavior + also compare self._master == other._master + """ + return self.__class__.__name__ == other.__class__.__name__ \ + and self._name == other._name + +class StringVar(Variable): + """Value holder for strings variables.""" + _default = "" + def __init__(self, master=None, value=None, name=None): + """Construct a string variable. + + MASTER can be given as master widget. + VALUE is an optional value (defaults to "") + NAME is an optional Tcl name (defaults to PY_VARnum). + + If NAME matches an existing variable and VALUE is omitted + then the existing value is retained. + """ + Variable.__init__(self, master, value, name) + + def get(self): + """Return value of variable as string.""" + value = self._tk.globalgetvar(self._name) + if isinstance(value, str): + return value + return str(value) + +class IntVar(Variable): + """Value holder for integer variables.""" + _default = 0 + def __init__(self, master=None, value=None, name=None): + """Construct an integer variable. + + MASTER can be given as master widget. + VALUE is an optional value (defaults to 0) + NAME is an optional Tcl name (defaults to PY_VARnum). + + If NAME matches an existing variable and VALUE is omitted + then the existing value is retained. + """ + Variable.__init__(self, master, value, name) + + def set(self, value): + """Set the variable to value, converting booleans to integers.""" + if isinstance(value, bool): + value = int(value) + return Variable.set(self, value) + + def get(self): + """Return the value of the variable as an integer.""" + return getint(self._tk.globalgetvar(self._name)) + +class DoubleVar(Variable): + """Value holder for float variables.""" + _default = 0.0 + def __init__(self, master=None, value=None, name=None): + """Construct a float variable. + + MASTER can be given as master widget. + VALUE is an optional value (defaults to 0.0) + NAME is an optional Tcl name (defaults to PY_VARnum). + + If NAME matches an existing variable and VALUE is omitted + then the existing value is retained. + """ + Variable.__init__(self, master, value, name) + + def get(self): + """Return the value of the variable as a float.""" + return getdouble(self._tk.globalgetvar(self._name)) + +class BooleanVar(Variable): + """Value holder for boolean variables.""" + _default = False + def __init__(self, master=None, value=None, name=None): + """Construct a boolean variable. + + MASTER can be given as master widget. + VALUE is an optional value (defaults to False) + NAME is an optional Tcl name (defaults to PY_VARnum). + + If NAME matches an existing variable and VALUE is omitted + then the existing value is retained. + """ + Variable.__init__(self, master, value, name) + + def get(self): + """Return the value of the variable as a bool.""" + return self._tk.getboolean(self._tk.globalgetvar(self._name)) + +def mainloop(n=0): + """Run the main loop of Tcl.""" + _default_root.tk.mainloop(n) + +getint = int + +getdouble = float + +def getboolean(s): + """Convert true and false to integer values 1 and 0.""" + return _default_root.tk.getboolean(s) + +# Methods defined on both toplevel and interior widgets +class Misc: + """Internal class. + + Base class which defines methods common for interior widgets.""" + + # XXX font command? + _tclCommands = None + def destroy(self): + """Internal function. + + Delete all Tcl commands created for + this widget in the Tcl interpreter.""" + if self._tclCommands is not None: + for name in self._tclCommands: + #print '- Tkinter: deleted command', name + self.tk.deletecommand(name) + self._tclCommands = None + def deletecommand(self, name): + """Internal function. + + Delete the Tcl command provided in NAME.""" + #print '- Tkinter: deleted command', name + self.tk.deletecommand(name) + try: + self._tclCommands.remove(name) + except ValueError: + pass + def tk_strictMotif(self, boolean=None): + """Set Tcl internal variable, whether the look and feel + should adhere to Motif. + + A parameter of 1 means adhere to Motif (e.g. no color + change if mouse passes over slider). + Returns the set value.""" + return self.tk.getboolean(self.tk.call( + 'set', 'tk_strictMotif', boolean)) + def tk_bisque(self): + """Change the color scheme to light brown as used in Tk 3.6 and before.""" + self.tk.call('tk_bisque') + def tk_setPalette(self, *args, **kw): + """Set a new color scheme for all widget elements. + + A single color as argument will cause that all colors of Tk + widget elements are derived from this. + Alternatively several keyword parameters and its associated + colors can be given. The following keywords are valid: + activeBackground, foreground, selectColor, + activeForeground, highlightBackground, selectBackground, + background, highlightColor, selectForeground, + disabledForeground, insertBackground, troughColor.""" + self.tk.call(('tk_setPalette',) + + _flatten(args) + _flatten(kw.items())) + def tk_menuBar(self, *args): + """Do not use. Needed in Tk 3.6 and earlier.""" + pass # obsolete since Tk 4.0 + def wait_variable(self, name='PY_VAR'): + """Wait until the variable is modified. + + A parameter of type IntVar, StringVar, DoubleVar or + BooleanVar must be given.""" + self.tk.call('tkwait', 'variable', name) + waitvar = wait_variable # XXX b/w compat + def wait_window(self, window=None): + """Wait until a WIDGET is destroyed. + + If no parameter is given self is used.""" + if window is None: + window = self + self.tk.call('tkwait', 'window', window._w) + def wait_visibility(self, window=None): + """Wait until the visibility of a WIDGET changes + (e.g. it appears). + + If no parameter is given self is used.""" + if window is None: + window = self + self.tk.call('tkwait', 'visibility', window._w) + def setvar(self, name='PY_VAR', value='1'): + """Set Tcl variable NAME to VALUE.""" + self.tk.setvar(name, value) + def getvar(self, name='PY_VAR'): + """Return value of Tcl variable NAME.""" + return self.tk.getvar(name) + getint = int + getdouble = float + def getboolean(self, s): + """Return a boolean value for Tcl boolean values true and false given as parameter.""" + return self.tk.getboolean(s) + def focus_set(self): + """Direct input focus to this widget. + + If the application currently does not have the focus + this widget will get the focus if the application gets + the focus through the window manager.""" + self.tk.call('focus', self._w) + focus = focus_set # XXX b/w compat? + def focus_force(self): + """Direct input focus to this widget even if the + application does not have the focus. Use with + caution!""" + self.tk.call('focus', '-force', self._w) + def focus_get(self): + """Return the widget which has currently the focus in the + application. + + Use focus_displayof to allow working with several + displays. Return None if application does not have + the focus.""" + name = self.tk.call('focus') + if name == 'none' or not name: return None + return self._nametowidget(name) + def focus_displayof(self): + """Return the widget which has currently the focus on the + display where this widget is located. + + Return None if the application does not have the focus.""" + name = self.tk.call('focus', '-displayof', self._w) + if name == 'none' or not name: return None + return self._nametowidget(name) + def focus_lastfor(self): + """Return the widget which would have the focus if top level + for this widget gets the focus from the window manager.""" + name = self.tk.call('focus', '-lastfor', self._w) + if name == 'none' or not name: return None + return self._nametowidget(name) + def tk_focusFollowsMouse(self): + """The widget under mouse will get automatically focus. Can not + be disabled easily.""" + self.tk.call('tk_focusFollowsMouse') + def tk_focusNext(self): + """Return the next widget in the focus order which follows + widget which has currently the focus. + + The focus order first goes to the next child, then to + the children of the child recursively and then to the + next sibling which is higher in the stacking order. A + widget is omitted if it has the takefocus resource set + to 0.""" + name = self.tk.call('tk_focusNext', self._w) + if not name: return None + return self._nametowidget(name) + def tk_focusPrev(self): + """Return previous widget in the focus order. See tk_focusNext for details.""" + name = self.tk.call('tk_focusPrev', self._w) + if not name: return None + return self._nametowidget(name) + def after(self, ms, func=None, *args): + """Call function once after given time. + + MS specifies the time in milliseconds. FUNC gives the + function which shall be called. Additional parameters + are given as parameters to the function call. Return + identifier to cancel scheduling with after_cancel.""" + if not func: + # I'd rather use time.sleep(ms*0.001) + self.tk.call('after', ms) + else: + def callit(): + try: + func(*args) + finally: + try: + self.deletecommand(name) + except TclError: + pass + name = self._register(callit) + return self.tk.call('after', ms, name) + def after_idle(self, func, *args): + """Call FUNC once if the Tcl main loop has no event to + process. + + Return an identifier to cancel the scheduling with + after_cancel.""" + return self.after('idle', func, *args) + def after_cancel(self, id): + """Cancel scheduling of function identified with ID. + + Identifier returned by after or after_idle must be + given as first parameter.""" + try: + data = self.tk.call('after', 'info', id) + # In Tk 8.3, splitlist returns: (script, type) + # In Tk 8.4, splitlist may return (script, type) or (script,) + script = self.tk.splitlist(data)[0] + self.deletecommand(script) + except TclError: + pass + self.tk.call('after', 'cancel', id) + def bell(self, displayof=0): + """Ring a display's bell.""" + self.tk.call(('bell',) + self._displayof(displayof)) + + # Clipboard handling: + def clipboard_get(self, **kw): + """Retrieve data from the clipboard on window's display. + + The window keyword defaults to the root window of the Tkinter + application. + + The type keyword specifies the form in which the data is + to be returned and should be an atom name such as STRING + or FILE_NAME. Type defaults to STRING. + + This command is equivalent to: + + selection_get(CLIPBOARD) + """ + return self.tk.call(('clipboard', 'get') + self._options(kw)) + + def clipboard_clear(self, **kw): + """Clear the data in the Tk clipboard. + + A widget specified for the optional displayof keyword + argument specifies the target display.""" + if 'displayof' not in kw: kw['displayof'] = self._w + self.tk.call(('clipboard', 'clear') + self._options(kw)) + def clipboard_append(self, string, **kw): + """Append STRING to the Tk clipboard. + + A widget specified at the optional displayof keyword + argument specifies the target display. The clipboard + can be retrieved with selection_get.""" + if 'displayof' not in kw: kw['displayof'] = self._w + self.tk.call(('clipboard', 'append') + self._options(kw) + + ('--', string)) + # XXX grab current w/o window argument + def grab_current(self): + """Return widget which has currently the grab in this application + or None.""" + name = self.tk.call('grab', 'current', self._w) + if not name: return None + return self._nametowidget(name) + def grab_release(self): + """Release grab for this widget if currently set.""" + self.tk.call('grab', 'release', self._w) + def grab_set(self): + """Set grab for this widget. + + A grab directs all events to this and descendant + widgets in the application.""" + self.tk.call('grab', 'set', self._w) + def grab_set_global(self): + """Set global grab for this widget. + + A global grab directs all events to this and + descendant widgets on the display. Use with caution - + other applications do not get events anymore.""" + self.tk.call('grab', 'set', '-global', self._w) + def grab_status(self): + """Return None, "local" or "global" if this widget has + no, a local or a global grab.""" + status = self.tk.call('grab', 'status', self._w) + if status == 'none': status = None + return status + def option_add(self, pattern, value, priority = None): + """Set a VALUE (second parameter) for an option + PATTERN (first parameter). + + An optional third parameter gives the numeric priority + (defaults to 80).""" + self.tk.call('option', 'add', pattern, value, priority) + def option_clear(self): + """Clear the option database. + + It will be reloaded if option_add is called.""" + self.tk.call('option', 'clear') + def option_get(self, name, className): + """Return the value for an option NAME for this widget + with CLASSNAME. + + Values with higher priority override lower values.""" + return self.tk.call('option', 'get', self._w, name, className) + def option_readfile(self, fileName, priority = None): + """Read file FILENAME into the option database. + + An optional second parameter gives the numeric + priority.""" + self.tk.call('option', 'readfile', fileName, priority) + def selection_clear(self, **kw): + """Clear the current X selection.""" + if 'displayof' not in kw: kw['displayof'] = self._w + self.tk.call(('selection', 'clear') + self._options(kw)) + def selection_get(self, **kw): + """Return the contents of the current X selection. + + A keyword parameter selection specifies the name of + the selection and defaults to PRIMARY. A keyword + parameter displayof specifies a widget on the display + to use.""" + if 'displayof' not in kw: kw['displayof'] = self._w + return self.tk.call(('selection', 'get') + self._options(kw)) + def selection_handle(self, command, **kw): + """Specify a function COMMAND to call if the X + selection owned by this widget is queried by another + application. + + This function must return the contents of the + selection. The function will be called with the + arguments OFFSET and LENGTH which allows the chunking + of very long selections. The following keyword + parameters can be provided: + selection - name of the selection (default PRIMARY), + type - type of the selection (e.g. STRING, FILE_NAME).""" + name = self._register(command) + self.tk.call(('selection', 'handle') + self._options(kw) + + (self._w, name)) + def selection_own(self, **kw): + """Become owner of X selection. + + A keyword parameter selection specifies the name of + the selection (default PRIMARY).""" + self.tk.call(('selection', 'own') + + self._options(kw) + (self._w,)) + def selection_own_get(self, **kw): + """Return owner of X selection. + + The following keyword parameter can + be provided: + selection - name of the selection (default PRIMARY), + type - type of the selection (e.g. STRING, FILE_NAME).""" + if 'displayof' not in kw: kw['displayof'] = self._w + name = self.tk.call(('selection', 'own') + self._options(kw)) + if not name: return None + return self._nametowidget(name) + def send(self, interp, cmd, *args): + """Send Tcl command CMD to different interpreter INTERP to be executed.""" + return self.tk.call(('send', interp, cmd) + args) + def lower(self, belowThis=None): + """Lower this widget in the stacking order.""" + self.tk.call('lower', self._w, belowThis) + def tkraise(self, aboveThis=None): + """Raise this widget in the stacking order.""" + self.tk.call('raise', self._w, aboveThis) + lift = tkraise + def colormodel(self, value=None): + """Useless. Not implemented in Tk.""" + return self.tk.call('tk', 'colormodel', self._w, value) + def winfo_atom(self, name, displayof=0): + """Return integer which represents atom NAME.""" + args = ('winfo', 'atom') + self._displayof(displayof) + (name,) + return getint(self.tk.call(args)) + def winfo_atomname(self, id, displayof=0): + """Return name of atom with identifier ID.""" + args = ('winfo', 'atomname') \ + + self._displayof(displayof) + (id,) + return self.tk.call(args) + def winfo_cells(self): + """Return number of cells in the colormap for this widget.""" + return getint( + self.tk.call('winfo', 'cells', self._w)) + def winfo_children(self): + """Return a list of all widgets which are children of this widget.""" + result = [] + for child in self.tk.splitlist( + self.tk.call('winfo', 'children', self._w)): + try: + # Tcl sometimes returns extra windows, e.g. for + # menus; those need to be skipped + result.append(self._nametowidget(child)) + except KeyError: + pass + return result + + def winfo_class(self): + """Return window class name of this widget.""" + return self.tk.call('winfo', 'class', self._w) + def winfo_colormapfull(self): + """Return true if at the last color request the colormap was full.""" + return self.tk.getboolean( + self.tk.call('winfo', 'colormapfull', self._w)) + def winfo_containing(self, rootX, rootY, displayof=0): + """Return the widget which is at the root coordinates ROOTX, ROOTY.""" + args = ('winfo', 'containing') \ + + self._displayof(displayof) + (rootX, rootY) + name = self.tk.call(args) + if not name: return None + return self._nametowidget(name) + def winfo_depth(self): + """Return the number of bits per pixel.""" + return getint(self.tk.call('winfo', 'depth', self._w)) + def winfo_exists(self): + """Return true if this widget exists.""" + return getint( + self.tk.call('winfo', 'exists', self._w)) + def winfo_fpixels(self, number): + """Return the number of pixels for the given distance NUMBER + (e.g. "3c") as float.""" + return getdouble(self.tk.call( + 'winfo', 'fpixels', self._w, number)) + def winfo_geometry(self): + """Return geometry string for this widget in the form "widthxheight+X+Y".""" + return self.tk.call('winfo', 'geometry', self._w) + def winfo_height(self): + """Return height of this widget.""" + return getint( + self.tk.call('winfo', 'height', self._w)) + def winfo_id(self): + """Return identifier ID for this widget.""" + return self.tk.getint( + self.tk.call('winfo', 'id', self._w)) + def winfo_interps(self, displayof=0): + """Return the name of all Tcl interpreters for this display.""" + args = ('winfo', 'interps') + self._displayof(displayof) + return self.tk.splitlist(self.tk.call(args)) + def winfo_ismapped(self): + """Return true if this widget is mapped.""" + return getint( + self.tk.call('winfo', 'ismapped', self._w)) + def winfo_manager(self): + """Return the window mananger name for this widget.""" + return self.tk.call('winfo', 'manager', self._w) + def winfo_name(self): + """Return the name of this widget.""" + return self.tk.call('winfo', 'name', self._w) + def winfo_parent(self): + """Return the name of the parent of this widget.""" + return self.tk.call('winfo', 'parent', self._w) + def winfo_pathname(self, id, displayof=0): + """Return the pathname of the widget given by ID.""" + args = ('winfo', 'pathname') \ + + self._displayof(displayof) + (id,) + return self.tk.call(args) + def winfo_pixels(self, number): + """Rounded integer value of winfo_fpixels.""" + return getint( + self.tk.call('winfo', 'pixels', self._w, number)) + def winfo_pointerx(self): + """Return the x coordinate of the pointer on the root window.""" + return getint( + self.tk.call('winfo', 'pointerx', self._w)) + def winfo_pointerxy(self): + """Return a tuple of x and y coordinates of the pointer on the root window.""" + return self._getints( + self.tk.call('winfo', 'pointerxy', self._w)) + def winfo_pointery(self): + """Return the y coordinate of the pointer on the root window.""" + return getint( + self.tk.call('winfo', 'pointery', self._w)) + def winfo_reqheight(self): + """Return requested height of this widget.""" + return getint( + self.tk.call('winfo', 'reqheight', self._w)) + def winfo_reqwidth(self): + """Return requested width of this widget.""" + return getint( + self.tk.call('winfo', 'reqwidth', self._w)) + def winfo_rgb(self, color): + """Return tuple of decimal values for red, green, blue for + COLOR in this widget.""" + return self._getints( + self.tk.call('winfo', 'rgb', self._w, color)) + def winfo_rootx(self): + """Return x coordinate of upper left corner of this widget on the + root window.""" + return getint( + self.tk.call('winfo', 'rootx', self._w)) + def winfo_rooty(self): + """Return y coordinate of upper left corner of this widget on the + root window.""" + return getint( + self.tk.call('winfo', 'rooty', self._w)) + def winfo_screen(self): + """Return the screen name of this widget.""" + return self.tk.call('winfo', 'screen', self._w) + def winfo_screencells(self): + """Return the number of the cells in the colormap of the screen + of this widget.""" + return getint( + self.tk.call('winfo', 'screencells', self._w)) + def winfo_screendepth(self): + """Return the number of bits per pixel of the root window of the + screen of this widget.""" + return getint( + self.tk.call('winfo', 'screendepth', self._w)) + def winfo_screenheight(self): + """Return the number of pixels of the height of the screen of this widget + in pixel.""" + return getint( + self.tk.call('winfo', 'screenheight', self._w)) + def winfo_screenmmheight(self): + """Return the number of pixels of the height of the screen of + this widget in mm.""" + return getint( + self.tk.call('winfo', 'screenmmheight', self._w)) + def winfo_screenmmwidth(self): + """Return the number of pixels of the width of the screen of + this widget in mm.""" + return getint( + self.tk.call('winfo', 'screenmmwidth', self._w)) + def winfo_screenvisual(self): + """Return one of the strings directcolor, grayscale, pseudocolor, + staticcolor, staticgray, or truecolor for the default + colormodel of this screen.""" + return self.tk.call('winfo', 'screenvisual', self._w) + def winfo_screenwidth(self): + """Return the number of pixels of the width of the screen of + this widget in pixel.""" + return getint( + self.tk.call('winfo', 'screenwidth', self._w)) + def winfo_server(self): + """Return information of the X-Server of the screen of this widget in + the form "XmajorRminor vendor vendorVersion".""" + return self.tk.call('winfo', 'server', self._w) + def winfo_toplevel(self): + """Return the toplevel widget of this widget.""" + return self._nametowidget(self.tk.call( + 'winfo', 'toplevel', self._w)) + def winfo_viewable(self): + """Return true if the widget and all its higher ancestors are mapped.""" + return getint( + self.tk.call('winfo', 'viewable', self._w)) + def winfo_visual(self): + """Return one of the strings directcolor, grayscale, pseudocolor, + staticcolor, staticgray, or truecolor for the + colormodel of this widget.""" + return self.tk.call('winfo', 'visual', self._w) + def winfo_visualid(self): + """Return the X identifier for the visual for this widget.""" + return self.tk.call('winfo', 'visualid', self._w) + def winfo_visualsavailable(self, includeids=0): + """Return a list of all visuals available for the screen + of this widget. + + Each item in the list consists of a visual name (see winfo_visual), a + depth and if INCLUDEIDS=1 is given also the X identifier.""" + data = self.tk.split( + self.tk.call('winfo', 'visualsavailable', self._w, + includeids and 'includeids' or None)) + if isinstance(data, str): + data = [self.tk.split(data)] + return map(self.__winfo_parseitem, data) + def __winfo_parseitem(self, t): + """Internal function.""" + return t[:1] + tuple(map(self.__winfo_getint, t[1:])) + def __winfo_getint(self, x): + """Internal function.""" + return int(x, 0) + def winfo_vrootheight(self): + """Return the height of the virtual root window associated with this + widget in pixels. If there is no virtual root window return the + height of the screen.""" + return getint( + self.tk.call('winfo', 'vrootheight', self._w)) + def winfo_vrootwidth(self): + """Return the width of the virtual root window associated with this + widget in pixel. If there is no virtual root window return the + width of the screen.""" + return getint( + self.tk.call('winfo', 'vrootwidth', self._w)) + def winfo_vrootx(self): + """Return the x offset of the virtual root relative to the root + window of the screen of this widget.""" + return getint( + self.tk.call('winfo', 'vrootx', self._w)) + def winfo_vrooty(self): + """Return the y offset of the virtual root relative to the root + window of the screen of this widget.""" + return getint( + self.tk.call('winfo', 'vrooty', self._w)) + def winfo_width(self): + """Return the width of this widget.""" + return getint( + self.tk.call('winfo', 'width', self._w)) + def winfo_x(self): + """Return the x coordinate of the upper left corner of this widget + in the parent.""" + return getint( + self.tk.call('winfo', 'x', self._w)) + def winfo_y(self): + """Return the y coordinate of the upper left corner of this widget + in the parent.""" + return getint( + self.tk.call('winfo', 'y', self._w)) + def update(self): + """Enter event loop until all pending events have been processed by Tcl.""" + self.tk.call('update') + def update_idletasks(self): + """Enter event loop until all idle callbacks have been called. This + will update the display of windows but not process events caused by + the user.""" + self.tk.call('update', 'idletasks') + def bindtags(self, tagList=None): + """Set or get the list of bindtags for this widget. + + With no argument return the list of all bindtags associated with + this widget. With a list of strings as argument the bindtags are + set to this list. The bindtags determine in which order events are + processed (see bind).""" + if tagList is None: + return self.tk.splitlist( + self.tk.call('bindtags', self._w)) + else: + self.tk.call('bindtags', self._w, tagList) + def _bind(self, what, sequence, func, add, needcleanup=1): + """Internal function.""" + if isinstance(func, str): + self.tk.call(what + (sequence, func)) + elif func: + funcid = self._register(func, self._substitute, + needcleanup) + cmd = ('%sif {"[%s %s]" == "break"} break\n' + % + (add and '+' or '', + funcid, self._subst_format_str)) + self.tk.call(what + (sequence, cmd)) + return funcid + elif sequence: + return self.tk.call(what + (sequence,)) + else: + return self.tk.splitlist(self.tk.call(what)) + def bind(self, sequence=None, func=None, add=None): + """Bind to this widget at event SEQUENCE a call to function FUNC. + + SEQUENCE is a string of concatenated event + patterns. An event pattern is of the form + where MODIFIER is one + of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4, + Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3, + B3, Alt, Button4, B4, Double, Button5, B5 Triple, + Mod1, M1. TYPE is one of Activate, Enter, Map, + ButtonPress, Button, Expose, Motion, ButtonRelease + FocusIn, MouseWheel, Circulate, FocusOut, Property, + Colormap, Gravity Reparent, Configure, KeyPress, Key, + Unmap, Deactivate, KeyRelease Visibility, Destroy, + Leave and DETAIL is the button number for ButtonPress, + ButtonRelease and DETAIL is the Keysym for KeyPress and + KeyRelease. Examples are + for pressing Control and mouse button 1 or + for pressing A and the Alt key (KeyPress can be omitted). + An event pattern can also be a virtual event of the form + <> where AString can be arbitrary. This + event can be generated by event_generate. + If events are concatenated they must appear shortly + after each other. + + FUNC will be called if the event sequence occurs with an + instance of Event as argument. If the return value of FUNC is + "break" no further bound function is invoked. + + An additional boolean parameter ADD specifies whether FUNC will + be called additionally to the other bound function or whether + it will replace the previous function. + + Bind will return an identifier to allow deletion of the bound function with + unbind without memory leak. + + If FUNC or SEQUENCE is omitted the bound function or list + of bound events are returned.""" + + return self._bind(('bind', self._w), sequence, func, add) + def unbind(self, sequence, funcid=None): + """Unbind for this widget for event SEQUENCE the + function identified with FUNCID.""" + self.tk.call('bind', self._w, sequence, '') + if funcid: + self.deletecommand(funcid) + def bind_all(self, sequence=None, func=None, add=None): + """Bind to all widgets at an event SEQUENCE a call to function FUNC. + An additional boolean parameter ADD specifies whether FUNC will + be called additionally to the other bound function or whether + it will replace the previous function. See bind for the return value.""" + return self._bind(('bind', 'all'), sequence, func, add, 0) + def unbind_all(self, sequence): + """Unbind for all widgets for event SEQUENCE all functions.""" + self.tk.call('bind', 'all' , sequence, '') + def bind_class(self, className, sequence=None, func=None, add=None): + + """Bind to widgets with bindtag CLASSNAME at event + SEQUENCE a call of function FUNC. An additional + boolean parameter ADD specifies whether FUNC will be + called additionally to the other bound function or + whether it will replace the previous function. See bind for + the return value.""" + + return self._bind(('bind', className), sequence, func, add, 0) + def unbind_class(self, className, sequence): + """Unbind for a all widgets with bindtag CLASSNAME for event SEQUENCE + all functions.""" + self.tk.call('bind', className , sequence, '') + def mainloop(self, n=0): + """Call the mainloop of Tk.""" + self.tk.mainloop(n) + def quit(self): + """Quit the Tcl interpreter. All widgets will be destroyed.""" + self.tk.quit() + def _getints(self, string): + """Internal function.""" + if string: + return tuple(map(getint, self.tk.splitlist(string))) + def _getdoubles(self, string): + """Internal function.""" + if string: + return tuple(map(getdouble, self.tk.splitlist(string))) + def _getboolean(self, string): + """Internal function.""" + if string: + return self.tk.getboolean(string) + def _displayof(self, displayof): + """Internal function.""" + if displayof: + return ('-displayof', displayof) + if displayof is None: + return ('-displayof', self._w) + return () + def _options(self, cnf, kw = None): + """Internal function.""" + if kw: + cnf = _cnfmerge((cnf, kw)) + else: + cnf = _cnfmerge(cnf) + res = () + for k, v in cnf.items(): + if v is not None: + if k[-1] == '_': k = k[:-1] + if hasattr(v, '__call__'): + v = self._register(v) + res = res + ('-'+k, v) + return res + def nametowidget(self, name): + """Return the Tkinter instance of a widget identified by + its Tcl name NAME.""" + w = self + if name[0] == '.': + w = w._root() + name = name[1:] + while name: + i = name.find('.') + if i >= 0: + name, tail = name[:i], name[i+1:] + else: + tail = '' + w = w.children[name] + name = tail + return w + _nametowidget = nametowidget + def _register(self, func, subst=None, needcleanup=1): + """Return a newly created Tcl function. If this + function is called, the Python function FUNC will + be executed. An optional function SUBST can + be given which will be executed before FUNC.""" + f = CallWrapper(func, subst, self).__call__ + name = repr(id(f)) + try: + func = func.__func__ + except AttributeError: + pass + try: + name = name + func.__name__ + except AttributeError: + pass + self.tk.createcommand(name, f) + if needcleanup: + if self._tclCommands is None: + self._tclCommands = [] + self._tclCommands.append(name) + #print '+ Tkinter created command', name + return name + register = _register + def _root(self): + """Internal function.""" + w = self + while w.master: w = w.master + return w + _subst_format = ('%#', '%b', '%f', '%h', '%k', + '%s', '%t', '%w', '%x', '%y', + '%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D') + _subst_format_str = " ".join(_subst_format) + def _substitute(self, *args): + """Internal function.""" + if len(args) != len(self._subst_format): return args + getboolean = self.tk.getboolean + + getint = int + def getint_event(s): + """Tk changed behavior in 8.4.2, returning "??" rather more often.""" + try: + return int(s) + except ValueError: + return s + + nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args + # Missing: (a, c, d, m, o, v, B, R) + e = Event() + # serial field: valid vor all events + # number of button: ButtonPress and ButtonRelease events only + # height field: Configure, ConfigureRequest, Create, + # ResizeRequest, and Expose events only + # keycode field: KeyPress and KeyRelease events only + # time field: "valid for events that contain a time field" + # width field: Configure, ConfigureRequest, Create, ResizeRequest, + # and Expose events only + # x field: "valid for events that contain a x field" + # y field: "valid for events that contain a y field" + # keysym as decimal: KeyPress and KeyRelease events only + # x_root, y_root fields: ButtonPress, ButtonRelease, KeyPress, + # KeyRelease,and Motion events + e.serial = getint(nsign) + e.num = getint_event(b) + try: e.focus = getboolean(f) + except TclError: pass + e.height = getint_event(h) + e.keycode = getint_event(k) + e.state = getint_event(s) + e.time = getint_event(t) + e.width = getint_event(w) + e.x = getint_event(x) + e.y = getint_event(y) + e.char = A + try: e.send_event = getboolean(E) + except TclError: pass + e.keysym = K + e.keysym_num = getint_event(N) + e.type = T + try: + e.widget = self._nametowidget(W) + except KeyError: + e.widget = W + e.x_root = getint_event(X) + e.y_root = getint_event(Y) + try: + e.delta = getint(D) + except ValueError: + e.delta = 0 + return (e,) + def _report_exception(self): + """Internal function.""" + import sys + exc, val, tb = sys.exc_info() + root = self._root() + root.report_callback_exception(exc, val, tb) + def _configure(self, cmd, cnf, kw): + """Internal function.""" + if kw: + cnf = _cnfmerge((cnf, kw)) + elif cnf: + cnf = _cnfmerge(cnf) + if cnf is None: + cnf = {} + for x in self.tk.split( + self.tk.call(_flatten((self._w, cmd)))): + cnf[x[0][1:]] = (x[0][1:],) + x[1:] + return cnf + if isinstance(cnf, str): + x = self.tk.split( + self.tk.call(_flatten((self._w, cmd, '-'+cnf)))) + return (x[0][1:],) + x[1:] + self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) + # These used to be defined in Widget: + def configure(self, cnf=None, **kw): + """Configure resources of a widget. + + The values for resources are specified as keyword + arguments. To get an overview about + the allowed keyword arguments call the method keys. + """ + return self._configure('configure', cnf, kw) + config = configure + def cget(self, key): + """Return the resource value for a KEY given as string.""" + return self.tk.call(self._w, 'cget', '-' + key) + __getitem__ = cget + def __setitem__(self, key, value): + self.configure({key: value}) + def keys(self): + """Return a list of all resource names of this widget.""" + return map(lambda x: x[0][1:], + self.tk.split(self.tk.call(self._w, 'configure'))) + def __str__(self): + """Return the window path name of this widget.""" + return self._w + # Pack methods that apply to the master + _noarg_ = ['_noarg_'] + def pack_propagate(self, flag=_noarg_): + """Set or get the status for propagation of geometry information. + + A boolean argument specifies whether the geometry information + of the slaves will determine the size of this widget. If no argument + is given the current setting will be returned. + """ + if flag is Misc._noarg_: + return self._getboolean(self.tk.call( + 'pack', 'propagate', self._w)) + else: + self.tk.call('pack', 'propagate', self._w, flag) + propagate = pack_propagate + def pack_slaves(self): + """Return a list of all slaves of this widget + in its packing order.""" + return map(self._nametowidget, + self.tk.splitlist( + self.tk.call('pack', 'slaves', self._w))) + slaves = pack_slaves + # Place method that applies to the master + def place_slaves(self): + """Return a list of all slaves of this widget + in its packing order.""" + return map(self._nametowidget, + self.tk.splitlist( + self.tk.call( + 'place', 'slaves', self._w))) + # Grid methods that apply to the master + def grid_bbox(self, column=None, row=None, col2=None, row2=None): + """Return a tuple of integer coordinates for the bounding + box of this widget controlled by the geometry manager grid. + + If COLUMN, ROW is given the bounding box applies from + the cell with row and column 0 to the specified + cell. If COL2 and ROW2 are given the bounding box + starts at that cell. + + The returned integers specify the offset of the upper left + corner in the master widget and the width and height. + """ + args = ('grid', 'bbox', self._w) + if column is not None and row is not None: + args = args + (column, row) + if col2 is not None and row2 is not None: + args = args + (col2, row2) + return self._getints(self.tk.call(*args)) or None + + bbox = grid_bbox + def _grid_configure(self, command, index, cnf, kw): + """Internal function.""" + if isinstance(cnf, str) and not kw: + if cnf[-1:] == '_': + cnf = cnf[:-1] + if cnf[:1] != '-': + cnf = '-'+cnf + options = (cnf,) + else: + options = self._options(cnf, kw) + if not options: + res = self.tk.call('grid', + command, self._w, index) + words = self.tk.splitlist(res) + dict = {} + for i in range(0, len(words), 2): + key = words[i][1:] + value = words[i+1] + if not value: + value = None + elif '.' in value: + value = getdouble(value) + else: + value = getint(value) + dict[key] = value + return dict + res = self.tk.call( + ('grid', command, self._w, index) + + options) + if len(options) == 1: + if not res: return None + # In Tk 7.5, -width can be a float + if '.' in res: return getdouble(res) + return getint(res) + def grid_columnconfigure(self, index, cnf={}, **kw): + """Configure column INDEX of a grid. + + Valid resources are minsize (minimum size of the column), + weight (how much does additional space propagate to this column) + and pad (how much space to let additionally).""" + return self._grid_configure('columnconfigure', index, cnf, kw) + columnconfigure = grid_columnconfigure + def grid_location(self, x, y): + """Return a tuple of column and row which identify the cell + at which the pixel at position X and Y inside the master + widget is located.""" + return self._getints( + self.tk.call( + 'grid', 'location', self._w, x, y)) or None + def grid_propagate(self, flag=_noarg_): + """Set or get the status for propagation of geometry information. + + A boolean argument specifies whether the geometry information + of the slaves will determine the size of this widget. If no argument + is given, the current setting will be returned. + """ + if flag is Misc._noarg_: + return self._getboolean(self.tk.call( + 'grid', 'propagate', self._w)) + else: + self.tk.call('grid', 'propagate', self._w, flag) + def grid_rowconfigure(self, index, cnf={}, **kw): + """Configure row INDEX of a grid. + + Valid resources are minsize (minimum size of the row), + weight (how much does additional space propagate to this row) + and pad (how much space to let additionally).""" + return self._grid_configure('rowconfigure', index, cnf, kw) + rowconfigure = grid_rowconfigure + def grid_size(self): + """Return a tuple of the number of column and rows in the grid.""" + return self._getints( + self.tk.call('grid', 'size', self._w)) or None + size = grid_size + def grid_slaves(self, row=None, column=None): + """Return a list of all slaves of this widget + in its packing order.""" + args = () + if row is not None: + args = args + ('-row', row) + if column is not None: + args = args + ('-column', column) + return map(self._nametowidget, + self.tk.splitlist(self.tk.call( + ('grid', 'slaves', self._w) + args))) + + # Support for the "event" command, new in Tk 4.2. + # By Case Roole. + + def event_add(self, virtual, *sequences): + """Bind a virtual event VIRTUAL (of the form <>) + to an event SEQUENCE such that the virtual event is triggered + whenever SEQUENCE occurs.""" + args = ('event', 'add', virtual) + sequences + self.tk.call(args) + + def event_delete(self, virtual, *sequences): + """Unbind a virtual event VIRTUAL from SEQUENCE.""" + args = ('event', 'delete', virtual) + sequences + self.tk.call(args) + + def event_generate(self, sequence, **kw): + """Generate an event SEQUENCE. Additional + keyword arguments specify parameter of the event + (e.g. x, y, rootx, rooty).""" + args = ('event', 'generate', self._w, sequence) + for k, v in kw.items(): + args = args + ('-%s' % k, str(v)) + self.tk.call(args) + + def event_info(self, virtual=None): + """Return a list of all virtual events or the information + about the SEQUENCE bound to the virtual event VIRTUAL.""" + return self.tk.splitlist( + self.tk.call('event', 'info', virtual)) + + # Image related commands + + def image_names(self): + """Return a list of all existing image names.""" + return self.tk.call('image', 'names') + + def image_types(self): + """Return a list of all available image types (e.g. phote bitmap).""" + return self.tk.call('image', 'types') + + +class CallWrapper: + """Internal class. Stores function to call when some user + defined Tcl function is called e.g. after an event occurred.""" + def __init__(self, func, subst, widget): + """Store FUNC, SUBST and WIDGET as members.""" + self.func = func + self.subst = subst + self.widget = widget + def __call__(self, *args): + """Apply first function SUBST to arguments, than FUNC.""" + try: + if self.subst: + args = self.subst(*args) + return self.func(*args) + except SystemExit as msg: + raise SystemExit(msg) + except: + self.widget._report_exception() + + +class Wm: + """Provides functions for the communication with the window manager.""" + + def wm_aspect(self, + minNumer=None, minDenom=None, + maxNumer=None, maxDenom=None): + """Instruct the window manager to set the aspect ratio (width/height) + of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple + of the actual values if no argument is given.""" + return self._getints( + self.tk.call('wm', 'aspect', self._w, + minNumer, minDenom, + maxNumer, maxDenom)) + aspect = wm_aspect + + def wm_attributes(self, *args): + """This subcommand returns or sets platform specific attributes + + The first form returns a list of the platform specific flags and + their values. The second form returns the value for the specific + option. The third form sets one or more of the values. The values + are as follows: + + On Windows, -disabled gets or sets whether the window is in a + disabled state. -toolwindow gets or sets the style of the window + to toolwindow (as defined in the MSDN). -topmost gets or sets + whether this is a topmost window (displays above all other + windows). + + On Macintosh, XXXXX + + On Unix, there are currently no special attribute values. + """ + args = ('wm', 'attributes', self._w) + args + return self.tk.call(args) + attributes=wm_attributes + + def wm_client(self, name=None): + """Store NAME in WM_CLIENT_MACHINE property of this widget. Return + current value.""" + return self.tk.call('wm', 'client', self._w, name) + client = wm_client + def wm_colormapwindows(self, *wlist): + """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property + of this widget. This list contains windows whose colormaps differ from their + parents. Return current list of widgets if WLIST is empty.""" + if len(wlist) > 1: + wlist = (wlist,) # Tk needs a list of windows here + args = ('wm', 'colormapwindows', self._w) + wlist + return map(self._nametowidget, self.tk.call(args)) + colormapwindows = wm_colormapwindows + def wm_command(self, value=None): + """Store VALUE in WM_COMMAND property. It is the command + which shall be used to invoke the application. Return current + command if VALUE is None.""" + return self.tk.call('wm', 'command', self._w, value) + command = wm_command + def wm_deiconify(self): + """Deiconify this widget. If it was never mapped it will not be mapped. + On Windows it will raise this widget and give it the focus.""" + return self.tk.call('wm', 'deiconify', self._w) + deiconify = wm_deiconify + def wm_focusmodel(self, model=None): + """Set focus model to MODEL. "active" means that this widget will claim + the focus itself, "passive" means that the window manager shall give + the focus. Return current focus model if MODEL is None.""" + return self.tk.call('wm', 'focusmodel', self._w, model) + focusmodel = wm_focusmodel + def wm_frame(self): + """Return identifier for decorative frame of this widget if present.""" + return self.tk.call('wm', 'frame', self._w) + frame = wm_frame + def wm_geometry(self, newGeometry=None): + """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return + current value if None is given.""" + return self.tk.call('wm', 'geometry', self._w, newGeometry) + geometry = wm_geometry + def wm_grid(self, + baseWidth=None, baseHeight=None, + widthInc=None, heightInc=None): + """Instruct the window manager that this widget shall only be + resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and + height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the + number of grid units requested in Tk_GeometryRequest.""" + return self._getints(self.tk.call( + 'wm', 'grid', self._w, + baseWidth, baseHeight, widthInc, heightInc)) + grid = wm_grid + def wm_group(self, pathName=None): + """Set the group leader widgets for related widgets to PATHNAME. Return + the group leader of this widget if None is given.""" + return self.tk.call('wm', 'group', self._w, pathName) + group = wm_group + def wm_iconbitmap(self, bitmap=None, default=None): + """Set bitmap for the iconified widget to BITMAP. Return + the bitmap if None is given. + + Under Windows, the DEFAULT parameter can be used to set the icon + for the widget and any descendents that don't have an icon set + explicitly. DEFAULT can be the relative path to a .ico file + (example: root.iconbitmap(default='myicon.ico') ). See Tk + documentation for more information.""" + if default: + return self.tk.call('wm', 'iconbitmap', self._w, '-default', default) + else: + return self.tk.call('wm', 'iconbitmap', self._w, bitmap) + iconbitmap = wm_iconbitmap + def wm_iconify(self): + """Display widget as icon.""" + return self.tk.call('wm', 'iconify', self._w) + iconify = wm_iconify + def wm_iconmask(self, bitmap=None): + """Set mask for the icon bitmap of this widget. Return the + mask if None is given.""" + return self.tk.call('wm', 'iconmask', self._w, bitmap) + iconmask = wm_iconmask + def wm_iconname(self, newName=None): + """Set the name of the icon for this widget. Return the name if + None is given.""" + return self.tk.call('wm', 'iconname', self._w, newName) + iconname = wm_iconname + def wm_iconposition(self, x=None, y=None): + """Set the position of the icon of this widget to X and Y. Return + a tuple of the current values of X and X if None is given.""" + return self._getints(self.tk.call( + 'wm', 'iconposition', self._w, x, y)) + iconposition = wm_iconposition + def wm_iconwindow(self, pathName=None): + """Set widget PATHNAME to be displayed instead of icon. Return the current + value if None is given.""" + return self.tk.call('wm', 'iconwindow', self._w, pathName) + iconwindow = wm_iconwindow + def wm_maxsize(self, width=None, height=None): + """Set max WIDTH and HEIGHT for this widget. If the window is gridded + the values are given in grid units. Return the current values if None + is given.""" + return self._getints(self.tk.call( + 'wm', 'maxsize', self._w, width, height)) + maxsize = wm_maxsize + def wm_minsize(self, width=None, height=None): + """Set min WIDTH and HEIGHT for this widget. If the window is gridded + the values are given in grid units. Return the current values if None + is given.""" + return self._getints(self.tk.call( + 'wm', 'minsize', self._w, width, height)) + minsize = wm_minsize + def wm_overrideredirect(self, boolean=None): + """Instruct the window manager to ignore this widget + if BOOLEAN is given with 1. Return the current value if None + is given.""" + return self._getboolean(self.tk.call( + 'wm', 'overrideredirect', self._w, boolean)) + overrideredirect = wm_overrideredirect + def wm_positionfrom(self, who=None): + """Instruct the window manager that the position of this widget shall + be defined by the user if WHO is "user", and by its own policy if WHO is + "program".""" + return self.tk.call('wm', 'positionfrom', self._w, who) + positionfrom = wm_positionfrom + def wm_protocol(self, name=None, func=None): + """Bind function FUNC to command NAME for this widget. + Return the function bound to NAME if None is given. NAME could be + e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW".""" + if hasattr(func, '__call__'): + command = self._register(func) + else: + command = func + return self.tk.call( + 'wm', 'protocol', self._w, name, command) + protocol = wm_protocol + def wm_resizable(self, width=None, height=None): + """Instruct the window manager whether this width can be resized + in WIDTH or HEIGHT. Both values are boolean values.""" + return self.tk.call('wm', 'resizable', self._w, width, height) + resizable = wm_resizable + def wm_sizefrom(self, who=None): + """Instruct the window manager that the size of this widget shall + be defined by the user if WHO is "user", and by its own policy if WHO is + "program".""" + return self.tk.call('wm', 'sizefrom', self._w, who) + sizefrom = wm_sizefrom + def wm_state(self, newstate=None): + """Query or set the state of this widget as one of normal, icon, + iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only).""" + return self.tk.call('wm', 'state', self._w, newstate) + state = wm_state + def wm_title(self, string=None): + """Set the title of this widget.""" + return self.tk.call('wm', 'title', self._w, string) + title = wm_title + def wm_transient(self, master=None): + """Instruct the window manager that this widget is transient + with regard to widget MASTER.""" + return self.tk.call('wm', 'transient', self._w, master) + transient = wm_transient + def wm_withdraw(self): + """Withdraw this widget from the screen such that it is unmapped + and forgotten by the window manager. Re-draw it with wm_deiconify.""" + return self.tk.call('wm', 'withdraw', self._w) + withdraw = wm_withdraw + + +class Tk(Misc, Wm): + """Toplevel widget of Tk which represents mostly the main window + of an appliation. It has an associated Tcl interpreter.""" + _w = '.' + def __init__(self, screenName=None, baseName=None, className='Tk', + useTk=1, sync=0, use=None): + """Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will + be created. BASENAME will be used for the identification of the profile file (see + readprofile). + It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME + is the name of the widget class.""" + self.master = None + self.children = {} + self._tkloaded = 0 + # to avoid recursions in the getattr code in case of failure, we + # ensure that self.tk is always _something_. + self.tk = None + if baseName is None: + import sys, os + baseName = os.path.basename(sys.argv[0]) + baseName, ext = os.path.splitext(baseName) + if ext not in ('.py', '.pyc', '.pyo'): + baseName = baseName + ext + interactive = 0 + self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use) + if useTk: + self._loadtk() + self.readprofile(baseName, className) + def loadtk(self): + if not self._tkloaded: + self.tk.loadtk() + self._loadtk() + def _loadtk(self): + self._tkloaded = 1 + global _default_root + if _MacOS and hasattr(_MacOS, 'SchedParams'): + # Disable event scanning except for Command-Period + _MacOS.SchedParams(1, 0) + # Work around nasty MacTk bug + # XXX Is this one still needed? + self.update() + # Version sanity checks + tk_version = self.tk.getvar('tk_version') + if tk_version != _tkinter.TK_VERSION: + raise RuntimeError("tk.h version (%s) doesn't match libtk.a version (%s)" + % (_tkinter.TK_VERSION, tk_version)) + # Under unknown circumstances, tcl_version gets coerced to float + tcl_version = str(self.tk.getvar('tcl_version')) + if tcl_version != _tkinter.TCL_VERSION: + raise RuntimeError("tcl.h version (%s) doesn't match libtcl.a version (%s)" \ + % (_tkinter.TCL_VERSION, tcl_version)) + if TkVersion < 4.0: + raise RuntimeError("Tk 4.0 or higher is required; found Tk %s" + % str(TkVersion)) + # Create and register the tkerror and exit commands + # We need to inline parts of _register here, _ register + # would register differently-named commands. + if self._tclCommands is None: + self._tclCommands = [] + self.tk.createcommand('tkerror', _tkerror) + self.tk.createcommand('exit', _exit) + self._tclCommands.append('tkerror') + self._tclCommands.append('exit') + if _support_default_root and not _default_root: + _default_root = self + self.protocol("WM_DELETE_WINDOW", self.destroy) + def destroy(self): + """Destroy this and all descendants widgets. This will + end the application of this Tcl interpreter.""" + for c in list(self.children.values()): c.destroy() + self.tk.call('destroy', self._w) + Misc.destroy(self) + global _default_root + if _support_default_root and _default_root is self: + _default_root = None + def readprofile(self, baseName, className): + """Internal function. It reads BASENAME.tcl and CLASSNAME.tcl into + the Tcl Interpreter and calls exec on the contents of BASENAME.py and + CLASSNAME.py if such a file exists in the home directory.""" + import os + if 'HOME' in os.environ: home = os.environ['HOME'] + else: home = os.curdir + class_tcl = os.path.join(home, '.%s.tcl' % className) + class_py = os.path.join(home, '.%s.py' % className) + base_tcl = os.path.join(home, '.%s.tcl' % baseName) + base_py = os.path.join(home, '.%s.py' % baseName) + dir = {'self': self} + exec('from tkinter import *', dir) + if os.path.isfile(class_tcl): + self.tk.call('source', class_tcl) + if os.path.isfile(class_py): + exec(open(class_py).read(), dir) + if os.path.isfile(base_tcl): + self.tk.call('source', base_tcl) + if os.path.isfile(base_py): + exec(open(base_py).read(), dir) + def report_callback_exception(self, exc, val, tb): + """Internal function. It reports exception on sys.stderr.""" + import traceback, sys + sys.stderr.write("Exception in Tkinter callback\n") + sys.last_type = exc + sys.last_value = val + sys.last_traceback = tb + traceback.print_exception(exc, val, tb) + def __getattr__(self, attr): + "Delegate attribute access to the interpreter object" + return getattr(self.tk, attr) + +# Ideally, the classes Pack, Place and Grid disappear, the +# pack/place/grid methods are defined on the Widget class, and +# everybody uses w.pack_whatever(...) instead of Pack.whatever(w, +# ...), with pack(), place() and grid() being short for +# pack_configure(), place_configure() and grid_columnconfigure(), and +# forget() being short for pack_forget(). As a practical matter, I'm +# afraid that there is too much code out there that may be using the +# Pack, Place or Grid class, so I leave them intact -- but only as +# backwards compatibility features. Also note that those methods that +# take a master as argument (e.g. pack_propagate) have been moved to +# the Misc class (which now incorporates all methods common between +# toplevel and interior widgets). Again, for compatibility, these are +# copied into the Pack, Place or Grid class. + + +def Tcl(screenName=None, baseName=None, className='Tk', useTk=0): + return Tk(screenName, baseName, className, useTk) + +class Pack: + """Geometry manager Pack. + + Base class to use the methods pack_* in every widget.""" + def pack_configure(self, cnf={}, **kw): + """Pack a widget in the parent widget. Use as options: + after=widget - pack it after you have packed widget + anchor=NSEW (or subset) - position widget according to + given direction + before=widget - pack it before you will pack widget + expand=bool - expand widget if parent size grows + fill=NONE or X or Y or BOTH - fill widget if widget grows + in=master - use master to contain this widget + ipadx=amount - add internal padding in x direction + ipady=amount - add internal padding in y direction + padx=amount - add padding in x direction + pady=amount - add padding in y direction + side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget. + """ + self.tk.call( + ('pack', 'configure', self._w) + + self._options(cnf, kw)) + pack = configure = config = pack_configure + def pack_forget(self): + """Unmap this widget and do not use it for the packing order.""" + self.tk.call('pack', 'forget', self._w) + forget = pack_forget + def pack_info(self): + """Return information about the packing options + for this widget.""" + words = self.tk.splitlist( + self.tk.call('pack', 'info', self._w)) + dict = {} + for i in range(0, len(words), 2): + key = words[i][1:] + value = words[i+1] + if value[:1] == '.': + value = self._nametowidget(value) + dict[key] = value + return dict + info = pack_info + propagate = pack_propagate = Misc.pack_propagate + slaves = pack_slaves = Misc.pack_slaves + +class Place: + """Geometry manager Place. + + Base class to use the methods place_* in every widget.""" + def place_configure(self, cnf={}, **kw): + """Place a widget in the parent widget. Use as options: + in=master - master relative to which the widget is placed. + x=amount - locate anchor of this widget at position x of master + y=amount - locate anchor of this widget at position y of master + relx=amount - locate anchor of this widget between 0.0 and 1.0 + relative to width of master (1.0 is right edge) + rely=amount - locate anchor of this widget between 0.0 and 1.0 + relative to height of master (1.0 is bottom edge) + anchor=NSEW (or subset) - position anchor according to given direction + width=amount - width of this widget in pixel + height=amount - height of this widget in pixel + relwidth=amount - width of this widget between 0.0 and 1.0 + relative to width of master (1.0 is the same width + as the master) + relheight=amount - height of this widget between 0.0 and 1.0 + relative to height of master (1.0 is the same + height as the master) + bordermode="inside" or "outside" - whether to take border width of master widget + into account + """ + for k in ['in_']: + if k in kw: + kw[k[:-1]] = kw[k] + del kw[k] + self.tk.call( + ('place', 'configure', self._w) + + self._options(cnf, kw)) + place = configure = config = place_configure + def place_forget(self): + """Unmap this widget.""" + self.tk.call('place', 'forget', self._w) + forget = place_forget + def place_info(self): + """Return information about the placing options + for this widget.""" + words = self.tk.splitlist( + self.tk.call('place', 'info', self._w)) + dict = {} + for i in range(0, len(words), 2): + key = words[i][1:] + value = words[i+1] + if value[:1] == '.': + value = self._nametowidget(value) + dict[key] = value + return dict + info = place_info + slaves = place_slaves = Misc.place_slaves + +class Grid: + """Geometry manager Grid. + + Base class to use the methods grid_* in every widget.""" + # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu) + def grid_configure(self, cnf={}, **kw): + """Position a widget in the parent widget in a grid. Use as options: + column=number - use cell identified with given column (starting with 0) + columnspan=number - this widget will span several columns + in=master - use master to contain this widget + ipadx=amount - add internal padding in x direction + ipady=amount - add internal padding in y direction + padx=amount - add padding in x direction + pady=amount - add padding in y direction + row=number - use cell identified with given row (starting with 0) + rowspan=number - this widget will span several rows + sticky=NSEW - if cell is larger on which sides will this + widget stick to the cell boundary + """ + self.tk.call( + ('grid', 'configure', self._w) + + self._options(cnf, kw)) + grid = configure = config = grid_configure + bbox = grid_bbox = Misc.grid_bbox + columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure + def grid_forget(self): + """Unmap this widget.""" + self.tk.call('grid', 'forget', self._w) + forget = grid_forget + def grid_remove(self): + """Unmap this widget but remember the grid options.""" + self.tk.call('grid', 'remove', self._w) + def grid_info(self): + """Return information about the options + for positioning this widget in a grid.""" + words = self.tk.splitlist( + self.tk.call('grid', 'info', self._w)) + dict = {} + for i in range(0, len(words), 2): + key = words[i][1:] + value = words[i+1] + if value[:1] == '.': + value = self._nametowidget(value) + dict[key] = value + return dict + info = grid_info + location = grid_location = Misc.grid_location + propagate = grid_propagate = Misc.grid_propagate + rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure + size = grid_size = Misc.grid_size + slaves = grid_slaves = Misc.grid_slaves + +class BaseWidget(Misc): + """Internal class.""" + def _setup(self, master, cnf): + """Internal function. Sets up information about children.""" + if _support_default_root: + global _default_root + if not master: + if not _default_root: + _default_root = Tk() + master = _default_root + self.master = master + self.tk = master.tk + name = None + if 'name' in cnf: + name = cnf['name'] + del cnf['name'] + if not name: + name = repr(id(self)) + self._name = name + if master._w=='.': + self._w = '.' + name + else: + self._w = master._w + '.' + name + self.children = {} + if self._name in self.master.children: + self.master.children[self._name].destroy() + self.master.children[self._name] = self + def __init__(self, master, widgetName, cnf={}, kw={}, extra=()): + """Construct a widget with the parent widget MASTER, a name WIDGETNAME + and appropriate options.""" + if kw: + cnf = _cnfmerge((cnf, kw)) + self.widgetName = widgetName + BaseWidget._setup(self, master, cnf) + classes = [] + for k in cnf.keys(): + if isinstance(k, type): + classes.append((k, cnf[k])) + del cnf[k] + self.tk.call( + (widgetName, self._w) + extra + self._options(cnf)) + for k, v in classes: + k.configure(self, v) + def destroy(self): + """Destroy this and all descendants widgets.""" + for c in list(self.children.values()): c.destroy() + self.tk.call('destroy', self._w) + if self._name in self.master.children: + del self.master.children[self._name] + Misc.destroy(self) + def _do(self, name, args=()): + # XXX Obsolete -- better use self.tk.call directly! + return self.tk.call((self._w, name) + args) + +class Widget(BaseWidget, Pack, Place, Grid): + """Internal class. + + Base class for a widget which can be positioned with the geometry managers + Pack, Place or Grid.""" + pass + +class Toplevel(BaseWidget, Wm): + """Toplevel widget, e.g. for dialogs.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a toplevel widget with the parent MASTER. + + Valid resource names: background, bd, bg, borderwidth, class, + colormap, container, cursor, height, highlightbackground, + highlightcolor, highlightthickness, menu, relief, screen, takefocus, + use, visual, width.""" + if kw: + cnf = _cnfmerge((cnf, kw)) + extra = () + for wmkey in ['screen', 'class_', 'class', 'visual', + 'colormap']: + if wmkey in cnf: + val = cnf[wmkey] + # TBD: a hack needed because some keys + # are not valid as keyword arguments + if wmkey[-1] == '_': opt = '-'+wmkey[:-1] + else: opt = '-'+wmkey + extra = extra + (opt, val) + del cnf[wmkey] + BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra) + root = self._root() + self.iconname(root.iconname()) + self.title(root.title()) + self.protocol("WM_DELETE_WINDOW", self.destroy) + +class Button(Widget): + """Button widget.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a button widget with the parent MASTER. + + STANDARD OPTIONS + + activebackground, activeforeground, anchor, + background, bitmap, borderwidth, cursor, + disabledforeground, font, foreground + highlightbackground, highlightcolor, + highlightthickness, image, justify, + padx, pady, relief, repeatdelay, + repeatinterval, takefocus, text, + textvariable, underline, wraplength + + WIDGET-SPECIFIC OPTIONS + + command, compound, default, height, + overrelief, state, width + """ + Widget.__init__(self, master, 'button', cnf, kw) + + def tkButtonEnter(self, *dummy): + self.tk.call('tkButtonEnter', self._w) + + def tkButtonLeave(self, *dummy): + self.tk.call('tkButtonLeave', self._w) + + def tkButtonDown(self, *dummy): + self.tk.call('tkButtonDown', self._w) + + def tkButtonUp(self, *dummy): + self.tk.call('tkButtonUp', self._w) + + def tkButtonInvoke(self, *dummy): + self.tk.call('tkButtonInvoke', self._w) + + def flash(self): + """Flash the button. + + This is accomplished by redisplaying + the button several times, alternating between active and + normal colors. At the end of the flash the button is left + in the same normal/active state as when the command was + invoked. This command is ignored if the button's state is + disabled. + """ + self.tk.call(self._w, 'flash') + + def invoke(self): + """Invoke the command associated with the button. + + The return value is the return value from the command, + or an empty string if there is no command associated with + the button. This command is ignored if the button's state + is disabled. + """ + return self.tk.call(self._w, 'invoke') + +# Indices: +# XXX I don't like these -- take them away +def AtEnd(): + return 'end' +def AtInsert(*args): + s = 'insert' + for a in args: + if a: s = s + (' ' + a) + return s +def AtSelFirst(): + return 'sel.first' +def AtSelLast(): + return 'sel.last' +def At(x, y=None): + if y is None: + return '@%r' % (x,) + else: + return '@%r,%r' % (x, y) + +class Canvas(Widget): + """Canvas widget to display graphical elements like lines or text.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a canvas widget with the parent MASTER. + + Valid resource names: background, bd, bg, borderwidth, closeenough, + confine, cursor, height, highlightbackground, highlightcolor, + highlightthickness, insertbackground, insertborderwidth, + insertofftime, insertontime, insertwidth, offset, relief, + scrollregion, selectbackground, selectborderwidth, selectforeground, + state, takefocus, width, xscrollcommand, xscrollincrement, + yscrollcommand, yscrollincrement.""" + Widget.__init__(self, master, 'canvas', cnf, kw) + def addtag(self, *args): + """Internal function.""" + self.tk.call((self._w, 'addtag') + args) + def addtag_above(self, newtag, tagOrId): + """Add tag NEWTAG to all items above TAGORID.""" + self.addtag(newtag, 'above', tagOrId) + def addtag_all(self, newtag): + """Add tag NEWTAG to all items.""" + self.addtag(newtag, 'all') + def addtag_below(self, newtag, tagOrId): + """Add tag NEWTAG to all items below TAGORID.""" + self.addtag(newtag, 'below', tagOrId) + def addtag_closest(self, newtag, x, y, halo=None, start=None): + """Add tag NEWTAG to item which is closest to pixel at X, Y. + If several match take the top-most. + All items closer than HALO are considered overlapping (all are + closests). If START is specified the next below this tag is taken.""" + self.addtag(newtag, 'closest', x, y, halo, start) + def addtag_enclosed(self, newtag, x1, y1, x2, y2): + """Add tag NEWTAG to all items in the rectangle defined + by X1,Y1,X2,Y2.""" + self.addtag(newtag, 'enclosed', x1, y1, x2, y2) + def addtag_overlapping(self, newtag, x1, y1, x2, y2): + """Add tag NEWTAG to all items which overlap the rectangle + defined by X1,Y1,X2,Y2.""" + self.addtag(newtag, 'overlapping', x1, y1, x2, y2) + def addtag_withtag(self, newtag, tagOrId): + """Add tag NEWTAG to all items with TAGORID.""" + self.addtag(newtag, 'withtag', tagOrId) + def bbox(self, *args): + """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle + which encloses all items with tags specified as arguments.""" + return self._getints( + self.tk.call((self._w, 'bbox') + args)) or None + def tag_unbind(self, tagOrId, sequence, funcid=None): + """Unbind for all items with TAGORID for event SEQUENCE the + function identified with FUNCID.""" + self.tk.call(self._w, 'bind', tagOrId, sequence, '') + if funcid: + self.deletecommand(funcid) + def tag_bind(self, tagOrId, sequence=None, func=None, add=None): + """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC. + + An additional boolean parameter ADD specifies whether FUNC will be + called additionally to the other bound function or whether it will + replace the previous function. See bind for the return value.""" + return self._bind((self._w, 'bind', tagOrId), + sequence, func, add) + def canvasx(self, screenx, gridspacing=None): + """Return the canvas x coordinate of pixel position SCREENX rounded + to nearest multiple of GRIDSPACING units.""" + return getdouble(self.tk.call( + self._w, 'canvasx', screenx, gridspacing)) + def canvasy(self, screeny, gridspacing=None): + """Return the canvas y coordinate of pixel position SCREENY rounded + to nearest multiple of GRIDSPACING units.""" + return getdouble(self.tk.call( + self._w, 'canvasy', screeny, gridspacing)) + def coords(self, *args): + """Return a list of coordinates for the item given in ARGS.""" + # XXX Should use _flatten on args + return map(getdouble, + self.tk.splitlist( + self.tk.call((self._w, 'coords') + args))) + def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={}) + """Internal function.""" + args = _flatten(args) + cnf = args[-1] + if isinstance(cnf, (dict, tuple)): + args = args[:-1] + else: + cnf = {} + return getint(self.tk.call( + self._w, 'create', itemType, + *(args + self._options(cnf, kw)))) + def create_arc(self, *args, **kw): + """Create arc shaped region with coordinates x1,y1,x2,y2.""" + return self._create('arc', args, kw) + def create_bitmap(self, *args, **kw): + """Create bitmap with coordinates x1,y1.""" + return self._create('bitmap', args, kw) + def create_image(self, *args, **kw): + """Create image item with coordinates x1,y1.""" + return self._create('image', args, kw) + def create_line(self, *args, **kw): + """Create line with coordinates x1,y1,...,xn,yn.""" + return self._create('line', args, kw) + def create_oval(self, *args, **kw): + """Create oval with coordinates x1,y1,x2,y2.""" + return self._create('oval', args, kw) + def create_polygon(self, *args, **kw): + """Create polygon with coordinates x1,y1,...,xn,yn.""" + return self._create('polygon', args, kw) + def create_rectangle(self, *args, **kw): + """Create rectangle with coordinates x1,y1,x2,y2.""" + return self._create('rectangle', args, kw) + def create_text(self, *args, **kw): + """Create text with coordinates x1,y1.""" + return self._create('text', args, kw) + def create_window(self, *args, **kw): + """Create window with coordinates x1,y1,x2,y2.""" + return self._create('window', args, kw) + def dchars(self, *args): + """Delete characters of text items identified by tag or id in ARGS (possibly + several times) from FIRST to LAST character (including).""" + self.tk.call((self._w, 'dchars') + args) + def delete(self, *args): + """Delete items identified by all tag or ids contained in ARGS.""" + self.tk.call((self._w, 'delete') + args) + def dtag(self, *args): + """Delete tag or id given as last arguments in ARGS from items + identified by first argument in ARGS.""" + self.tk.call((self._w, 'dtag') + args) + def find(self, *args): + """Internal function.""" + return self._getints( + self.tk.call((self._w, 'find') + args)) or () + def find_above(self, tagOrId): + """Return items above TAGORID.""" + return self.find('above', tagOrId) + def find_all(self): + """Return all items.""" + return self.find('all') + def find_below(self, tagOrId): + """Return all items below TAGORID.""" + return self.find('below', tagOrId) + def find_closest(self, x, y, halo=None, start=None): + """Return item which is closest to pixel at X, Y. + If several match take the top-most. + All items closer than HALO are considered overlapping (all are + closests). If START is specified the next below this tag is taken.""" + return self.find('closest', x, y, halo, start) + def find_enclosed(self, x1, y1, x2, y2): + """Return all items in rectangle defined + by X1,Y1,X2,Y2.""" + return self.find('enclosed', x1, y1, x2, y2) + def find_overlapping(self, x1, y1, x2, y2): + """Return all items which overlap the rectangle + defined by X1,Y1,X2,Y2.""" + return self.find('overlapping', x1, y1, x2, y2) + def find_withtag(self, tagOrId): + """Return all items with TAGORID.""" + return self.find('withtag', tagOrId) + def focus(self, *args): + """Set focus to the first item specified in ARGS.""" + return self.tk.call((self._w, 'focus') + args) + def gettags(self, *args): + """Return tags associated with the first item specified in ARGS.""" + return self.tk.splitlist( + self.tk.call((self._w, 'gettags') + args)) + def icursor(self, *args): + """Set cursor at position POS in the item identified by TAGORID. + In ARGS TAGORID must be first.""" + self.tk.call((self._w, 'icursor') + args) + def index(self, *args): + """Return position of cursor as integer in item specified in ARGS.""" + return getint(self.tk.call((self._w, 'index') + args)) + def insert(self, *args): + """Insert TEXT in item TAGORID at position POS. ARGS must + be TAGORID POS TEXT.""" + self.tk.call((self._w, 'insert') + args) + def itemcget(self, tagOrId, option): + """Return the resource value for an OPTION for item TAGORID.""" + return self.tk.call( + (self._w, 'itemcget') + (tagOrId, '-'+option)) + def itemconfigure(self, tagOrId, cnf=None, **kw): + """Configure resources of an item TAGORID. + + The values for resources are specified as keyword + arguments. To get an overview about + the allowed keyword arguments call the method without arguments. + """ + return self._configure(('itemconfigure', tagOrId), cnf, kw) + itemconfig = itemconfigure + # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift, + # so the preferred name for them is tag_lower, tag_raise + # (similar to tag_bind, and similar to the Text widget); + # unfortunately can't delete the old ones yet (maybe in 1.6) + def tag_lower(self, *args): + """Lower an item TAGORID given in ARGS + (optional below another item).""" + self.tk.call((self._w, 'lower') + args) + lower = tag_lower + def move(self, *args): + """Move an item TAGORID given in ARGS.""" + self.tk.call((self._w, 'move') + args) + def postscript(self, cnf={}, **kw): + """Print the contents of the canvas to a postscript + file. Valid options: colormap, colormode, file, fontmap, + height, pageanchor, pageheight, pagewidth, pagex, pagey, + rotate, witdh, x, y.""" + return self.tk.call((self._w, 'postscript') + + self._options(cnf, kw)) + def tag_raise(self, *args): + """Raise an item TAGORID given in ARGS + (optional above another item).""" + self.tk.call((self._w, 'raise') + args) + lift = tkraise = tag_raise + def scale(self, *args): + """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE.""" + self.tk.call((self._w, 'scale') + args) + def scan_mark(self, x, y): + """Remember the current X, Y coordinates.""" + self.tk.call(self._w, 'scan', 'mark', x, y) + def scan_dragto(self, x, y, gain=10): + """Adjust the view of the canvas to GAIN times the + difference between X and Y and the coordinates given in + scan_mark.""" + self.tk.call(self._w, 'scan', 'dragto', x, y, gain) + def select_adjust(self, tagOrId, index): + """Adjust the end of the selection near the cursor of an item TAGORID to index.""" + self.tk.call(self._w, 'select', 'adjust', tagOrId, index) + def select_clear(self): + """Clear the selection if it is in this widget.""" + self.tk.call(self._w, 'select', 'clear') + def select_from(self, tagOrId, index): + """Set the fixed end of a selection in item TAGORID to INDEX.""" + self.tk.call(self._w, 'select', 'from', tagOrId, index) + def select_item(self): + """Return the item which has the selection.""" + return self.tk.call(self._w, 'select', 'item') or None + def select_to(self, tagOrId, index): + """Set the variable end of a selection in item TAGORID to INDEX.""" + self.tk.call(self._w, 'select', 'to', tagOrId, index) + def type(self, tagOrId): + """Return the type of the item TAGORID.""" + return self.tk.call(self._w, 'type', tagOrId) or None + def xview(self, *args): + """Query and change horizontal position of the view.""" + if not args: + return self._getdoubles(self.tk.call(self._w, 'xview')) + self.tk.call((self._w, 'xview') + args) + def xview_moveto(self, fraction): + """Adjusts the view in the window so that FRACTION of the + total width of the canvas is off-screen to the left.""" + self.tk.call(self._w, 'xview', 'moveto', fraction) + def xview_scroll(self, number, what): + """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" + self.tk.call(self._w, 'xview', 'scroll', number, what) + def yview(self, *args): + """Query and change vertical position of the view.""" + if not args: + return self._getdoubles(self.tk.call(self._w, 'yview')) + self.tk.call((self._w, 'yview') + args) + def yview_moveto(self, fraction): + """Adjusts the view in the window so that FRACTION of the + total height of the canvas is off-screen to the top.""" + self.tk.call(self._w, 'yview', 'moveto', fraction) + def yview_scroll(self, number, what): + """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" + self.tk.call(self._w, 'yview', 'scroll', number, what) + +class Checkbutton(Widget): + """Checkbutton widget which is either in on- or off-state.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a checkbutton widget with the parent MASTER. + + Valid resource names: activebackground, activeforeground, anchor, + background, bd, bg, bitmap, borderwidth, command, cursor, + disabledforeground, fg, font, foreground, height, + highlightbackground, highlightcolor, highlightthickness, image, + indicatoron, justify, offvalue, onvalue, padx, pady, relief, + selectcolor, selectimage, state, takefocus, text, textvariable, + underline, variable, width, wraplength.""" + Widget.__init__(self, master, 'checkbutton', cnf, kw) + def deselect(self): + """Put the button in off-state.""" + self.tk.call(self._w, 'deselect') + def flash(self): + """Flash the button.""" + self.tk.call(self._w, 'flash') + def invoke(self): + """Toggle the button and invoke a command if given as resource.""" + return self.tk.call(self._w, 'invoke') + def select(self): + """Put the button in on-state.""" + self.tk.call(self._w, 'select') + def toggle(self): + """Toggle the button.""" + self.tk.call(self._w, 'toggle') + +class Entry(Widget): + """Entry widget which allows to display simple text.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct an entry widget with the parent MASTER. + + Valid resource names: background, bd, bg, borderwidth, cursor, + exportselection, fg, font, foreground, highlightbackground, + highlightcolor, highlightthickness, insertbackground, + insertborderwidth, insertofftime, insertontime, insertwidth, + invalidcommand, invcmd, justify, relief, selectbackground, + selectborderwidth, selectforeground, show, state, takefocus, + textvariable, validate, validatecommand, vcmd, width, + xscrollcommand.""" + Widget.__init__(self, master, 'entry', cnf, kw) + def delete(self, first, last=None): + """Delete text from FIRST to LAST (not included).""" + self.tk.call(self._w, 'delete', first, last) + def get(self): + """Return the text.""" + return self.tk.call(self._w, 'get') + def icursor(self, index): + """Insert cursor at INDEX.""" + self.tk.call(self._w, 'icursor', index) + def index(self, index): + """Return position of cursor.""" + return getint(self.tk.call( + self._w, 'index', index)) + def insert(self, index, string): + """Insert STRING at INDEX.""" + self.tk.call(self._w, 'insert', index, string) + def scan_mark(self, x): + """Remember the current X, Y coordinates.""" + self.tk.call(self._w, 'scan', 'mark', x) + def scan_dragto(self, x): + """Adjust the view of the canvas to 10 times the + difference between X and Y and the coordinates given in + scan_mark.""" + self.tk.call(self._w, 'scan', 'dragto', x) + def selection_adjust(self, index): + """Adjust the end of the selection near the cursor to INDEX.""" + self.tk.call(self._w, 'selection', 'adjust', index) + select_adjust = selection_adjust + def selection_clear(self): + """Clear the selection if it is in this widget.""" + self.tk.call(self._w, 'selection', 'clear') + select_clear = selection_clear + def selection_from(self, index): + """Set the fixed end of a selection to INDEX.""" + self.tk.call(self._w, 'selection', 'from', index) + select_from = selection_from + def selection_present(self): + """Return whether the widget has the selection.""" + return self.tk.getboolean( + self.tk.call(self._w, 'selection', 'present')) + select_present = selection_present + def selection_range(self, start, end): + """Set the selection from START to END (not included).""" + self.tk.call(self._w, 'selection', 'range', start, end) + select_range = selection_range + def selection_to(self, index): + """Set the variable end of a selection to INDEX.""" + self.tk.call(self._w, 'selection', 'to', index) + select_to = selection_to + def xview(self, index): + """Query and change horizontal position of the view.""" + self.tk.call(self._w, 'xview', index) + def xview_moveto(self, fraction): + """Adjust the view in the window so that FRACTION of the + total width of the entry is off-screen to the left.""" + self.tk.call(self._w, 'xview', 'moveto', fraction) + def xview_scroll(self, number, what): + """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" + self.tk.call(self._w, 'xview', 'scroll', number, what) + +class Frame(Widget): + """Frame widget which may contain other widgets and can have a 3D border.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a frame widget with the parent MASTER. + + Valid resource names: background, bd, bg, borderwidth, class, + colormap, container, cursor, height, highlightbackground, + highlightcolor, highlightthickness, relief, takefocus, visual, width.""" + cnf = _cnfmerge((cnf, kw)) + extra = () + if 'class_' in cnf: + extra = ('-class', cnf['class_']) + del cnf['class_'] + elif 'class' in cnf: + extra = ('-class', cnf['class']) + del cnf['class'] + Widget.__init__(self, master, 'frame', cnf, {}, extra) + +class Label(Widget): + """Label widget which can display text and bitmaps.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a label widget with the parent MASTER. + + STANDARD OPTIONS + + activebackground, activeforeground, anchor, + background, bitmap, borderwidth, cursor, + disabledforeground, font, foreground, + highlightbackground, highlightcolor, + highlightthickness, image, justify, + padx, pady, relief, takefocus, text, + textvariable, underline, wraplength + + WIDGET-SPECIFIC OPTIONS + + height, state, width + + """ + Widget.__init__(self, master, 'label', cnf, kw) + +class Listbox(Widget): + """Listbox widget which can display a list of strings.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a listbox widget with the parent MASTER. + + Valid resource names: background, bd, bg, borderwidth, cursor, + exportselection, fg, font, foreground, height, highlightbackground, + highlightcolor, highlightthickness, relief, selectbackground, + selectborderwidth, selectforeground, selectmode, setgrid, takefocus, + width, xscrollcommand, yscrollcommand, listvariable.""" + Widget.__init__(self, master, 'listbox', cnf, kw) + def activate(self, index): + """Activate item identified by INDEX.""" + self.tk.call(self._w, 'activate', index) + def bbox(self, *args): + """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle + which encloses the item identified by index in ARGS.""" + return self._getints( + self.tk.call((self._w, 'bbox') + args)) or None + def curselection(self): + """Return list of indices of currently selected item.""" + return self._getints(self.tk.call(self._w, 'curselection')) + def delete(self, first, last=None): + """Delete items from FIRST to LAST (not included).""" + self.tk.call(self._w, 'delete', first, last) + def get(self, first, last=None): + """Get list of items from FIRST to LAST (not included).""" + if last: + return self.tk.splitlist(self.tk.call( + self._w, 'get', first, last)) + else: + return self.tk.call(self._w, 'get', first) + def index(self, index): + """Return index of item identified with INDEX.""" + i = self.tk.call(self._w, 'index', index) + if i == 'none': return None + return getint(i) + def insert(self, index, *elements): + """Insert ELEMENTS at INDEX.""" + self.tk.call((self._w, 'insert', index) + elements) + def nearest(self, y): + """Get index of item which is nearest to y coordinate Y.""" + return getint(self.tk.call( + self._w, 'nearest', y)) + def scan_mark(self, x, y): + """Remember the current X, Y coordinates.""" + self.tk.call(self._w, 'scan', 'mark', x, y) + def scan_dragto(self, x, y): + """Adjust the view of the listbox to 10 times the + difference between X and Y and the coordinates given in + scan_mark.""" + self.tk.call(self._w, 'scan', 'dragto', x, y) + def see(self, index): + """Scroll such that INDEX is visible.""" + self.tk.call(self._w, 'see', index) + def selection_anchor(self, index): + """Set the fixed end oft the selection to INDEX.""" + self.tk.call(self._w, 'selection', 'anchor', index) + select_anchor = selection_anchor + def selection_clear(self, first, last=None): + """Clear the selection from FIRST to LAST (not included).""" + self.tk.call(self._w, + 'selection', 'clear', first, last) + select_clear = selection_clear + def selection_includes(self, index): + """Return 1 if INDEX is part of the selection.""" + return self.tk.getboolean(self.tk.call( + self._w, 'selection', 'includes', index)) + select_includes = selection_includes + def selection_set(self, first, last=None): + """Set the selection from FIRST to LAST (not included) without + changing the currently selected elements.""" + self.tk.call(self._w, 'selection', 'set', first, last) + select_set = selection_set + def size(self): + """Return the number of elements in the listbox.""" + return getint(self.tk.call(self._w, 'size')) + def xview(self, *what): + """Query and change horizontal position of the view.""" + if not what: + return self._getdoubles(self.tk.call(self._w, 'xview')) + self.tk.call((self._w, 'xview') + what) + def xview_moveto(self, fraction): + """Adjust the view in the window so that FRACTION of the + total width of the entry is off-screen to the left.""" + self.tk.call(self._w, 'xview', 'moveto', fraction) + def xview_scroll(self, number, what): + """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" + self.tk.call(self._w, 'xview', 'scroll', number, what) + def yview(self, *what): + """Query and change vertical position of the view.""" + if not what: + return self._getdoubles(self.tk.call(self._w, 'yview')) + self.tk.call((self._w, 'yview') + what) + def yview_moveto(self, fraction): + """Adjust the view in the window so that FRACTION of the + total width of the entry is off-screen to the top.""" + self.tk.call(self._w, 'yview', 'moveto', fraction) + def yview_scroll(self, number, what): + """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" + self.tk.call(self._w, 'yview', 'scroll', number, what) + def itemcget(self, index, option): + """Return the resource value for an ITEM and an OPTION.""" + return self.tk.call( + (self._w, 'itemcget') + (index, '-'+option)) + def itemconfigure(self, index, cnf=None, **kw): + """Configure resources of an ITEM. + + The values for resources are specified as keyword arguments. + To get an overview about the allowed keyword arguments + call the method without arguments. + Valid resource names: background, bg, foreground, fg, + selectbackground, selectforeground.""" + return self._configure(('itemconfigure', index), cnf, kw) + itemconfig = itemconfigure + +class Menu(Widget): + """Menu widget which allows to display menu bars, pull-down menus and pop-up menus.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct menu widget with the parent MASTER. + + Valid resource names: activebackground, activeborderwidth, + activeforeground, background, bd, bg, borderwidth, cursor, + disabledforeground, fg, font, foreground, postcommand, relief, + selectcolor, takefocus, tearoff, tearoffcommand, title, type.""" + Widget.__init__(self, master, 'menu', cnf, kw) + def tk_bindForTraversal(self): + pass # obsolete since Tk 4.0 + def tk_mbPost(self): + self.tk.call('tk_mbPost', self._w) + def tk_mbUnpost(self): + self.tk.call('tk_mbUnpost') + def tk_traverseToMenu(self, char): + self.tk.call('tk_traverseToMenu', self._w, char) + def tk_traverseWithinMenu(self, char): + self.tk.call('tk_traverseWithinMenu', self._w, char) + def tk_getMenuButtons(self): + return self.tk.call('tk_getMenuButtons', self._w) + def tk_nextMenu(self, count): + self.tk.call('tk_nextMenu', count) + def tk_nextMenuEntry(self, count): + self.tk.call('tk_nextMenuEntry', count) + def tk_invokeMenu(self): + self.tk.call('tk_invokeMenu', self._w) + def tk_firstMenu(self): + self.tk.call('tk_firstMenu', self._w) + def tk_mbButtonDown(self): + self.tk.call('tk_mbButtonDown', self._w) + def tk_popup(self, x, y, entry=""): + """Post the menu at position X,Y with entry ENTRY.""" + self.tk.call('tk_popup', self._w, x, y, entry) + def activate(self, index): + """Activate entry at INDEX.""" + self.tk.call(self._w, 'activate', index) + def add(self, itemType, cnf={}, **kw): + """Internal function.""" + self.tk.call((self._w, 'add', itemType) + + self._options(cnf, kw)) + def add_cascade(self, cnf={}, **kw): + """Add hierarchical menu item.""" + self.add('cascade', cnf or kw) + def add_checkbutton(self, cnf={}, **kw): + """Add checkbutton menu item.""" + self.add('checkbutton', cnf or kw) + def add_command(self, cnf={}, **kw): + """Add command menu item.""" + self.add('command', cnf or kw) + def add_radiobutton(self, cnf={}, **kw): + """Addd radio menu item.""" + self.add('radiobutton', cnf or kw) + def add_separator(self, cnf={}, **kw): + """Add separator.""" + self.add('separator', cnf or kw) + def insert(self, index, itemType, cnf={}, **kw): + """Internal function.""" + self.tk.call((self._w, 'insert', index, itemType) + + self._options(cnf, kw)) + def insert_cascade(self, index, cnf={}, **kw): + """Add hierarchical menu item at INDEX.""" + self.insert(index, 'cascade', cnf or kw) + def insert_checkbutton(self, index, cnf={}, **kw): + """Add checkbutton menu item at INDEX.""" + self.insert(index, 'checkbutton', cnf or kw) + def insert_command(self, index, cnf={}, **kw): + """Add command menu item at INDEX.""" + self.insert(index, 'command', cnf or kw) + def insert_radiobutton(self, index, cnf={}, **kw): + """Addd radio menu item at INDEX.""" + self.insert(index, 'radiobutton', cnf or kw) + def insert_separator(self, index, cnf={}, **kw): + """Add separator at INDEX.""" + self.insert(index, 'separator', cnf or kw) + def delete(self, index1, index2=None): + """Delete menu items between INDEX1 and INDEX2 (not included).""" + self.tk.call(self._w, 'delete', index1, index2) + def entrycget(self, index, option): + """Return the resource value of an menu item for OPTION at INDEX.""" + return self.tk.call(self._w, 'entrycget', index, '-' + option) + def entryconfigure(self, index, cnf=None, **kw): + """Configure a menu item at INDEX.""" + return self._configure(('entryconfigure', index), cnf, kw) + entryconfig = entryconfigure + def index(self, index): + """Return the index of a menu item identified by INDEX.""" + i = self.tk.call(self._w, 'index', index) + if i == 'none': return None + return getint(i) + def invoke(self, index): + """Invoke a menu item identified by INDEX and execute + the associated command.""" + return self.tk.call(self._w, 'invoke', index) + def post(self, x, y): + """Display a menu at position X,Y.""" + self.tk.call(self._w, 'post', x, y) + def type(self, index): + """Return the type of the menu item at INDEX.""" + return self.tk.call(self._w, 'type', index) + def unpost(self): + """Unmap a menu.""" + self.tk.call(self._w, 'unpost') + def yposition(self, index): + """Return the y-position of the topmost pixel of the menu item at INDEX.""" + return getint(self.tk.call( + self._w, 'yposition', index)) + +class Menubutton(Widget): + """Menubutton widget, obsolete since Tk8.0.""" + def __init__(self, master=None, cnf={}, **kw): + Widget.__init__(self, master, 'menubutton', cnf, kw) + +class Message(Widget): + """Message widget to display multiline text. Obsolete since Label does it too.""" + def __init__(self, master=None, cnf={}, **kw): + Widget.__init__(self, master, 'message', cnf, kw) + +class Radiobutton(Widget): + """Radiobutton widget which shows only one of several buttons in on-state.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a radiobutton widget with the parent MASTER. + + Valid resource names: activebackground, activeforeground, anchor, + background, bd, bg, bitmap, borderwidth, command, cursor, + disabledforeground, fg, font, foreground, height, + highlightbackground, highlightcolor, highlightthickness, image, + indicatoron, justify, padx, pady, relief, selectcolor, selectimage, + state, takefocus, text, textvariable, underline, value, variable, + width, wraplength.""" + Widget.__init__(self, master, 'radiobutton', cnf, kw) + def deselect(self): + """Put the button in off-state.""" + + self.tk.call(self._w, 'deselect') + def flash(self): + """Flash the button.""" + self.tk.call(self._w, 'flash') + def invoke(self): + """Toggle the button and invoke a command if given as resource.""" + return self.tk.call(self._w, 'invoke') + def select(self): + """Put the button in on-state.""" + self.tk.call(self._w, 'select') + +class Scale(Widget): + """Scale widget which can display a numerical scale.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a scale widget with the parent MASTER. + + Valid resource names: activebackground, background, bigincrement, bd, + bg, borderwidth, command, cursor, digits, fg, font, foreground, from, + highlightbackground, highlightcolor, highlightthickness, label, + length, orient, relief, repeatdelay, repeatinterval, resolution, + showvalue, sliderlength, sliderrelief, state, takefocus, + tickinterval, to, troughcolor, variable, width.""" + Widget.__init__(self, master, 'scale', cnf, kw) + def get(self): + """Get the current value as integer or float.""" + value = self.tk.call(self._w, 'get') + try: + return getint(value) + except ValueError: + return getdouble(value) + def set(self, value): + """Set the value to VALUE.""" + self.tk.call(self._w, 'set', value) + def coords(self, value=None): + """Return a tuple (X,Y) of the point along the centerline of the + trough that corresponds to VALUE or the current value if None is + given.""" + + return self._getints(self.tk.call(self._w, 'coords', value)) + def identify(self, x, y): + """Return where the point X,Y lies. Valid return values are "slider", + "though1" and "though2".""" + return self.tk.call(self._w, 'identify', x, y) + +class Scrollbar(Widget): + """Scrollbar widget which displays a slider at a certain position.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a scrollbar widget with the parent MASTER. + + Valid resource names: activebackground, activerelief, + background, bd, bg, borderwidth, command, cursor, + elementborderwidth, highlightbackground, + highlightcolor, highlightthickness, jump, orient, + relief, repeatdelay, repeatinterval, takefocus, + troughcolor, width.""" + Widget.__init__(self, master, 'scrollbar', cnf, kw) + def activate(self, index): + """Display the element at INDEX with activebackground and activerelief. + INDEX can be "arrow1","slider" or "arrow2".""" + self.tk.call(self._w, 'activate', index) + def delta(self, deltax, deltay): + """Return the fractional change of the scrollbar setting if it + would be moved by DELTAX or DELTAY pixels.""" + return getdouble( + self.tk.call(self._w, 'delta', deltax, deltay)) + def fraction(self, x, y): + """Return the fractional value which corresponds to a slider + position of X,Y.""" + return getdouble(self.tk.call(self._w, 'fraction', x, y)) + def identify(self, x, y): + """Return the element under position X,Y as one of + "arrow1","slider","arrow2" or "".""" + return self.tk.call(self._w, 'identify', x, y) + def get(self): + """Return the current fractional values (upper and lower end) + of the slider position.""" + return self._getdoubles(self.tk.call(self._w, 'get')) + def set(self, *args): + """Set the fractional values of the slider position (upper and + lower ends as value between 0 and 1).""" + self.tk.call((self._w, 'set') + args) + + + +class Text(Widget): + """Text widget which can display text in various forms.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a text widget with the parent MASTER. + + STANDARD OPTIONS + + background, borderwidth, cursor, + exportselection, font, foreground, + highlightbackground, highlightcolor, + highlightthickness, insertbackground, + insertborderwidth, insertofftime, + insertontime, insertwidth, padx, pady, + relief, selectbackground, + selectborderwidth, selectforeground, + setgrid, takefocus, + xscrollcommand, yscrollcommand, + + WIDGET-SPECIFIC OPTIONS + + autoseparators, height, maxundo, + spacing1, spacing2, spacing3, + state, tabs, undo, width, wrap, + + """ + Widget.__init__(self, master, 'text', cnf, kw) + def bbox(self, *args): + """Return a tuple of (x,y,width,height) which gives the bounding + box of the visible part of the character at the index in ARGS.""" + return self._getints( + self.tk.call((self._w, 'bbox') + args)) or None + def tk_textSelectTo(self, index): + self.tk.call('tk_textSelectTo', self._w, index) + def tk_textBackspace(self): + self.tk.call('tk_textBackspace', self._w) + def tk_textIndexCloser(self, a, b, c): + self.tk.call('tk_textIndexCloser', self._w, a, b, c) + def tk_textResetAnchor(self, index): + self.tk.call('tk_textResetAnchor', self._w, index) + def compare(self, index1, op, index2): + """Return whether between index INDEX1 and index INDEX2 the + relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=.""" + return self.tk.getboolean(self.tk.call( + self._w, 'compare', index1, op, index2)) + def debug(self, boolean=None): + """Turn on the internal consistency checks of the B-Tree inside the text + widget according to BOOLEAN.""" + return self.tk.getboolean(self.tk.call( + self._w, 'debug', boolean)) + def delete(self, index1, index2=None): + """Delete the characters between INDEX1 and INDEX2 (not included).""" + self.tk.call(self._w, 'delete', index1, index2) + def dlineinfo(self, index): + """Return tuple (x,y,width,height,baseline) giving the bounding box + and baseline position of the visible part of the line containing + the character at INDEX.""" + return self._getints(self.tk.call(self._w, 'dlineinfo', index)) + def dump(self, index1, index2=None, command=None, **kw): + """Return the contents of the widget between index1 and index2. + + The type of contents returned in filtered based on the keyword + parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are + given and true, then the corresponding items are returned. The result + is a list of triples of the form (key, value, index). If none of the + keywords are true then 'all' is used by default. + + If the 'command' argument is given, it is called once for each element + of the list of triples, with the values of each triple serving as the + arguments to the function. In this case the list is not returned.""" + args = [] + func_name = None + result = None + if not command: + # Never call the dump command without the -command flag, since the + # output could involve Tcl quoting and would be a pain to parse + # right. Instead just set the command to build a list of triples + # as if we had done the parsing. + result = [] + def append_triple(key, value, index, result=result): + result.append((key, value, index)) + command = append_triple + try: + if not isinstance(command, str): + func_name = command = self._register(command) + args += ["-command", command] + for key in kw: + if kw[key]: args.append("-" + key) + args.append(index1) + if index2: + args.append(index2) + self.tk.call(self._w, "dump", *args) + return result + finally: + if func_name: + self.deletecommand(func_name) + + ## new in tk8.4 + def edit(self, *args): + """Internal method + + This method controls the undo mechanism and + the modified flag. The exact behavior of the + command depends on the option argument that + follows the edit argument. The following forms + of the command are currently supported: + + edit_modified, edit_redo, edit_reset, edit_separator + and edit_undo + + """ + return self._getints( + self.tk.call((self._w, 'edit') + args)) or () + + def edit_modified(self, arg=None): + """Get or Set the modified flag + + If arg is not specified, returns the modified + flag of the widget. The insert, delete, edit undo and + edit redo commands or the user can set or clear the + modified flag. If boolean is specified, sets the + modified flag of the widget to arg. + """ + return self.edit("modified", arg) + + def edit_redo(self): + """Redo the last undone edit + + When the undo option is true, reapplies the last + undone edits provided no other edits were done since + then. Generates an error when the redo stack is empty. + Does nothing when the undo option is false. + """ + return self.edit("redo") + + def edit_reset(self): + """Clears the undo and redo stacks + """ + return self.edit("reset") + + def edit_separator(self): + """Inserts a separator (boundary) on the undo stack. + + Does nothing when the undo option is false + """ + return self.edit("separator") + + def edit_undo(self): + """Undoes the last edit action + + If the undo option is true. An edit action is defined + as all the insert and delete commands that are recorded + on the undo stack in between two separators. Generates + an error when the undo stack is empty. Does nothing + when the undo option is false + """ + return self.edit("undo") + + def get(self, index1, index2=None): + """Return the text from INDEX1 to INDEX2 (not included).""" + return self.tk.call(self._w, 'get', index1, index2) + # (Image commands are new in 8.0) + def image_cget(self, index, option): + """Return the value of OPTION of an embedded image at INDEX.""" + if option[:1] != "-": + option = "-" + option + if option[-1:] == "_": + option = option[:-1] + return self.tk.call(self._w, "image", "cget", index, option) + def image_configure(self, index, cnf=None, **kw): + """Configure an embedded image at INDEX.""" + return self._configure(('image', 'configure', index), cnf, kw) + def image_create(self, index, cnf={}, **kw): + """Create an embedded image at INDEX.""" + return self.tk.call( + self._w, "image", "create", index, + *self._options(cnf, kw)) + def image_names(self): + """Return all names of embedded images in this widget.""" + return self.tk.call(self._w, "image", "names") + def index(self, index): + """Return the index in the form line.char for INDEX.""" + return str(self.tk.call(self._w, 'index', index)) + def insert(self, index, chars, *args): + """Insert CHARS before the characters at INDEX. An additional + tag can be given in ARGS. Additional CHARS and tags can follow in ARGS.""" + self.tk.call((self._w, 'insert', index, chars) + args) + def mark_gravity(self, markName, direction=None): + """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT). + Return the current value if None is given for DIRECTION.""" + return self.tk.call( + (self._w, 'mark', 'gravity', markName, direction)) + def mark_names(self): + """Return all mark names.""" + return self.tk.splitlist(self.tk.call( + self._w, 'mark', 'names')) + def mark_set(self, markName, index): + """Set mark MARKNAME before the character at INDEX.""" + self.tk.call(self._w, 'mark', 'set', markName, index) + def mark_unset(self, *markNames): + """Delete all marks in MARKNAMES.""" + self.tk.call((self._w, 'mark', 'unset') + markNames) + def mark_next(self, index): + """Return the name of the next mark after INDEX.""" + return self.tk.call(self._w, 'mark', 'next', index) or None + def mark_previous(self, index): + """Return the name of the previous mark before INDEX.""" + return self.tk.call(self._w, 'mark', 'previous', index) or None + def scan_mark(self, x, y): + """Remember the current X, Y coordinates.""" + self.tk.call(self._w, 'scan', 'mark', x, y) + def scan_dragto(self, x, y): + """Adjust the view of the text to 10 times the + difference between X and Y and the coordinates given in + scan_mark.""" + self.tk.call(self._w, 'scan', 'dragto', x, y) + def search(self, pattern, index, stopindex=None, + forwards=None, backwards=None, exact=None, + regexp=None, nocase=None, count=None, elide=None): + """Search PATTERN beginning from INDEX until STOPINDEX. + Return the index of the first character of a match or an empty string.""" + args = [self._w, 'search'] + if forwards: args.append('-forwards') + if backwards: args.append('-backwards') + if exact: args.append('-exact') + if regexp: args.append('-regexp') + if nocase: args.append('-nocase') + if elide: args.append('-elide') + if count: args.append('-count'); args.append(count) + if pattern[0] == '-': args.append('--') + args.append(pattern) + args.append(index) + if stopindex: args.append(stopindex) + return self.tk.call(tuple(args)) + def see(self, index): + """Scroll such that the character at INDEX is visible.""" + self.tk.call(self._w, 'see', index) + def tag_add(self, tagName, index1, *args): + """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS. + Additional pairs of indices may follow in ARGS.""" + self.tk.call( + (self._w, 'tag', 'add', tagName, index1) + args) + def tag_unbind(self, tagName, sequence, funcid=None): + """Unbind for all characters with TAGNAME for event SEQUENCE the + function identified with FUNCID.""" + self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '') + if funcid: + self.deletecommand(funcid) + def tag_bind(self, tagName, sequence, func, add=None): + """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC. + + An additional boolean parameter ADD specifies whether FUNC will be + called additionally to the other bound function or whether it will + replace the previous function. See bind for the return value.""" + return self._bind((self._w, 'tag', 'bind', tagName), + sequence, func, add) + def tag_cget(self, tagName, option): + """Return the value of OPTION for tag TAGNAME.""" + if option[:1] != '-': + option = '-' + option + if option[-1:] == '_': + option = option[:-1] + return self.tk.call(self._w, 'tag', 'cget', tagName, option) + def tag_configure(self, tagName, cnf=None, **kw): + """Configure a tag TAGNAME.""" + return self._configure(('tag', 'configure', tagName), cnf, kw) + tag_config = tag_configure + def tag_delete(self, *tagNames): + """Delete all tags in TAGNAMES.""" + self.tk.call((self._w, 'tag', 'delete') + tagNames) + def tag_lower(self, tagName, belowThis=None): + """Change the priority of tag TAGNAME such that it is lower + than the priority of BELOWTHIS.""" + self.tk.call(self._w, 'tag', 'lower', tagName, belowThis) + def tag_names(self, index=None): + """Return a list of all tag names.""" + return self.tk.splitlist( + self.tk.call(self._w, 'tag', 'names', index)) + def tag_nextrange(self, tagName, index1, index2=None): + """Return a list of start and end index for the first sequence of + characters between INDEX1 and INDEX2 which all have tag TAGNAME. + The text is searched forward from INDEX1.""" + return self.tk.splitlist(self.tk.call( + self._w, 'tag', 'nextrange', tagName, index1, index2)) + def tag_prevrange(self, tagName, index1, index2=None): + """Return a list of start and end index for the first sequence of + characters between INDEX1 and INDEX2 which all have tag TAGNAME. + The text is searched backwards from INDEX1.""" + return self.tk.splitlist(self.tk.call( + self._w, 'tag', 'prevrange', tagName, index1, index2)) + def tag_raise(self, tagName, aboveThis=None): + """Change the priority of tag TAGNAME such that it is higher + than the priority of ABOVETHIS.""" + self.tk.call( + self._w, 'tag', 'raise', tagName, aboveThis) + def tag_ranges(self, tagName): + """Return a list of ranges of text which have tag TAGNAME.""" + return self.tk.splitlist(self.tk.call( + self._w, 'tag', 'ranges', tagName)) + def tag_remove(self, tagName, index1, index2=None): + """Remove tag TAGNAME from all characters between INDEX1 and INDEX2.""" + self.tk.call( + self._w, 'tag', 'remove', tagName, index1, index2) + def window_cget(self, index, option): + """Return the value of OPTION of an embedded window at INDEX.""" + if option[:1] != '-': + option = '-' + option + if option[-1:] == '_': + option = option[:-1] + return self.tk.call(self._w, 'window', 'cget', index, option) + def window_configure(self, index, cnf=None, **kw): + """Configure an embedded window at INDEX.""" + return self._configure(('window', 'configure', index), cnf, kw) + window_config = window_configure + def window_create(self, index, cnf={}, **kw): + """Create a window at INDEX.""" + self.tk.call( + (self._w, 'window', 'create', index) + + self._options(cnf, kw)) + def window_names(self): + """Return all names of embedded windows in this widget.""" + return self.tk.splitlist( + self.tk.call(self._w, 'window', 'names')) + def xview(self, *what): + """Query and change horizontal position of the view.""" + if not what: + return self._getdoubles(self.tk.call(self._w, 'xview')) + self.tk.call((self._w, 'xview') + what) + def xview_moveto(self, fraction): + """Adjusts the view in the window so that FRACTION of the + total width of the canvas is off-screen to the left.""" + self.tk.call(self._w, 'xview', 'moveto', fraction) + def xview_scroll(self, number, what): + """Shift the x-view according to NUMBER which is measured + in "units" or "pages" (WHAT).""" + self.tk.call(self._w, 'xview', 'scroll', number, what) + def yview(self, *what): + """Query and change vertical position of the view.""" + if not what: + return self._getdoubles(self.tk.call(self._w, 'yview')) + self.tk.call((self._w, 'yview') + what) + def yview_moveto(self, fraction): + """Adjusts the view in the window so that FRACTION of the + total height of the canvas is off-screen to the top.""" + self.tk.call(self._w, 'yview', 'moveto', fraction) + def yview_scroll(self, number, what): + """Shift the y-view according to NUMBER which is measured + in "units" or "pages" (WHAT).""" + self.tk.call(self._w, 'yview', 'scroll', number, what) + def yview_pickplace(self, *what): + """Obsolete function, use see.""" + self.tk.call((self._w, 'yview', '-pickplace') + what) + + +class _setit: + """Internal class. It wraps the command in the widget OptionMenu.""" + def __init__(self, var, value, callback=None): + self.__value = value + self.__var = var + self.__callback = callback + def __call__(self, *args): + self.__var.set(self.__value) + if self.__callback: + self.__callback(self.__value, *args) + +class OptionMenu(Menubutton): + """OptionMenu which allows the user to select a value from a menu.""" + def __init__(self, master, variable, value, *values, **kwargs): + """Construct an optionmenu widget with the parent MASTER, with + the resource textvariable set to VARIABLE, the initially selected + value VALUE, the other menu values VALUES and an additional + keyword argument command.""" + kw = {"borderwidth": 2, "textvariable": variable, + "indicatoron": 1, "relief": RAISED, "anchor": "c", + "highlightthickness": 2} + Widget.__init__(self, master, "menubutton", kw) + self.widgetName = 'tk_optionMenu' + menu = self.__menu = Menu(self, name="menu", tearoff=0) + self.menuname = menu._w + # 'command' is the only supported keyword + callback = kwargs.get('command') + if 'command' in kwargs: + del kwargs['command'] + if kwargs: + raise TclError('unknown option -'+kwargs.keys()[0]) + menu.add_command(label=value, + command=_setit(variable, value, callback)) + for v in values: + menu.add_command(label=v, + command=_setit(variable, v, callback)) + self["menu"] = menu + + def __getitem__(self, name): + if name == 'menu': + return self.__menu + return Widget.__getitem__(self, name) + + def destroy(self): + """Destroy this widget and the associated menu.""" + Menubutton.destroy(self) + self.__menu = None + +class Image: + """Base class for images.""" + _last_id = 0 + def __init__(self, imgtype, name=None, cnf={}, master=None, **kw): + self.name = None + if not master: + master = _default_root + if not master: + raise RuntimeError('Too early to create image') + self.tk = master.tk + if not name: + Image._last_id += 1 + name = "pyimage%r" % (Image._last_id,) # tk itself would use image + # The following is needed for systems where id(x) + # can return a negative number, such as Linux/m68k: + if name[0] == '-': name = '_' + name[1:] + if kw and cnf: cnf = _cnfmerge((cnf, kw)) + elif kw: cnf = kw + options = () + for k, v in cnf.items(): + if hasattr(v, '__call__'): + v = self._register(v) + options = options + ('-'+k, v) + self.tk.call(('image', 'create', imgtype, name,) + options) + self.name = name + def __str__(self): return self.name + def __del__(self): + if self.name: + try: + self.tk.call('image', 'delete', self.name) + except TclError: + # May happen if the root was destroyed + pass + def __setitem__(self, key, value): + self.tk.call(self.name, 'configure', '-'+key, value) + def __getitem__(self, key): + return self.tk.call(self.name, 'configure', '-'+key) + def configure(self, **kw): + """Configure the image.""" + res = () + for k, v in _cnfmerge(kw).items(): + if v is not None: + if k[-1] == '_': k = k[:-1] + if hasattr(v, '__call__'): + v = self._register(v) + res = res + ('-'+k, v) + self.tk.call((self.name, 'config') + res) + config = configure + def height(self): + """Return the height of the image.""" + return getint( + self.tk.call('image', 'height', self.name)) + def type(self): + """Return the type of the imgage, e.g. "photo" or "bitmap".""" + return self.tk.call('image', 'type', self.name) + def width(self): + """Return the width of the image.""" + return getint( + self.tk.call('image', 'width', self.name)) + +class PhotoImage(Image): + """Widget which can display colored images in GIF, PPM/PGM format.""" + def __init__(self, name=None, cnf={}, master=None, **kw): + """Create an image with NAME. + + Valid resource names: data, format, file, gamma, height, palette, + width.""" + Image.__init__(self, 'photo', name, cnf, master, **kw) + def blank(self): + """Display a transparent image.""" + self.tk.call(self.name, 'blank') + def cget(self, option): + """Return the value of OPTION.""" + return self.tk.call(self.name, 'cget', '-' + option) + # XXX config + def __getitem__(self, key): + return self.tk.call(self.name, 'cget', '-' + key) + # XXX copy -from, -to, ...? + def copy(self): + """Return a new PhotoImage with the same image as this widget.""" + destImage = PhotoImage() + self.tk.call(destImage, 'copy', self.name) + return destImage + def zoom(self,x,y=''): + """Return a new PhotoImage with the same image as this widget + but zoom it with X and Y.""" + destImage = PhotoImage() + if y=='': y=x + self.tk.call(destImage, 'copy', self.name, '-zoom',x,y) + return destImage + def subsample(self,x,y=''): + """Return a new PhotoImage based on the same image as this widget + but use only every Xth or Yth pixel.""" + destImage = PhotoImage() + if y=='': y=x + self.tk.call(destImage, 'copy', self.name, '-subsample',x,y) + return destImage + def get(self, x, y): + """Return the color (red, green, blue) of the pixel at X,Y.""" + return self.tk.call(self.name, 'get', x, y) + def put(self, data, to=None): + """Put row formated colors to image starting from + position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))""" + args = (self.name, 'put', data) + if to: + if to[0] == '-to': + to = to[1:] + args = args + ('-to',) + tuple(to) + self.tk.call(args) + # XXX read + def write(self, filename, format=None, from_coords=None): + """Write image to file FILENAME in FORMAT starting from + position FROM_COORDS.""" + args = (self.name, 'write', filename) + if format: + args = args + ('-format', format) + if from_coords: + args = args + ('-from',) + tuple(from_coords) + self.tk.call(args) + +class BitmapImage(Image): + """Widget which can display a bitmap.""" + def __init__(self, name=None, cnf={}, master=None, **kw): + """Create a bitmap with NAME. + + Valid resource names: background, data, file, foreground, maskdata, maskfile.""" + Image.__init__(self, 'bitmap', name, cnf, master, **kw) + +def image_names(): return _default_root.tk.call('image', 'names') +def image_types(): return _default_root.tk.call('image', 'types') + + +class Spinbox(Widget): + """spinbox widget.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a spinbox widget with the parent MASTER. + + STANDARD OPTIONS + + activebackground, background, borderwidth, + cursor, exportselection, font, foreground, + highlightbackground, highlightcolor, + highlightthickness, insertbackground, + insertborderwidth, insertofftime, + insertontime, insertwidth, justify, relief, + repeatdelay, repeatinterval, + selectbackground, selectborderwidth + selectforeground, takefocus, textvariable + xscrollcommand. + + WIDGET-SPECIFIC OPTIONS + + buttonbackground, buttoncursor, + buttondownrelief, buttonuprelief, + command, disabledbackground, + disabledforeground, format, from, + invalidcommand, increment, + readonlybackground, state, to, + validate, validatecommand values, + width, wrap, + """ + Widget.__init__(self, master, 'spinbox', cnf, kw) + + def bbox(self, index): + """Return a tuple of X1,Y1,X2,Y2 coordinates for a + rectangle which encloses the character given by index. + + The first two elements of the list give the x and y + coordinates of the upper-left corner of the screen + area covered by the character (in pixels relative + to the widget) and the last two elements give the + width and height of the character, in pixels. The + bounding box may refer to a region outside the + visible area of the window. + """ + return self.tk.call(self._w, 'bbox', index) + + def delete(self, first, last=None): + """Delete one or more elements of the spinbox. + + First is the index of the first character to delete, + and last is the index of the character just after + the last one to delete. If last isn't specified it + defaults to first+1, i.e. a single character is + deleted. This command returns an empty string. + """ + return self.tk.call(self._w, 'delete', first, last) + + def get(self): + """Returns the spinbox's string""" + return self.tk.call(self._w, 'get') + + def icursor(self, index): + """Alter the position of the insertion cursor. + + The insertion cursor will be displayed just before + the character given by index. Returns an empty string + """ + return self.tk.call(self._w, 'icursor', index) + + def identify(self, x, y): + """Returns the name of the widget at position x, y + + Return value is one of: none, buttondown, buttonup, entry + """ + return self.tk.call(self._w, 'identify', x, y) + + def index(self, index): + """Returns the numerical index corresponding to index + """ + return self.tk.call(self._w, 'index', index) + + def insert(self, index, s): + """Insert string s at index + + Returns an empty string. + """ + return self.tk.call(self._w, 'insert', index, s) + + def invoke(self, element): + """Causes the specified element to be invoked + + The element could be buttondown or buttonup + triggering the action associated with it. + """ + return self.tk.call(self._w, 'invoke', element) + + def scan(self, *args): + """Internal function.""" + return self._getints( + self.tk.call((self._w, 'scan') + args)) or () + + def scan_mark(self, x): + """Records x and the current view in the spinbox window; + + used in conjunction with later scan dragto commands. + Typically this command is associated with a mouse button + press in the widget. It returns an empty string. + """ + return self.scan("mark", x) + + def scan_dragto(self, x): + """Compute the difference between the given x argument + and the x argument to the last scan mark command + + It then adjusts the view left or right by 10 times the + difference in x-coordinates. This command is typically + associated with mouse motion events in the widget, to + produce the effect of dragging the spinbox at high speed + through the window. The return value is an empty string. + """ + return self.scan("dragto", x) + + def selection(self, *args): + """Internal function.""" + return self._getints( + self.tk.call((self._w, 'selection') + args)) or () + + def selection_adjust(self, index): + """Locate the end of the selection nearest to the character + given by index, + + Then adjust that end of the selection to be at index + (i.e including but not going beyond index). The other + end of the selection is made the anchor point for future + select to commands. If the selection isn't currently in + the spinbox, then a new selection is created to include + the characters between index and the most recent selection + anchor point, inclusive. Returns an empty string. + """ + return self.selection("adjust", index) + + def selection_clear(self): + """Clear the selection + + If the selection isn't in this widget then the + command has no effect. Returns an empty string. + """ + return self.selection("clear") + + def selection_element(self, element=None): + """Sets or gets the currently selected element. + + If a spinbutton element is specified, it will be + displayed depressed + """ + return self.selection("element", element) + +########################################################################### + +class LabelFrame(Widget): + """labelframe widget.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a labelframe widget with the parent MASTER. + + STANDARD OPTIONS + + borderwidth, cursor, font, foreground, + highlightbackground, highlightcolor, + highlightthickness, padx, pady, relief, + takefocus, text + + WIDGET-SPECIFIC OPTIONS + + background, class, colormap, container, + height, labelanchor, labelwidget, + visual, width + """ + Widget.__init__(self, master, 'labelframe', cnf, kw) + +######################################################################## + +class PanedWindow(Widget): + """panedwindow widget.""" + def __init__(self, master=None, cnf={}, **kw): + """Construct a panedwindow widget with the parent MASTER. + + STANDARD OPTIONS + + background, borderwidth, cursor, height, + orient, relief, width + + WIDGET-SPECIFIC OPTIONS + + handlepad, handlesize, opaqueresize, + sashcursor, sashpad, sashrelief, + sashwidth, showhandle, + """ + Widget.__init__(self, master, 'panedwindow', cnf, kw) + + def add(self, child, **kw): + """Add a child widget to the panedwindow in a new pane. + + The child argument is the name of the child widget + followed by pairs of arguments that specify how to + manage the windows. Options may have any of the values + accepted by the configure subcommand. + """ + self.tk.call((self._w, 'add', child) + self._options(kw)) + + def remove(self, child): + """Remove the pane containing child from the panedwindow + + All geometry management options for child will be forgotten. + """ + self.tk.call(self._w, 'forget', child) + forget=remove + + def identify(self, x, y): + """Identify the panedwindow component at point x, y + + If the point is over a sash or a sash handle, the result + is a two element list containing the index of the sash or + handle, and a word indicating whether it is over a sash + or a handle, such as {0 sash} or {2 handle}. If the point + is over any other part of the panedwindow, the result is + an empty list. + """ + return self.tk.call(self._w, 'identify', x, y) + + def proxy(self, *args): + """Internal function.""" + return self._getints( + self.tk.call((self._w, 'proxy') + args)) or () + + def proxy_coord(self): + """Return the x and y pair of the most recent proxy location + """ + return self.proxy("coord") + + def proxy_forget(self): + """Remove the proxy from the display. + """ + return self.proxy("forget") + + def proxy_place(self, x, y): + """Place the proxy at the given x and y coordinates. + """ + return self.proxy("place", x, y) + + def sash(self, *args): + """Internal function.""" + return self._getints( + self.tk.call((self._w, 'sash') + args)) or () + + def sash_coord(self, index): + """Return the current x and y pair for the sash given by index. + + Index must be an integer between 0 and 1 less than the + number of panes in the panedwindow. The coordinates given are + those of the top left corner of the region containing the sash. + pathName sash dragto index x y This command computes the + difference between the given coordinates and the coordinates + given to the last sash coord command for the given sash. It then + moves that sash the computed difference. The return value is the + empty string. + """ + return self.sash("coord", index) + + def sash_mark(self, index): + """Records x and y for the sash given by index; + + Used in conjunction with later dragto commands to move the sash. + """ + return self.sash("mark", index) + + def sash_place(self, index, x, y): + """Place the sash given by index at the given coordinates + """ + return self.sash("place", index, x, y) + + def panecget(self, child, option): + """Query a management option for window. + + Option may be any value allowed by the paneconfigure subcommand + """ + return self.tk.call( + (self._w, 'panecget') + (child, '-'+option)) + + def paneconfigure(self, tagOrId, cnf=None, **kw): + """Query or modify the management options for window. + + If no option is specified, returns a list describing all + of the available options for pathName. If option is + specified with no value, then the command returns a list + describing the one named option (this list will be identical + to the corresponding sublist of the value returned if no + option is specified). If one or more option-value pairs are + specified, then the command modifies the given widget + option(s) to have the given value(s); in this case the + command returns an empty string. The following options + are supported: + + after window + Insert the window after the window specified. window + should be the name of a window already managed by pathName. + before window + Insert the window before the window specified. window + should be the name of a window already managed by pathName. + height size + Specify a height for the window. The height will be the + outer dimension of the window including its border, if + any. If size is an empty string, or if -height is not + specified, then the height requested internally by the + window will be used initially; the height may later be + adjusted by the movement of sashes in the panedwindow. + Size may be any value accepted by Tk_GetPixels. + minsize n + Specifies that the size of the window cannot be made + less than n. This constraint only affects the size of + the widget in the paned dimension -- the x dimension + for horizontal panedwindows, the y dimension for + vertical panedwindows. May be any value accepted by + Tk_GetPixels. + padx n + Specifies a non-negative value indicating how much + extra space to leave on each side of the window in + the X-direction. The value may have any of the forms + accepted by Tk_GetPixels. + pady n + Specifies a non-negative value indicating how much + extra space to leave on each side of the window in + the Y-direction. The value may have any of the forms + accepted by Tk_GetPixels. + sticky style + If a window's pane is larger than the requested + dimensions of the window, this option may be used + to position (or stretch) the window within its pane. + Style is a string that contains zero or more of the + characters n, s, e or w. The string can optionally + contains spaces or commas, but they are ignored. Each + letter refers to a side (north, south, east, or west) + that the window will "stick" to. If both n and s + (or e and w) are specified, the window will be + stretched to fill the entire height (or width) of + its cavity. + width size + Specify a width for the window. The width will be + the outer dimension of the window including its + border, if any. If size is an empty string, or + if -width is not specified, then the width requested + internally by the window will be used initially; the + width may later be adjusted by the movement of sashes + in the panedwindow. Size may be any value accepted by + Tk_GetPixels. + + """ + if cnf is None and not kw: + cnf = {} + for x in self.tk.split( + self.tk.call(self._w, + 'paneconfigure', tagOrId)): + cnf[x[0][1:]] = (x[0][1:],) + x[1:] + return cnf + if isinstance(cnf, str) and not kw: + x = self.tk.split(self.tk.call( + self._w, 'paneconfigure', tagOrId, '-'+cnf)) + return (x[0][1:],) + x[1:] + self.tk.call((self._w, 'paneconfigure', tagOrId) + + self._options(cnf, kw)) + paneconfig = paneconfigure + + def panes(self): + """Returns an ordered list of the child panes.""" + return self.tk.call(self._w, 'panes') + +###################################################################### +# Extensions: + +class Studbutton(Button): + def __init__(self, master=None, cnf={}, **kw): + Widget.__init__(self, master, 'studbutton', cnf, kw) + self.bind('', self.tkButtonEnter) + self.bind('', self.tkButtonLeave) + self.bind('<1>', self.tkButtonDown) + self.bind('', self.tkButtonUp) + +class Tributton(Button): + def __init__(self, master=None, cnf={}, **kw): + Widget.__init__(self, master, 'tributton', cnf, kw) + self.bind('', self.tkButtonEnter) + self.bind('', self.tkButtonLeave) + self.bind('<1>', self.tkButtonDown) + self.bind('', self.tkButtonUp) + self['fg'] = self['bg'] + self['activebackground'] = self['bg'] + +###################################################################### +# Test: + +def _test(): + root = Tk() + text = "This is Tcl/Tk version %s" % TclVersion + if TclVersion >= 8.1: + text += "\nThis should be a cedilla: \xe7" + label = Label(root, text=text) + label.pack() + test = Button(root, text="Click me!", + command=lambda root=root: root.test.configure( + text="[%s]" % root.test['text'])) + test.pack() + root.test = test + quit = Button(root, text="QUIT", command=root.destroy) + quit.pack() + # The following three commands are needed so the window pops + # up on top on Windows... + root.iconify() + root.update() + root.deiconify() + root.mainloop() + +if __name__ == '__main__': + _test() Index: Lib/tkinter/filedialog.py =================================================================== --- Lib/tkinter/filedialog.py (revision 0) +++ Lib/tkinter/filedialog.py (revision 0) @@ -0,0 +1,492 @@ +"""File selection dialog classes. + +Classes: + +- FileDialog +- LoadFileDialog +- SaveFileDialog +- Open +- SaveAs +- Directory +""" + +from tkinter import * +from tkinter.dialog import Dialog +from tkinter.commondialog import Dialog as CommonDialog + +import os +import fnmatch + + +dialogstates = {} + + +class FileDialog: + + """Standard file selection dialog -- no checks on selected file. + + Usage: + + d = FileDialog(master) + fname = d.go(dir_or_file, pattern, default, key) + if fname is None: ...canceled... + else: ...open file... + + All arguments to go() are optional. + + The 'key' argument specifies a key in the global dictionary + 'dialogstates', which keeps track of the values for the directory + and pattern arguments, overriding the values passed in (it does + not keep track of the default argument!). If no key is specified, + the dialog keeps no memory of previous state. Note that memory is + kept even when the dialog is canceled. (All this emulates the + behavior of the Macintosh file selection dialogs.) + + """ + + title = "File Selection Dialog" + + def __init__(self, master, title=None): + if title is None: title = self.title + self.master = master + self.directory = None + + self.top = Toplevel(master) + self.top.title(title) + self.top.iconname(title) + + self.botframe = Frame(self.top) + self.botframe.pack(side=BOTTOM, fill=X) + + self.selection = Entry(self.top) + self.selection.pack(side=BOTTOM, fill=X) + self.selection.bind('', self.ok_event) + + self.filter = Entry(self.top) + self.filter.pack(side=TOP, fill=X) + self.filter.bind('', self.filter_command) + + self.midframe = Frame(self.top) + self.midframe.pack(expand=YES, fill=BOTH) + + self.filesbar = Scrollbar(self.midframe) + self.filesbar.pack(side=RIGHT, fill=Y) + self.files = Listbox(self.midframe, exportselection=0, + yscrollcommand=(self.filesbar, 'set')) + self.files.pack(side=RIGHT, expand=YES, fill=BOTH) + btags = self.files.bindtags() + self.files.bindtags(btags[1:] + btags[:1]) + self.files.bind('', self.files_select_event) + self.files.bind('', self.files_double_event) + self.filesbar.config(command=(self.files, 'yview')) + + self.dirsbar = Scrollbar(self.midframe) + self.dirsbar.pack(side=LEFT, fill=Y) + self.dirs = Listbox(self.midframe, exportselection=0, + yscrollcommand=(self.dirsbar, 'set')) + self.dirs.pack(side=LEFT, expand=YES, fill=BOTH) + self.dirsbar.config(command=(self.dirs, 'yview')) + btags = self.dirs.bindtags() + self.dirs.bindtags(btags[1:] + btags[:1]) + self.dirs.bind('', self.dirs_select_event) + self.dirs.bind('', self.dirs_double_event) + + self.ok_button = Button(self.botframe, + text="OK", + command=self.ok_command) + self.ok_button.pack(side=LEFT) + self.filter_button = Button(self.botframe, + text="Filter", + command=self.filter_command) + self.filter_button.pack(side=LEFT, expand=YES) + self.cancel_button = Button(self.botframe, + text="Cancel", + command=self.cancel_command) + self.cancel_button.pack(side=RIGHT) + + self.top.protocol('WM_DELETE_WINDOW', self.cancel_command) + # XXX Are the following okay for a general audience? + self.top.bind('', self.cancel_command) + self.top.bind('', self.cancel_command) + + def go(self, dir_or_file=os.curdir, pattern="*", default="", key=None): + if key and key in dialogstates: + self.directory, pattern = dialogstates[key] + else: + dir_or_file = os.path.expanduser(dir_or_file) + if os.path.isdir(dir_or_file): + self.directory = dir_or_file + else: + self.directory, default = os.path.split(dir_or_file) + self.set_filter(self.directory, pattern) + self.set_selection(default) + self.filter_command() + self.selection.focus_set() + self.top.wait_visibility() # window needs to be visible for the grab + self.top.grab_set() + self.how = None + self.master.mainloop() # Exited by self.quit(how) + if key: + directory, pattern = self.get_filter() + if self.how: + directory = os.path.dirname(self.how) + dialogstates[key] = directory, pattern + self.top.destroy() + return self.how + + def quit(self, how=None): + self.how = how + self.master.quit() # Exit mainloop() + + def dirs_double_event(self, event): + self.filter_command() + + def dirs_select_event(self, event): + dir, pat = self.get_filter() + subdir = self.dirs.get('active') + dir = os.path.normpath(os.path.join(self.directory, subdir)) + self.set_filter(dir, pat) + + def files_double_event(self, event): + self.ok_command() + + def files_select_event(self, event): + file = self.files.get('active') + self.set_selection(file) + + def ok_event(self, event): + self.ok_command() + + def ok_command(self): + self.quit(self.get_selection()) + + def filter_command(self, event=None): + dir, pat = self.get_filter() + try: + names = os.listdir(dir) + except os.error: + self.master.bell() + return + self.directory = dir + self.set_filter(dir, pat) + names.sort() + subdirs = [os.pardir] + matchingfiles = [] + for name in names: + fullname = os.path.join(dir, name) + if os.path.isdir(fullname): + subdirs.append(name) + elif fnmatch.fnmatch(name, pat): + matchingfiles.append(name) + self.dirs.delete(0, END) + for name in subdirs: + self.dirs.insert(END, name) + self.files.delete(0, END) + for name in matchingfiles: + self.files.insert(END, name) + head, tail = os.path.split(self.get_selection()) + if tail == os.curdir: tail = '' + self.set_selection(tail) + + def get_filter(self): + filter = self.filter.get() + filter = os.path.expanduser(filter) + if filter[-1:] == os.sep or os.path.isdir(filter): + filter = os.path.join(filter, "*") + return os.path.split(filter) + + def get_selection(self): + file = self.selection.get() + file = os.path.expanduser(file) + return file + + def cancel_command(self, event=None): + self.quit() + + def set_filter(self, dir, pat): + if not os.path.isabs(dir): + try: + pwd = os.getcwd() + except os.error: + pwd = None + if pwd: + dir = os.path.join(pwd, dir) + dir = os.path.normpath(dir) + self.filter.delete(0, END) + self.filter.insert(END, os.path.join(dir or os.curdir, pat or "*")) + + def set_selection(self, file): + self.selection.delete(0, END) + self.selection.insert(END, os.path.join(self.directory, file)) + + +class LoadFileDialog(FileDialog): + + """File selection dialog which checks that the file exists.""" + + title = "Load File Selection Dialog" + + def ok_command(self): + file = self.get_selection() + if not os.path.isfile(file): + self.master.bell() + else: + self.quit(file) + + +class SaveFileDialog(FileDialog): + + """File selection dialog which checks that the file may be created.""" + + title = "Save File Selection Dialog" + + def ok_command(self): + file = self.get_selection() + if os.path.exists(file): + if os.path.isdir(file): + self.master.bell() + return + d = Dialog(self.top, + title="Overwrite Existing File Question", + text="Overwrite existing file %r?" % (file,), + bitmap='questhead', + default=1, + strings=("Yes", "Cancel")) + if d.num != 0: + return + else: + head, tail = os.path.split(file) + if not os.path.isdir(head): + self.master.bell() + return + self.quit(file) + + +# +# The rest of this module has been merged from tkFileDialog.py +# +# Instant Python +# $Id: tkFileDialog.py 53686 2007-02-09 05:37:30Z guido.van.rossum $ +# +# tk common file dialogues +# +# this module provides interfaces to the native file dialogues +# available in Tk 4.2 and newer, and the directory dialogue available +# in Tk 8.3 and newer. +# +# written by Fredrik Lundh, May 1997. +# + +# +# options (all have default values): +# +# - defaultextension: added to filename if not explicitly given +# +# - filetypes: sequence of (label, pattern) tuples. the same pattern +# may occur with several patterns. use "*" as pattern to indicate +# all files. +# +# - initialdir: initial directory. preserved by dialog instance. +# +# - initialfile: initial file (ignored by the open dialog). preserved +# by dialog instance. +# +# - parent: which window to place the dialog on top of +# +# - title: dialog title +# +# - multiple: if true user may select more than one file +# +# options for the directory chooser: +# +# - initialdir, parent, title: see above +# +# - mustexist: if true, user must pick an existing directory +# +# + + +class _Dialog(CommonDialog): + + def _fixoptions(self): + try: + # make sure "filetypes" is a tuple + self.options["filetypes"] = tuple(self.options["filetypes"]) + except KeyError: + pass + + def _fixresult(self, widget, result): + if result: + # keep directory and filename until next time + import os + # convert Tcl path objects to strings + try: + result = result.string + except AttributeError: + # it already is a string + pass + path, file = os.path.split(result) + self.options["initialdir"] = path + self.options["initialfile"] = file + self.filename = result # compatibility + return result + + +# +# file dialogs + +class Open(_Dialog): + "Ask for a filename to open" + + command = "tk_getOpenFile" + + def _fixresult(self, widget, result): + if isinstance(result, tuple): + # multiple results: + result = tuple([getattr(r, "string", r) for r in result]) + if result: + import os + path, file = os.path.split(result[0]) + self.options["initialdir"] = path + # don't set initialfile or filename, as we have multiple of these + return result + if not widget.tk.wantobjects() and "multiple" in self.options: + # Need to split result explicitly + return self._fixresult(widget, widget.tk.splitlist(result)) + return _Dialog._fixresult(self, widget, result) + +class SaveAs(_Dialog): + "Ask for a filename to save as" + + command = "tk_getSaveFile" + + +# the directory dialog has its own _fix routines. +class Directory(CommonDialog): + "Ask for a directory" + + command = "tk_chooseDirectory" + + def _fixresult(self, widget, result): + if result: + # convert Tcl path objects to strings + try: + result = result.string + except AttributeError: + # it already is a string + pass + # keep directory until next time + self.options["initialdir"] = result + self.directory = result # compatibility + return result + +# +# convenience stuff + +def askopenfilename(**options): + "Ask for a filename to open" + + return Open(**options).show() + +def asksaveasfilename(**options): + "Ask for a filename to save as" + + return SaveAs(**options).show() + +def askopenfilenames(**options): + """Ask for multiple filenames to open + + Returns a list of filenames or empty list if + cancel button selected + """ + options["multiple"]=1 + return Open(**options).show() + +# FIXME: are the following perhaps a bit too convenient? + +def askopenfile(mode = "r", **options): + "Ask for a filename to open, and returned the opened file" + + filename = Open(**options).show() + if filename: + return open(filename, mode) + return None + +def askopenfiles(mode = "r", **options): + """Ask for multiple filenames and return the open file + objects + + returns a list of open file objects or an empty list if + cancel selected + """ + + files = askopenfilenames(**options) + if files: + ofiles=[] + for filename in files: + ofiles.append(open(filename, mode)) + files=ofiles + return files + + +def asksaveasfile(mode = "w", **options): + "Ask for a filename to save as, and returned the opened file" + + filename = SaveAs(**options).show() + if filename: + return open(filename, mode) + return None + +def askdirectory (**options): + "Ask for a directory, and return the file name" + return Directory(**options).show() + + +def test(): + """Simple test program.""" + root = Tk() + root.withdraw() + fd = LoadFileDialog(root) + loadfile = fd.go(key="test") + fd = SaveFileDialog(root) + savefile = fd.go(key="test") + print(loadfile, savefile) + + # Merged tests from tkFileDialog.py + # + # Since the file name may contain non-ASCII characters, we need + # to find an encoding that likely supports the file name, and + # displays correctly on the terminal. + + # Start off with UTF-8 + enc = "utf-8" + import sys + + # See whether CODESET is defined + try: + import locale + locale.setlocale(locale.LC_ALL,'') + enc = locale.nl_langinfo(locale.CODESET) + except (ImportError, AttributeError): + pass + + # dialog for openening files + + openfilename=askopenfilename(filetypes=[("all files", "*")]) + try: + fp=open(openfilename,"r") + fp.close() + except: + print("Could not open File: ") + print(sys.exc_info()[1]) + + print("open", openfilename.encode(enc)) + + # dialog for saving files + + saveasfilename=asksaveasfilename() + print("saveas", saveasfilename.encode(enc)) + + +if __name__ == '__main__': + test() Index: Lib/tkinter/dialog.py =================================================================== --- Lib/tkinter/dialog.py (revision 0) +++ Lib/tkinter/dialog.py (revision 0) @@ -0,0 +1,49 @@ +# dialog.py -- Tkinter interface to the tk_dialog script. + +from tkinter import * +from tkinter import _cnfmerge + +if TkVersion <= 3.6: + DIALOG_ICON = 'warning' +else: + DIALOG_ICON = 'questhead' + + +class Dialog(Widget): + def __init__(self, master=None, cnf={}, **kw): + cnf = _cnfmerge((cnf, kw)) + self.widgetName = '__dialog__' + Widget._setup(self, master, cnf) + self.num = self.tk.getint( + self.tk.call( + 'tk_dialog', self._w, + cnf['title'], cnf['text'], + cnf['bitmap'], cnf['default'], + *cnf['strings'])) + try: Widget.destroy(self) + except TclError: pass + def destroy(self): pass + +def _test(): + d = Dialog(None, {'title': 'File Modified', + 'text': + 'File "Python.h" has been modified' + ' since the last time it was saved.' + ' Do you want to save it before' + ' exiting the application.', + 'bitmap': DIALOG_ICON, + 'default': 0, + 'strings': ('Save File', + 'Discard Changes', + 'Return to Editor')}) + print(d.num) + + +if __name__ == '__main__': + t = Button(None, {'text': 'Test', + 'command': _test, + Pack: {}}) + q = Button(None, {'text': 'Quit', + 'command': t.quit, + Pack: {}}) + t.mainloop() Index: Lib/tkinter/turtle.py =================================================================== --- Lib/tkinter/turtle.py (revision 0) +++ Lib/tkinter/turtle.py (revision 0) @@ -0,0 +1,956 @@ +# LogoMation-like turtle graphics + +""" +Turtle graphics is a popular way for introducing programming to +kids. It was part of the original Logo programming language developed +by Wally Feurzeig and Seymour Papert in 1966. + +Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it +the command turtle.forward(15), and it moves (on-screen!) 15 pixels in +the direction it is facing, drawing a line as it moves. Give it the +command turtle.left(25), and it rotates in-place 25 degrees clockwise. + +By combining together these and similar commands, intricate shapes and +pictures can easily be drawn. +""" + +from math import * # Also for export +from time import sleep +import tkinter + +speeds = ['fastest', 'fast', 'normal', 'slow', 'slowest'] + +class Error(Exception): + pass + +class RawPen: + + def __init__(self, canvas): + self._canvas = canvas + self._items = [] + self._tracing = 1 + self._arrow = 0 + self._delay = 10 # default delay for drawing + self._angle = 0.0 + self.degrees() + self.reset() + + def degrees(self, fullcircle=360.0): + """ Set angle measurement units to degrees. + + Example: + >>> turtle.degrees() + """ + # Don't try to change _angle if it is 0, because + # _fullcircle might not be set, yet + if self._angle: + self._angle = (self._angle / self._fullcircle) * fullcircle + self._fullcircle = fullcircle + self._invradian = pi / (fullcircle * 0.5) + + def radians(self): + """ Set the angle measurement units to radians. + + Example: + >>> turtle.radians() + """ + self.degrees(2.0*pi) + + def reset(self): + """ Clear the screen, re-center the pen, and set variables to + the default values. + + Example: + >>> turtle.position() + [0.0, -22.0] + >>> turtle.heading() + 100.0 + >>> turtle.reset() + >>> turtle.position() + [0.0, 0.0] + >>> turtle.heading() + 0.0 + """ + canvas = self._canvas + self._canvas.update() + width = canvas.winfo_width() + height = canvas.winfo_height() + if width <= 1: + width = canvas['width'] + if height <= 1: + height = canvas['height'] + self._origin = float(width)/2.0, float(height)/2.0 + self._position = self._origin + self._angle = 0.0 + self._drawing = 1 + self._width = 1 + self._color = "black" + self._filling = 0 + self._path = [] + self.clear() + canvas._root().tkraise() + + def clear(self): + """ Clear the screen. The turtle does not move. + + Example: + >>> turtle.clear() + """ + self.fill(0) + canvas = self._canvas + items = self._items + self._items = [] + for item in items: + canvas.delete(item) + self._delete_turtle() + self._draw_turtle() + + def tracer(self, flag): + """ Set tracing on if flag is True, and off if it is False. + Tracing means line are drawn more slowly, with an + animation of an arrow along the line. + + Example: + >>> turtle.tracer(False) # turns off Tracer + """ + self._tracing = flag + if not self._tracing: + self._delete_turtle() + self._draw_turtle() + + def forward(self, distance): + """ Go forward distance steps. + + Example: + >>> turtle.position() + [0.0, 0.0] + >>> turtle.forward(25) + >>> turtle.position() + [25.0, 0.0] + >>> turtle.forward(-75) + >>> turtle.position() + [-50.0, 0.0] + """ + x0, y0 = start = self._position + x1 = x0 + distance * cos(self._angle*self._invradian) + y1 = y0 - distance * sin(self._angle*self._invradian) + self._goto(x1, y1) + + def backward(self, distance): + """ Go backwards distance steps. + + The turtle's heading does not change. + + Example: + >>> turtle.position() + [0.0, 0.0] + >>> turtle.backward(30) + >>> turtle.position() + [-30.0, 0.0] + """ + self.forward(-distance) + + def left(self, angle): + """ Turn left angle units (units are by default degrees, + but can be set via the degrees() and radians() functions.) + + When viewed from above, the turning happens in-place around + its front tip. + + Example: + >>> turtle.heading() + 22 + >>> turtle.left(45) + >>> turtle.heading() + 67.0 + """ + self._angle = (self._angle + angle) % self._fullcircle + self._draw_turtle() + + def right(self, angle): + """ Turn right angle units (units are by default degrees, + but can be set via the degrees() and radians() functions.) + + When viewed from above, the turning happens in-place around + its front tip. + + Example: + >>> turtle.heading() + 22 + >>> turtle.right(45) + >>> turtle.heading() + 337.0 + """ + self.left(-angle) + + def up(self): + """ Pull the pen up -- no drawing when moving. + + Example: + >>> turtle.up() + """ + self._drawing = 0 + + def down(self): + """ Put the pen down -- draw when moving. + + Example: + >>> turtle.down() + """ + self._drawing = 1 + + def width(self, width): + """ Set the line to thickness to width. + + Example: + >>> turtle.width(10) + """ + self._width = float(width) + + def color(self, *args): + """ Set the pen color. + + Three input formats are allowed: + + color(s) + s is a Tk specification string, such as "red" or "yellow" + + color((r, g, b)) + *a tuple* of r, g, and b, which represent, an RGB color, + and each of r, g, and b are in the range [0..1] + + color(r, g, b) + r, g, and b represent an RGB color, and each of r, g, and b + are in the range [0..1] + + Example: + + >>> turtle.color('brown') + >>> tup = (0.2, 0.8, 0.55) + >>> turtle.color(tup) + >>> turtle.color(0, .5, 0) + """ + if not args: + raise Error("no color arguments") + if len(args) == 1: + color = args[0] + if type(color) == type(""): + # Test the color first + try: + id = self._canvas.create_line(0, 0, 0, 0, fill=color) + except tkinter.TclError: + raise Error("bad color string: %r" % (color,)) + self._set_color(color) + return + try: + r, g, b = color + except: + raise Error("bad color sequence: %r" % (color,)) + else: + try: + r, g, b = args + except: + raise Error("bad color arguments: %r" % (args,)) + assert 0 <= r <= 1 + assert 0 <= g <= 1 + assert 0 <= b <= 1 + x = 255.0 + y = 0.5 + self._set_color("#%02x%02x%02x" % (int(r*x+y), int(g*x+y), int(b*x+y))) + + def _set_color(self,color): + self._color = color + self._draw_turtle() + + def write(self, text, move=False): + """ Write text at the current pen position. + + If move is true, the pen is moved to the bottom-right corner + of the text. By default, move is False. + + Example: + >>> turtle.write('The race is on!') + >>> turtle.write('Home = (0, 0)', True) + """ + x, y = self._position + x = x-1 # correction -- calibrated for Windows + item = self._canvas.create_text(x, y, + text=str(text), anchor="sw", + fill=self._color) + self._items.append(item) + if move: + x0, y0, x1, y1 = self._canvas.bbox(item) + self._goto(x1, y1) + self._draw_turtle() + + def fill(self, flag): + """ Call fill(1) before drawing the shape you + want to fill, and fill(0) when done. + + Example: + >>> turtle.fill(1) + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.fill(0) + """ + if self._filling: + path = tuple(self._path) + smooth = self._filling < 0 + if len(path) > 2: + item = self._canvas._create('polygon', path, + {'fill': self._color, + 'smooth': smooth}) + self._items.append(item) + self._path = [] + self._filling = flag + if flag: + self._path.append(self._position) + + def begin_fill(self): + """ Called just before drawing a shape to be filled. + Must eventually be followed by a corresponding end_fill() call. + Otherwise it will be ignored. + + Example: + >>> turtle.begin_fill() + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.end_fill() + """ + self._path = [self._position] + self._filling = 1 + + def end_fill(self): + """ Called after drawing a shape to be filled. + + Example: + >>> turtle.begin_fill() + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.left(90) + >>> turtle.forward(100) + >>> turtle.end_fill() + """ + self.fill(0) + + def circle(self, radius, extent = None): + """ Draw a circle with given radius. + The center is radius units left of the turtle; extent + determines which part of the circle is drawn. If not given, + the entire circle is drawn. + + If extent is not a full circle, one endpoint of the arc is the + current pen position. The arc is drawn in a counter clockwise + direction if radius is positive, otherwise in a clockwise + direction. In the process, the direction of the turtle is + changed by the amount of the extent. + + >>> turtle.circle(50) + >>> turtle.circle(120, 180) # half a circle + """ + if extent is None: + extent = self._fullcircle + frac = abs(extent)/self._fullcircle + steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac) + w = 1.0 * extent / steps + w2 = 0.5 * w + l = 2.0 * radius * sin(w2*self._invradian) + if radius < 0: + l, w, w2 = -l, -w, -w2 + self.left(w2) + for i in range(steps): + self.forward(l) + self.left(w) + self.right(w2) + + def heading(self): + """ Return the turtle's current heading. + + Example: + >>> turtle.heading() + 67.0 + """ + return self._angle + + def setheading(self, angle): + """ Set the turtle facing the given angle. + + Here are some common directions in degrees: + + 0 - east + 90 - north + 180 - west + 270 - south + + Example: + >>> turtle.setheading(90) + >>> turtle.heading() + 90 + >>> turtle.setheading(128) + >>> turtle.heading() + 128 + """ + self._angle = angle + self._draw_turtle() + + def window_width(self): + """ Returns the width of the turtle window. + + Example: + >>> turtle.window_width() + 640 + """ + width = self._canvas.winfo_width() + if width <= 1: # the window isn't managed by a geometry manager + width = self._canvas['width'] + return width + + def window_height(self): + """ Return the height of the turtle window. + + Example: + >>> turtle.window_height() + 768 + """ + height = self._canvas.winfo_height() + if height <= 1: # the window isn't managed by a geometry manager + height = self._canvas['height'] + return height + + def position(self): + """ Return the current (x, y) location of the turtle. + + Example: + >>> turtle.position() + [0.0, 240.0] + """ + x0, y0 = self._origin + x1, y1 = self._position + return [x1-x0, -y1+y0] + + def setx(self, xpos): + """ Set the turtle's x coordinate to be xpos. + + Example: + >>> turtle.position() + [10.0, 240.0] + >>> turtle.setx(10) + >>> turtle.position() + [10.0, 240.0] + """ + x0, y0 = self._origin + x1, y1 = self._position + self._goto(x0+xpos, y1) + + def sety(self, ypos): + """ Set the turtle's y coordinate to be ypos. + + Example: + >>> turtle.position() + [0.0, 0.0] + >>> turtle.sety(-22) + >>> turtle.position() + [0.0, -22.0] + """ + x0, y0 = self._origin + x1, y1 = self._position + self._goto(x1, y0-ypos) + + def towards(self, *args): + """Returs the angle, which corresponds to the line + from turtle-position to point (x,y). + + Argument can be two coordinates or one pair of coordinates + or a RawPen/Pen instance. + + Example: + >>> turtle.position() + [10.0, 10.0] + >>> turtle.towards(0,0) + 225.0 + """ + if len(args) == 2: + x, y = args + else: + arg = args[0] + if isinstance(arg, RawPen): + x, y = arg.position() + else: + x, y = arg + x0, y0 = self.position() + dx = x - x0 + dy = y - y0 + return (atan2(dy,dx) / self._invradian) % self._fullcircle + + def goto(self, *args): + """ Go to the given point. + + If the pen is down, then a line will be drawn. The turtle's + orientation does not change. + + Two input formats are accepted: + + goto(x, y) + go to point (x, y) + + goto((x, y)) + go to point (x, y) + + Example: + >>> turtle.position() + [0.0, 0.0] + >>> turtle.goto(50, -45) + >>> turtle.position() + [50.0, -45.0] + """ + if len(args) == 1: + try: + x, y = args[0] + except: + raise Error("bad point argument: %r" % (args[0],)) + else: + try: + x, y = args + except: + raise Error("bad coordinates: %r" % (args[0],)) + x0, y0 = self._origin + self._goto(x0+x, y0-y) + + def _goto(self, x1, y1): + x0, y0 = self._position + self._position = (float(x1), float(y1)) + if self._filling: + self._path.append(self._position) + if self._drawing: + if self._tracing: + dx = float(x1 - x0) + dy = float(y1 - y0) + distance = hypot(dx, dy) + nhops = int(distance) + item = self._canvas.create_line(x0, y0, x0, y0, + width=self._width, + capstyle="round", + fill=self._color) + try: + for i in range(1, 1+nhops): + x, y = x0 + dx*i/nhops, y0 + dy*i/nhops + self._canvas.coords(item, x0, y0, x, y) + self._draw_turtle((x,y)) + self._canvas.update() + self._canvas.after(self._delay) + # in case nhops==0 + self._canvas.coords(item, x0, y0, x1, y1) + self._canvas.itemconfigure(item, arrow="none") + except tkinter.TclError: + # Probably the window was closed! + return + else: + item = self._canvas.create_line(x0, y0, x1, y1, + width=self._width, + capstyle="round", + fill=self._color) + self._items.append(item) + self._draw_turtle() + + def speed(self, speed): + """ Set the turtle's speed. + + speed must one of these five strings: + + 'fastest' is a 0 ms delay + 'fast' is a 5 ms delay + 'normal' is a 10 ms delay + 'slow' is a 15 ms delay + 'slowest' is a 20 ms delay + + Example: + >>> turtle.speed('slow') + """ + try: + speed = speed.strip().lower() + self._delay = speeds.index(speed) * 5 + except: + raise ValueError("%r is not a valid speed. speed must be " + "one of %s" % (speed, speeds)) + + + def delay(self, delay): + """ Set the drawing delay in milliseconds. + + This is intended to allow finer control of the drawing speed + than the speed() method + + Example: + >>> turtle.delay(15) + """ + if int(delay) < 0: + raise ValueError("delay must be greater than or equal to 0") + self._delay = int(delay) + + def _draw_turtle(self, position=[]): + if not self._tracing: + self._canvas.update() + return + if position == []: + position = self._position + x,y = position + distance = 8 + dx = distance * cos(self._angle*self._invradian) + dy = distance * sin(self._angle*self._invradian) + self._delete_turtle() + self._arrow = self._canvas.create_line(x-dx,y+dy,x,y, + width=self._width, + arrow="last", + capstyle="round", + fill=self._color) + self._canvas.update() + + def _delete_turtle(self): + if self._arrow != 0: + self._canvas.delete(self._arrow) + self._arrow = 0 + + +_root = None +_canvas = None +_pen = None +_width = 0.50 # 50% of window width +_height = 0.75 # 75% of window height +_startx = None +_starty = None +_title = "Turtle Graphics" # default title + +class Pen(RawPen): + + def __init__(self): + global _root, _canvas + if _root is None: + _root = tkinter.Tk() + _root.wm_protocol("WM_DELETE_WINDOW", self._destroy) + _root.title(_title) + + if _canvas is None: + # XXX Should have scroll bars + _canvas = tkinter.Canvas(_root, background="white") + _canvas.pack(expand=1, fill="both") + + setup(width=_width, height= _height, startx=_startx, starty=_starty) + + RawPen.__init__(self, _canvas) + + def _destroy(self): + global _root, _canvas, _pen + root = self._canvas._root() + if root is _root: + _pen = None + _root = None + _canvas = None + root.destroy() + +def _getpen(): + global _pen + if not _pen: + _pen = Pen() + return _pen + +class Turtle(Pen): + pass + +"""For documentation of the following functions see + the RawPen methods with the same names +""" + +def degrees(): _getpen().degrees() +def radians(): _getpen().radians() +def reset(): _getpen().reset() +def clear(): _getpen().clear() +def tracer(flag): _getpen().tracer(flag) +def forward(distance): _getpen().forward(distance) +def backward(distance): _getpen().backward(distance) +def left(angle): _getpen().left(angle) +def right(angle): _getpen().right(angle) +def up(): _getpen().up() +def down(): _getpen().down() +def width(width): _getpen().width(width) +def color(*args): _getpen().color(*args) +def write(arg, move=0): _getpen().write(arg, move) +def fill(flag): _getpen().fill(flag) +def begin_fill(): _getpen().begin_fill() +def end_fill(): _getpen().end_fill() +def circle(radius, extent=None): _getpen().circle(radius, extent) +def goto(*args): _getpen().goto(*args) +def heading(): return _getpen().heading() +def setheading(angle): _getpen().setheading(angle) +def position(): return _getpen().position() +def window_width(): return _getpen().window_width() +def window_height(): return _getpen().window_height() +def setx(xpos): _getpen().setx(xpos) +def sety(ypos): _getpen().sety(ypos) +def towards(*args): return _getpen().towards(*args) + +def done(): _root.mainloop() +def delay(delay): return _getpen().delay(delay) +def speed(speed): return _getpen().speed(speed) + +for methodname in dir(RawPen): + """ copies RawPen docstrings to module functions of same name """ + if not methodname.startswith("_"): + eval(methodname).__doc__ = RawPen.__dict__[methodname].__doc__ + + +def setup(**geometry): + """ Sets the size and position of the main window. + + Keywords are width, height, startx and starty: + + width: either a size in pixels or a fraction of the screen. + Default is 50% of screen. + height: either the height in pixels or a fraction of the screen. + Default is 75% of screen. + + Setting either width or height to None before drawing will force + use of default geometry as in older versions of turtle.py + + startx: starting position in pixels from the left edge of the screen. + Default is to center window. Setting startx to None is the default + and centers window horizontally on screen. + + starty: starting position in pixels from the top edge of the screen. + Default is to center window. Setting starty to None is the default + and centers window vertically on screen. + + Examples: + >>> setup (width=200, height=200, startx=0, starty=0) + + sets window to 200x200 pixels, in upper left of screen + + >>> setup(width=.75, height=0.5, startx=None, starty=None) + + sets window to 75% of screen by 50% of screen and centers + + >>> setup(width=None) + + forces use of default geometry as in older versions of turtle.py + """ + + global _width, _height, _startx, _starty + + width = geometry.get('width',_width) + if width >= 0 or width is None: + _width = width + else: + raise ValueError("width can not be less than 0") + + height = geometry.get('height',_height) + if height >= 0 or height is None: + _height = height + else: + raise ValueError("height can not be less than 0") + + startx = geometry.get('startx', _startx) + if startx >= 0 or startx is None: + _startx = _startx + else: + raise ValueError("startx can not be less than 0") + + starty = geometry.get('starty', _starty) + if starty >= 0 or starty is None: + _starty = starty + else: + raise ValueError("startx can not be less than 0") + + + if _root and _width and _height: + if 0 < _width <= 1: + _width = _root.winfo_screenwidth() * +width + if 0 < _height <= 1: + _height = _root.winfo_screenheight() * _height + + # center window on screen + if _startx is None: + _startx = (_root.winfo_screenwidth() - _width) / 2 + + if _starty is None: + _starty = (_root.winfo_screenheight() - _height) / 2 + + _root.geometry("%dx%d+%d+%d" % (_width, _height, _startx, _starty)) + +def title(title): + """Set the window title. + + By default this is set to 'Turtle Graphics' + + Example: + >>> title("My Window") + """ + + global _title + _title = title + +def demo(): + reset() + tracer(1) + up() + backward(100) + down() + # draw 3 squares; the last filled + width(3) + for i in range(3): + if i == 2: + fill(1) + for j in range(4): + forward(20) + left(90) + if i == 2: + color("maroon") + fill(0) + up() + forward(30) + down() + width(1) + color("black") + # move out of the way + tracer(0) + up() + right(90) + forward(100) + right(90) + forward(100) + right(180) + down() + # some text + write("startstart", 1) + write("start", 1) + color("red") + # staircase + for i in range(5): + forward(20) + left(90) + forward(20) + right(90) + # filled staircase + fill(1) + for i in range(5): + forward(20) + left(90) + forward(20) + right(90) + fill(0) + tracer(1) + # more text + write("end") + +def demo2(): + # exercises some new and improved features + speed('fast') + width(3) + + # draw a segmented half-circle + setheading(towards(0,0)) + x,y = position() + r = (x**2+y**2)**.5/2.0 + right(90) + pendown = True + for i in range(18): + if pendown: + up() + pendown = False + else: + down() + pendown = True + circle(r,10) + sleep(2) + + reset() + left(90) + + # draw a series of triangles + l = 10 + color("green") + width(3) + left(180) + sp = 5 + for i in range(-2,16): + if i > 0: + color(1.0-0.05*i,0,0.05*i) + fill(1) + color("green") + for j in range(3): + forward(l) + left(120) + l += 10 + left(15) + if sp > 0: + sp = sp-1 + speed(speeds[sp]) + color(0.25,0,0.75) + fill(0) + + # draw and fill a concave shape + left(120) + up() + forward(70) + right(30) + down() + color("red") + speed("fastest") + fill(1) + for i in range(4): + circle(50,90) + right(90) + forward(30) + right(90) + color("yellow") + fill(0) + left(90) + up() + forward(30) + down(); + + color("red") + + # create a second turtle and make the original pursue and catch it + turtle=Turtle() + turtle.reset() + turtle.left(90) + turtle.speed('normal') + turtle.up() + turtle.goto(280,40) + turtle.left(24) + turtle.down() + turtle.speed('fast') + turtle.color("blue") + turtle.width(2) + speed('fastest') + + # turn default turtle towards new turtle object + setheading(towards(turtle)) + while ( abs(position()[0]-turtle.position()[0])>4 or + abs(position()[1]-turtle.position()[1])>4): + turtle.forward(3.5) + turtle.left(0.6) + # turn default turtle towards new turtle object + setheading(towards(turtle)) + forward(4) + write("CAUGHT! ", move=True) + + + +if __name__ == '__main__': + demo() + sleep(3) + demo2() + done() Index: Lib/tkinter/colorchooser.py =================================================================== --- Lib/tkinter/colorchooser.py (revision 0) +++ Lib/tkinter/colorchooser.py (revision 0) @@ -0,0 +1,70 @@ +# tk common colour chooser dialogue +# +# this module provides an interface to the native color dialogue +# available in Tk 4.2 and newer. +# +# written by Fredrik Lundh, May 1997 +# +# fixed initialcolor handling in August 1998 +# + +# +# options (all have default values): +# +# - initialcolor: colour to mark as selected when dialog is displayed +# (given as an RGB triplet or a Tk color string) +# +# - parent: which window to place the dialog on top of +# +# - title: dialog title +# + +from tkinter.commondialog import Dialog + + +# +# color chooser class + +class Chooser(Dialog): + "Ask for a color" + + command = "tk_chooseColor" + + def _fixoptions(self): + try: + # make sure initialcolor is a tk color string + color = self.options["initialcolor"] + if type(color) == type(()): + # assume an RGB triplet + self.options["initialcolor"] = "#%02x%02x%02x" % color + except KeyError: + pass + + def _fixresult(self, widget, result): + # to simplify application code, the color chooser returns + # an RGB tuple together with the Tk color string + if not result: + return None, None # canceled + r, g, b = widget.winfo_rgb(result) + return (r/256, g/256, b/256), result + + +# +# convenience stuff + +def askcolor(color = None, **options): + "Ask for a color" + + if color: + options = options.copy() + options["initialcolor"] = color + + return Chooser(**options).show() + + +# -------------------------------------------------------------------- +# test stuff + +if __name__ == "__main__": + + print("color", askcolor()) Index: Lib/tkinter/tix.py =================================================================== --- Lib/tkinter/tix.py (revision 0) +++ Lib/tkinter/tix.py (revision 0) @@ -0,0 +1,1892 @@ +# -*-mode: python; fill-column: 75; tab-width: 8 -*- +# +# $Id: tix.py 57692 2007-08-30 01:19:48Z collin.winter $ +# +# tix.py -- Tix widget wrappers. +# +# For Tix, see http://tix.sourceforge.net +# +# - Sudhir Shenoy (sshenoy@gol.com), Dec. 1995. +# based on an idea of Jean-Marc Lugrin (lugrin@ms.com) +# +# NOTE: In order to minimize changes to tkinter, some of the code here +# (TixWidget.__init__) has been taken from tkinter (Widget.__init__) +# and will break if there are major changes in tkinter. +# +# The Tix widgets are represented by a class hierarchy in python with proper +# inheritance of base classes. +# +# As a result after creating a 'w = StdButtonBox', I can write +# w.ok['text'] = 'Who Cares' +# or w.ok['bg'] = w['bg'] +# or even w.ok.invoke() +# etc. +# +# Compare the demo tixwidgets.py to the original Tcl program and you will +# appreciate the advantages. +# + +from tkinter import * +from tkinter import _flatten, _cnfmerge, _default_root + +# WARNING - TkVersion is a limited precision floating point number +if TkVersion < 3.999: + raise ImportError("This version of tix.py requires Tk 4.0 or higher") + +import _tkinter # If this fails your Python may not be configured for Tk + +# Some more constants (for consistency with tkinter) +WINDOW = 'window' +TEXT = 'text' +STATUS = 'status' +IMMEDIATE = 'immediate' +IMAGE = 'image' +IMAGETEXT = 'imagetext' +BALLOON = 'balloon' +AUTO = 'auto' +ACROSSTOP = 'acrosstop' + +# Some constants used by tkinter dooneevent() +TCL_DONT_WAIT = 1 << 1 +TCL_WINDOW_EVENTS = 1 << 2 +TCL_FILE_EVENTS = 1 << 3 +TCL_TIMER_EVENTS = 1 << 4 +TCL_IDLE_EVENTS = 1 << 5 +TCL_ALL_EVENTS = 0 + +# BEWARE - this is implemented by copying some code from the Widget class +# in tkinter (to override Widget initialization) and is therefore +# liable to break. +import tkinter, os + +# Could probably add this to tkinter.Misc +class tixCommand: + """The tix commands provide access to miscellaneous elements + of Tix's internal state and the Tix application context. + Most of the information manipulated by these commands pertains + to the application as a whole, or to a screen or + display, rather than to a particular window. + + This is a mixin class, assumed to be mixed to tkinter.Tk + that supports the self.tk.call method. + """ + + def tix_addbitmapdir(self, directory): + """Tix maintains a list of directories under which + the tix_getimage and tix_getbitmap commands will + search for image files. The standard bitmap directory + is $TIX_LIBRARY/bitmaps. The addbitmapdir command + adds directory into this list. By using this + command, the image files of an applications can + also be located using the tix_getimage or tix_getbitmap + command. + """ + return self.tk.call('tix', 'addbitmapdir', directory) + + def tix_cget(self, option): + """Returns the current value of the configuration + option given by option. Option may be any of the + options described in the CONFIGURATION OPTIONS section. + """ + return self.tk.call('tix', 'cget', option) + + def tix_configure(self, cnf=None, **kw): + """Query or modify the configuration options of the Tix application + context. If no option is specified, returns a dictionary all of the + available options. If option is specified with no value, then the + command returns a list describing the one named option (this list + will be identical to the corresponding sublist of the value + returned if no option is specified). If one or more option-value + pairs are specified, then the command modifies the given option(s) + to have the given value(s); in this case the command returns an + empty string. Option may be any of the configuration options. + """ + # Copied from tkinter/__init__.py + if kw: + cnf = _cnfmerge((cnf, kw)) + elif cnf: + cnf = _cnfmerge(cnf) + if cnf is None: + cnf = {} + for x in self.tk.split(self.tk.call('tix', 'configure')): + cnf[x[0][1:]] = (x[0][1:],) + x[1:] + return cnf + if isinstance(cnf, StringType): + x = self.tk.split(self.tk.call('tix', 'configure', '-'+cnf)) + return (x[0][1:],) + x[1:] + return self.tk.call(('tix', 'configure') + self._options(cnf)) + + def tix_filedialog(self, dlgclass=None): + """Returns the file selection dialog that may be shared among + different calls from this application. This command will create a + file selection dialog widget when it is called the first time. This + dialog will be returned by all subsequent calls to tix_filedialog. + An optional dlgclass parameter can be passed to specified what type + of file selection dialog widget is desired. Possible options are + tix FileSelectDialog or tixExFileSelectDialog. + """ + if dlgclass is not None: + return self.tk.call('tix', 'filedialog', dlgclass) + else: + return self.tk.call('tix', 'filedialog') + + def tix_getbitmap(self, name): + """Locates a bitmap file of the name name.xpm or name in one of the + bitmap directories (see the tix_addbitmapdir command above). By + using tix_getbitmap, you can avoid hard coding the pathnames of the + bitmap files in your application. When successful, it returns the + complete pathname of the bitmap file, prefixed with the character + '@'. The returned value can be used to configure the -bitmap + option of the TK and Tix widgets. + """ + return self.tk.call('tix', 'getbitmap', name) + + def tix_getimage(self, name): + """Locates an image file of the name name.xpm, name.xbm or name.ppm + in one of the bitmap directories (see the addbitmapdir command + above). If more than one file with the same name (but different + extensions) exist, then the image type is chosen according to the + depth of the X display: xbm images are chosen on monochrome + displays and color images are chosen on color displays. By using + tix_ getimage, you can advoid hard coding the pathnames of the + image files in your application. When successful, this command + returns the name of the newly created image, which can be used to + configure the -image option of the Tk and Tix widgets. + """ + return self.tk.call('tix', 'getimage', name) + + def tix_option_get(self, name): + """Gets the options manitained by the Tix + scheme mechanism. Available options include: + + active_bg active_fg bg + bold_font dark1_bg dark1_fg + dark2_bg dark2_fg disabled_fg + fg fixed_font font + inactive_bg inactive_fg input1_bg + input2_bg italic_font light1_bg + light1_fg light2_bg light2_fg + menu_font output1_bg output2_bg + select_bg select_fg selector + """ + # could use self.tk.globalgetvar('tixOption', name) + return self.tk.call('tix', 'option', 'get', name) + + def tix_resetoptions(self, newScheme, newFontSet, newScmPrio=None): + """Resets the scheme and fontset of the Tix application to + newScheme and newFontSet, respectively. This affects only those + widgets created after this call. Therefore, it is best to call the + resetoptions command before the creation of any widgets in a Tix + application. + + The optional parameter newScmPrio can be given to reset the + priority level of the Tk options set by the Tix schemes. + + Because of the way Tk handles the X option database, after Tix has + been has imported and inited, it is not possible to reset the color + schemes and font sets using the tix config command. Instead, the + tix_resetoptions command must be used. + """ + if newScmPrio is not None: + return self.tk.call('tix', 'resetoptions', newScheme, newFontSet, newScmPrio) + else: + return self.tk.call('tix', 'resetoptions', newScheme, newFontSet) + +class Tk(tkinter.Tk, tixCommand): + """Toplevel widget of Tix which represents mostly the main window + of an application. It has an associated Tcl interpreter.""" + def __init__(self, screenName=None, baseName=None, className='Tix'): + tkinter.Tk.__init__(self, screenName, baseName, className) + tixlib = os.environ.get('TIX_LIBRARY') + self.tk.eval('global auto_path; lappend auto_path [file dir [info nameof]]') + if tixlib is not None: + self.tk.eval('global auto_path; lappend auto_path {%s}' % tixlib) + self.tk.eval('global tcl_pkgPath; lappend tcl_pkgPath {%s}' % tixlib) + # Load Tix - this should work dynamically or statically + # If it's static, tcl/tix8.1/pkgIndex.tcl should have + # 'load {} Tix' + # If it's dynamic under Unix, tcl/tix8.1/pkgIndex.tcl should have + # 'load libtix8.1.8.3.so Tix' + self.tk.eval('package require Tix') + + def destroy(self): + # For safety, remove an delete_window binding before destroy + self.protocol("WM_DELETE_WINDOW", "") + tkinter.Tk.destroy(self) + +# The Tix 'tixForm' geometry manager +class Form: + """The Tix Form geometry manager + + Widgets can be arranged by specifying attachments to other widgets. + See Tix documentation for complete details""" + + def config(self, cnf={}, **kw): + self.tk.call('tixForm', self._w, *self._options(cnf, kw)) + + form = config + + def __setitem__(self, key, value): + Form.form(self, {key: value}) + + def check(self): + return self.tk.call('tixForm', 'check', self._w) + + def forget(self): + self.tk.call('tixForm', 'forget', self._w) + + def grid(self, xsize=0, ysize=0): + if (not xsize) and (not ysize): + x = self.tk.call('tixForm', 'grid', self._w) + y = self.tk.splitlist(x) + z = () + for x in y: + z = z + (self.tk.getint(x),) + return z + return self.tk.call('tixForm', 'grid', self._w, xsize, ysize) + + def info(self, option=None): + if not option: + return self.tk.call('tixForm', 'info', self._w) + if option[0] != '-': + option = '-' + option + return self.tk.call('tixForm', 'info', self._w, option) + + def slaves(self): + return map(self._nametowidget, + self.tk.splitlist( + self.tk.call( + 'tixForm', 'slaves', self._w))) + + + +tkinter.Widget.__bases__ = tkinter.Widget.__bases__ + (Form,) + +class TixWidget(tkinter.Widget): + """A TixWidget class is used to package all (or most) Tix widgets. + + Widget initialization is extended in two ways: + 1) It is possible to give a list of options which must be part of + the creation command (so called Tix 'static' options). These cannot be + given as a 'config' command later. + 2) It is possible to give the name of an existing TK widget. These are + child widgets created automatically by a Tix mega-widget. The Tk call + to create these widgets is therefore bypassed in TixWidget.__init__ + + Both options are for use by subclasses only. + """ + def __init__ (self, master=None, widgetName=None, + static_options=None, cnf={}, kw={}): + # Merge keywords and dictionary arguments + if kw: + cnf = _cnfmerge((cnf, kw)) + else: + cnf = _cnfmerge(cnf) + + # Move static options into extra. static_options must be + # a list of keywords (or None). + extra=() + + # 'options' is always a static option + if static_options: + static_options.append('options') + else: + static_options = ['options'] + + for k,v in cnf.items()[:]: + if k in static_options: + extra = extra + ('-' + k, v) + del cnf[k] + + self.widgetName = widgetName + Widget._setup(self, master, cnf) + + # If widgetName is None, this is a dummy creation call where the + # corresponding Tk widget has already been created by Tix + if widgetName: + self.tk.call(widgetName, self._w, *extra) + + # Non-static options - to be done via a 'config' command + if cnf: + Widget.config(self, cnf) + + # Dictionary to hold subwidget names for easier access. We can't + # use the children list because the public Tix names may not be the + # same as the pathname component + self.subwidget_list = {} + + # We set up an attribute access function so that it is possible to + # do w.ok['text'] = 'Hello' rather than w.subwidget('ok')['text'] = 'Hello' + # when w is a StdButtonBox. + # We can even do w.ok.invoke() because w.ok is subclassed from the + # Button class if you go through the proper constructors + def __getattr__(self, name): + if name in self.subwidget_list: + return self.subwidget_list[name] + raise AttributeError(name) + + def set_silent(self, value): + """Set a variable without calling its action routine""" + self.tk.call('tixSetSilent', self._w, value) + + def subwidget(self, name): + """Return the named subwidget (which must have been created by + the sub-class).""" + n = self._subwidget_name(name) + if not n: + raise TclError("Subwidget " + name + " not child of " + self._name) + # Remove header of name and leading dot + n = n[len(self._w)+1:] + return self._nametowidget(n) + + def subwidgets_all(self): + """Return all subwidgets.""" + names = self._subwidget_names() + if not names: + return [] + retlist = [] + for name in names: + name = name[len(self._w)+1:] + try: + retlist.append(self._nametowidget(name)) + except: + # some of the widgets are unknown e.g. border in LabelFrame + pass + return retlist + + def _subwidget_name(self,name): + """Get a subwidget name (returns a String, not a Widget !)""" + try: + return self.tk.call(self._w, 'subwidget', name) + except TclError: + return None + + def _subwidget_names(self): + """Return the name of all subwidgets.""" + try: + x = self.tk.call(self._w, 'subwidgets', '-all') + return self.tk.split(x) + except TclError: + return None + + def config_all(self, option, value): + """Set configuration options for all subwidgets (and self).""" + if option == '': + return + elif not isinstance(option, StringType): + option = repr(option) + if not isinstance(value, StringType): + value = repr(value) + names = self._subwidget_names() + for name in names: + self.tk.call(name, 'configure', '-' + option, value) + # These are missing from tkinter + def image_create(self, imgtype, cnf={}, master=None, **kw): + if not master: + master = tkinter._default_root + if not master: + raise RuntimeError('Too early to create image') + if kw and cnf: cnf = _cnfmerge((cnf, kw)) + elif kw: cnf = kw + options = () + for k, v in cnf.items(): + if hasattr(v, '__call__'): + v = self._register(v) + options = options + ('-'+k, v) + return master.tk.call(('image', 'create', imgtype,) + options) + def image_delete(self, imgname): + try: + self.tk.call('image', 'delete', imgname) + except TclError: + # May happen if the root was destroyed + pass + +# Subwidgets are child widgets created automatically by mega-widgets. +# In python, we have to create these subwidgets manually to mirror their +# existence in Tk/Tix. +class TixSubWidget(TixWidget): + """Subwidget class. + + This is used to mirror child widgets automatically created + by Tix/Tk as part of a mega-widget in Python (which is not informed + of this)""" + + def __init__(self, master, name, + destroy_physically=1, check_intermediate=1): + if check_intermediate: + path = master._subwidget_name(name) + try: + path = path[len(master._w)+1:] + plist = path.split('.') + except: + plist = [] + + if not check_intermediate: + # immediate descendant + TixWidget.__init__(self, master, None, None, {'name' : name}) + else: + # Ensure that the intermediate widgets exist + parent = master + for i in range(len(plist) - 1): + n = '.'.join(plist[:i+1]) + try: + w = master._nametowidget(n) + parent = w + except KeyError: + # Create the intermediate widget + parent = TixSubWidget(parent, plist[i], + destroy_physically=0, + check_intermediate=0) + # The Tk widget name is in plist, not in name + if plist: + name = plist[-1] + TixWidget.__init__(self, parent, None, None, {'name' : name}) + self.destroy_physically = destroy_physically + + def destroy(self): + # For some widgets e.g., a NoteBook, when we call destructors, + # we must be careful not to destroy the frame widget since this + # also destroys the parent NoteBook thus leading to an exception + # in tkinter when it finally calls Tcl to destroy the NoteBook + for c in self.children.values(): c.destroy() + if self._name in self.master.children: + del self.master.children[self._name] + if self._name in self.master.subwidget_list: + del self.master.subwidget_list[self._name] + if self.destroy_physically: + # This is bypassed only for a few widgets + self.tk.call('destroy', self._w) + + +# Useful func. to split Tcl lists and return as a dict. +# From tkinter/__init__.py +def _lst2dict(lst): + dict = {} + for x in lst: + dict[x[0][1:]] = (x[0][1:],) + x[1:] + return dict + +# Useful class to create a display style - later shared by many items. +# Contributed by Steffen Kremser +class DisplayStyle: + """DisplayStyle - handle configuration options shared by + (multiple) Display Items""" + + def __init__(self, itemtype, cnf={}, **kw): + master = _default_root # global from tkinter + if not master and 'refwindow' in cnf: master=cnf['refwindow'] + elif not master and 'refwindow' in kw: master= kw['refwindow'] + elif not master: raise RuntimeError("Too early to create display style: no root window") + self.tk = master.tk + self.stylename = self.tk.call('tixDisplayStyle', itemtype, + *self._options(cnf,kw) ) + + def __str__(self): + return self.stylename + + def _options(self, cnf, kw): + if kw and cnf: + cnf = _cnfmerge((cnf, kw)) + elif kw: + cnf = kw + opts = () + for k, v in cnf.items(): + opts = opts + ('-'+k, v) + return opts + + def delete(self): + self.tk.call(self.stylename, 'delete') + + def __setitem__(self,key,value): + self.tk.call(self.stylename, 'configure', '-%s'%key, value) + + def config(self, cnf={}, **kw): + return _lst2dict( + self.tk.split( + self.tk.call( + self.stylename, 'configure', *self._options(cnf,kw)))) + + def __getitem__(self,key): + return self.tk.call(self.stylename, 'cget', '-%s'%key) + + +###################################################### +### The Tix Widget classes - in alphabetical order ### +###################################################### + +class Balloon(TixWidget): + """Balloon help widget. + + Subwidget Class + --------- ----- + label Label + message Message""" + + # FIXME: It should inherit -superclass tixShell + def __init__(self, master=None, cnf={}, **kw): + # static seem to be -installcolormap -initwait -statusbar -cursor + static = ['options', 'installcolormap', 'initwait', 'statusbar', + 'cursor'] + TixWidget.__init__(self, master, 'tixBalloon', static, cnf, kw) + self.subwidget_list['label'] = _dummyLabel(self, 'label', + destroy_physically=0) + self.subwidget_list['message'] = _dummyLabel(self, 'message', + destroy_physically=0) + + def bind_widget(self, widget, cnf={}, **kw): + """Bind balloon widget to another. + One balloon widget may be bound to several widgets at the same time""" + self.tk.call(self._w, 'bind', widget._w, *self._options(cnf, kw)) + + def unbind_widget(self, widget): + self.tk.call(self._w, 'unbind', widget._w) + +class ButtonBox(TixWidget): + """ButtonBox - A container for pushbuttons. + Subwidgets are the buttons added with the add method. + """ + def __init__(self, master=None, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixButtonBox', + ['orientation', 'options'], cnf, kw) + + def add(self, name, cnf={}, **kw): + """Add a button with given name to box.""" + + btn = self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) + self.subwidget_list[name] = _dummyButton(self, name) + return btn + + def invoke(self, name): + if name in self.subwidget_list: + self.tk.call(self._w, 'invoke', name) + +class ComboBox(TixWidget): + """ComboBox - an Entry field with a dropdown menu. The user can select a + choice by either typing in the entry subwdget or selecting from the + listbox subwidget. + + Subwidget Class + --------- ----- + entry Entry + arrow Button + slistbox ScrolledListBox + tick Button + cross Button : present if created with the fancy option""" + + # FIXME: It should inherit -superclass tixLabelWidget + def __init__ (self, master=None, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixComboBox', + ['editable', 'dropdown', 'fancy', 'options'], + cnf, kw) + self.subwidget_list['label'] = _dummyLabel(self, 'label') + self.subwidget_list['entry'] = _dummyEntry(self, 'entry') + self.subwidget_list['arrow'] = _dummyButton(self, 'arrow') + self.subwidget_list['slistbox'] = _dummyScrolledListBox(self, + 'slistbox') + try: + self.subwidget_list['tick'] = _dummyButton(self, 'tick') + self.subwidget_list['cross'] = _dummyButton(self, 'cross') + except TypeError: + # unavailable when -fancy not specified + pass + + # align + + def add_history(self, str): + self.tk.call(self._w, 'addhistory', str) + + def append_history(self, str): + self.tk.call(self._w, 'appendhistory', str) + + def insert(self, index, str): + self.tk.call(self._w, 'insert', index, str) + + def pick(self, index): + self.tk.call(self._w, 'pick', index) + +class Control(TixWidget): + """Control - An entry field with value change arrows. The user can + adjust the value by pressing the two arrow buttons or by entering + the value directly into the entry. The new value will be checked + against the user-defined upper and lower limits. + + Subwidget Class + --------- ----- + incr Button + decr Button + entry Entry + label Label""" + + # FIXME: It should inherit -superclass tixLabelWidget + def __init__ (self, master=None, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixControl', ['options'], cnf, kw) + self.subwidget_list['incr'] = _dummyButton(self, 'incr') + self.subwidget_list['decr'] = _dummyButton(self, 'decr') + self.subwidget_list['label'] = _dummyLabel(self, 'label') + self.subwidget_list['entry'] = _dummyEntry(self, 'entry') + + def decrement(self): + self.tk.call(self._w, 'decr') + + def increment(self): + self.tk.call(self._w, 'incr') + + def invoke(self): + self.tk.call(self._w, 'invoke') + + def update(self): + self.tk.call(self._w, 'update') + +class DirList(TixWidget): + """DirList - displays a list view of a directory, its previous + directories and its sub-directories. The user can choose one of + the directories displayed in the list or change to another directory. + + Subwidget Class + --------- ----- + hlist HList + hsb Scrollbar + vsb Scrollbar""" + + # FIXME: It should inherit -superclass tixScrolledHList + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixDirList', ['options'], cnf, kw) + self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + + def chdir(self, dir): + self.tk.call(self._w, 'chdir', dir) + +class DirTree(TixWidget): + """DirTree - Directory Listing in a hierarchical view. + Displays a tree view of a directory, its previous directories and its + sub-directories. The user can choose one of the directories displayed + in the list or change to another directory. + + Subwidget Class + --------- ----- + hlist HList + hsb Scrollbar + vsb Scrollbar""" + + # FIXME: It should inherit -superclass tixScrolledHList + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixDirTree', ['options'], cnf, kw) + self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + + def chdir(self, dir): + self.tk.call(self._w, 'chdir', dir) + +class DirSelectBox(TixWidget): + """DirSelectBox - Motif style file select box. + It is generally used for + the user to choose a file. FileSelectBox stores the files mostly + recently selected into a ComboBox widget so that they can be quickly + selected again. + + Subwidget Class + --------- ----- + selection ComboBox + filter ComboBox + dirlist ScrolledListBox + filelist ScrolledListBox""" + + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixDirSelectBox', ['options'], cnf, kw) + self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist') + self.subwidget_list['dircbx'] = _dummyFileComboBox(self, 'dircbx') + +class ExFileSelectBox(TixWidget): + """ExFileSelectBox - MS Windows style file select box. + It provides an convenient method for the user to select files. + + Subwidget Class + --------- ----- + cancel Button + ok Button + hidden Checkbutton + types ComboBox + dir ComboBox + file ComboBox + dirlist ScrolledListBox + filelist ScrolledListBox""" + + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixExFileSelectBox', ['options'], cnf, kw) + self.subwidget_list['cancel'] = _dummyButton(self, 'cancel') + self.subwidget_list['ok'] = _dummyButton(self, 'ok') + self.subwidget_list['hidden'] = _dummyCheckbutton(self, 'hidden') + self.subwidget_list['types'] = _dummyComboBox(self, 'types') + self.subwidget_list['dir'] = _dummyComboBox(self, 'dir') + self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist') + self.subwidget_list['file'] = _dummyComboBox(self, 'file') + self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist') + + def filter(self): + self.tk.call(self._w, 'filter') + + def invoke(self): + self.tk.call(self._w, 'invoke') + + +# Should inherit from a Dialog class +class DirSelectDialog(TixWidget): + """The DirSelectDialog widget presents the directories in the file + system in a dialog window. The user can use this dialog window to + navigate through the file system to select the desired directory. + + Subwidgets Class + ---------- ----- + dirbox DirSelectDialog""" + + # FIXME: It should inherit -superclass tixDialogShell + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixDirSelectDialog', + ['options'], cnf, kw) + self.subwidget_list['dirbox'] = _dummyDirSelectBox(self, 'dirbox') + # cancel and ok buttons are missing + + def popup(self): + self.tk.call(self._w, 'popup') + + def popdown(self): + self.tk.call(self._w, 'popdown') + + +# Should inherit from a Dialog class +class ExFileSelectDialog(TixWidget): + """ExFileSelectDialog - MS Windows style file select dialog. + It provides an convenient method for the user to select files. + + Subwidgets Class + ---------- ----- + fsbox ExFileSelectBox""" + + # FIXME: It should inherit -superclass tixDialogShell + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixExFileSelectDialog', + ['options'], cnf, kw) + self.subwidget_list['fsbox'] = _dummyExFileSelectBox(self, 'fsbox') + + def popup(self): + self.tk.call(self._w, 'popup') + + def popdown(self): + self.tk.call(self._w, 'popdown') + +class FileSelectBox(TixWidget): + """ExFileSelectBox - Motif style file select box. + It is generally used for + the user to choose a file. FileSelectBox stores the files mostly + recently selected into a ComboBox widget so that they can be quickly + selected again. + + Subwidget Class + --------- ----- + selection ComboBox + filter ComboBox + dirlist ScrolledListBox + filelist ScrolledListBox""" + + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixFileSelectBox', ['options'], cnf, kw) + self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist') + self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist') + self.subwidget_list['filter'] = _dummyComboBox(self, 'filter') + self.subwidget_list['selection'] = _dummyComboBox(self, 'selection') + + def apply_filter(self): # name of subwidget is same as command + self.tk.call(self._w, 'filter') + + def invoke(self): + self.tk.call(self._w, 'invoke') + +# Should inherit from a Dialog class +class FileSelectDialog(TixWidget): + """FileSelectDialog - Motif style file select dialog. + + Subwidgets Class + ---------- ----- + btns StdButtonBox + fsbox FileSelectBox""" + + # FIXME: It should inherit -superclass tixStdDialogShell + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixFileSelectDialog', + ['options'], cnf, kw) + self.subwidget_list['btns'] = _dummyStdButtonBox(self, 'btns') + self.subwidget_list['fsbox'] = _dummyFileSelectBox(self, 'fsbox') + + def popup(self): + self.tk.call(self._w, 'popup') + + def popdown(self): + self.tk.call(self._w, 'popdown') + +class FileEntry(TixWidget): + """FileEntry - Entry field with button that invokes a FileSelectDialog. + The user can type in the filename manually. Alternatively, the user can + press the button widget that sits next to the entry, which will bring + up a file selection dialog. + + Subwidgets Class + ---------- ----- + button Button + entry Entry""" + + # FIXME: It should inherit -superclass tixLabelWidget + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixFileEntry', + ['dialogtype', 'options'], cnf, kw) + self.subwidget_list['button'] = _dummyButton(self, 'button') + self.subwidget_list['entry'] = _dummyEntry(self, 'entry') + + def invoke(self): + self.tk.call(self._w, 'invoke') + + def file_dialog(self): + # FIXME: return python object + pass + +class HList(TixWidget): + """HList - Hierarchy display widget can be used to display any data + that have a hierarchical structure, for example, file system directory + trees. The list entries are indented and connected by branch lines + according to their places in the hierachy. + + Subwidgets - None""" + + def __init__ (self,master=None,cnf={}, **kw): + TixWidget.__init__(self, master, 'tixHList', + ['columns', 'options'], cnf, kw) + + def add(self, entry, cnf={}, **kw): + return self.tk.call(self._w, 'add', entry, *self._options(cnf, kw)) + + def add_child(self, parent=None, cnf={}, **kw): + if not parent: + parent = '' + return self.tk.call( + self._w, 'addchild', parent, *self._options(cnf, kw)) + + def anchor_set(self, entry): + self.tk.call(self._w, 'anchor', 'set', entry) + + def anchor_clear(self): + self.tk.call(self._w, 'anchor', 'clear') + + def column_width(self, col=0, width=None, chars=None): + if not chars: + return self.tk.call(self._w, 'column', 'width', col, width) + else: + return self.tk.call(self._w, 'column', 'width', col, + '-char', chars) + + def delete_all(self): + self.tk.call(self._w, 'delete', 'all') + + def delete_entry(self, entry): + self.tk.call(self._w, 'delete', 'entry', entry) + + def delete_offsprings(self, entry): + self.tk.call(self._w, 'delete', 'offsprings', entry) + + def delete_siblings(self, entry): + self.tk.call(self._w, 'delete', 'siblings', entry) + + def dragsite_set(self, index): + self.tk.call(self._w, 'dragsite', 'set', index) + + def dragsite_clear(self): + self.tk.call(self._w, 'dragsite', 'clear') + + def dropsite_set(self, index): + self.tk.call(self._w, 'dropsite', 'set', index) + + def dropsite_clear(self): + self.tk.call(self._w, 'dropsite', 'clear') + + def header_create(self, col, cnf={}, **kw): + self.tk.call(self._w, 'header', 'create', col, *self._options(cnf, kw)) + + def header_configure(self, col, cnf={}, **kw): + if cnf is None: + return _lst2dict( + self.tk.split( + self.tk.call(self._w, 'header', 'configure', col))) + self.tk.call(self._w, 'header', 'configure', col, + *self._options(cnf, kw)) + + def header_cget(self, col, opt): + return self.tk.call(self._w, 'header', 'cget', col, opt) + + def header_exists(self, col): + return self.tk.call(self._w, 'header', 'exists', col) + + def header_delete(self, col): + self.tk.call(self._w, 'header', 'delete', col) + + def header_size(self, col): + return self.tk.call(self._w, 'header', 'size', col) + + def hide_entry(self, entry): + self.tk.call(self._w, 'hide', 'entry', entry) + + def indicator_create(self, entry, cnf={}, **kw): + self.tk.call( + self._w, 'indicator', 'create', entry, *self._options(cnf, kw)) + + def indicator_configure(self, entry, cnf={}, **kw): + if cnf is None: + return _lst2dict( + self.tk.split( + self.tk.call(self._w, 'indicator', 'configure', entry))) + self.tk.call( + self._w, 'indicator', 'configure', entry, *self._options(cnf, kw)) + + def indicator_cget(self, entry, opt): + return self.tk.call(self._w, 'indicator', 'cget', entry, opt) + + def indicator_exists(self, entry): + return self.tk.call (self._w, 'indicator', 'exists', entry) + + def indicator_delete(self, entry): + self.tk.call(self._w, 'indicator', 'delete', entry) + + def indicator_size(self, entry): + return self.tk.call(self._w, 'indicator', 'size', entry) + + def info_anchor(self): + return self.tk.call(self._w, 'info', 'anchor') + + def info_children(self, entry=None): + c = self.tk.call(self._w, 'info', 'children', entry) + return self.tk.splitlist(c) + + def info_data(self, entry): + return self.tk.call(self._w, 'info', 'data', entry) + + def info_exists(self, entry): + return self.tk.call(self._w, 'info', 'exists', entry) + + def info_hidden(self, entry): + return self.tk.call(self._w, 'info', 'hidden', entry) + + def info_next(self, entry): + return self.tk.call(self._w, 'info', 'next', entry) + + def info_parent(self, entry): + return self.tk.call(self._w, 'info', 'parent', entry) + + def info_prev(self, entry): + return self.tk.call(self._w, 'info', 'prev', entry) + + def info_selection(self): + c = self.tk.call(self._w, 'info', 'selection') + return self.tk.splitlist(c) + + def item_cget(self, entry, col, opt): + return self.tk.call(self._w, 'item', 'cget', entry, col, opt) + + def item_configure(self, entry, col, cnf={}, **kw): + if cnf is None: + return _lst2dict( + self.tk.split( + self.tk.call(self._w, 'item', 'configure', entry, col))) + self.tk.call(self._w, 'item', 'configure', entry, col, + *self._options(cnf, kw)) + + def item_create(self, entry, col, cnf={}, **kw): + self.tk.call( + self._w, 'item', 'create', entry, col, *self._options(cnf, kw)) + + def item_exists(self, entry, col): + return self.tk.call(self._w, 'item', 'exists', entry, col) + + def item_delete(self, entry, col): + self.tk.call(self._w, 'item', 'delete', entry, col) + + def entrycget(self, entry, opt): + return self.tk.call(self._w, 'entrycget', entry, opt) + + def entryconfigure(self, entry, cnf={}, **kw): + if cnf is None: + return _lst2dict( + self.tk.split( + self.tk.call(self._w, 'entryconfigure', entry))) + self.tk.call(self._w, 'entryconfigure', entry, + *self._options(cnf, kw)) + + def nearest(self, y): + return self.tk.call(self._w, 'nearest', y) + + def see(self, entry): + self.tk.call(self._w, 'see', entry) + + def selection_clear(self, cnf={}, **kw): + self.tk.call(self._w, 'selection', 'clear', *self._options(cnf, kw)) + + def selection_includes(self, entry): + return self.tk.call(self._w, 'selection', 'includes', entry) + + def selection_set(self, first, last=None): + self.tk.call(self._w, 'selection', 'set', first, last) + + def show_entry(self, entry): + return self.tk.call(self._w, 'show', 'entry', entry) + + def xview(self, *args): + self.tk.call(self._w, 'xview', *args) + + def yview(self, *args): + self.tk.call(self._w, 'yview', *args) + +class InputOnly(TixWidget): + """InputOnly - Invisible widget. Unix only. + + Subwidgets - None""" + + def __init__ (self,master=None,cnf={}, **kw): + TixWidget.__init__(self, master, 'tixInputOnly', None, cnf, kw) + +class LabelEntry(TixWidget): + """LabelEntry - Entry field with label. Packages an entry widget + and a label into one mega widget. It can beused be used to simplify + the creation of ``entry-form'' type of interface. + + Subwidgets Class + ---------- ----- + label Label + entry Entry""" + + def __init__ (self,master=None,cnf={}, **kw): + TixWidget.__init__(self, master, 'tixLabelEntry', + ['labelside','options'], cnf, kw) + self.subwidget_list['label'] = _dummyLabel(self, 'label') + self.subwidget_list['entry'] = _dummyEntry(self, 'entry') + +class LabelFrame(TixWidget): + """LabelFrame - Labelled Frame container. Packages a frame widget + and a label into one mega widget. To create widgets inside a + LabelFrame widget, one creates the new widgets relative to the + frame subwidget and manage them inside the frame subwidget. + + Subwidgets Class + ---------- ----- + label Label + frame Frame""" + + def __init__ (self,master=None,cnf={}, **kw): + TixWidget.__init__(self, master, 'tixLabelFrame', + ['labelside','options'], cnf, kw) + self.subwidget_list['label'] = _dummyLabel(self, 'label') + self.subwidget_list['frame'] = _dummyFrame(self, 'frame') + + +class ListNoteBook(TixWidget): + """A ListNoteBook widget is very similar to the TixNoteBook widget: + it can be used to display many windows in a limited space using a + notebook metaphor. The notebook is divided into a stack of pages + (windows). At one time only one of these pages can be shown. + The user can navigate through these pages by + choosing the name of the desired page in the hlist subwidget.""" + + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixListNoteBook', ['options'], cnf, kw) + # Is this necessary? It's not an exposed subwidget in Tix. + self.subwidget_list['pane'] = _dummyPanedWindow(self, 'pane', + destroy_physically=0) + self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') + self.subwidget_list['shlist'] = _dummyScrolledHList(self, 'shlist') + + def add(self, name, cnf={}, **kw): + self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) + self.subwidget_list[name] = TixSubWidget(self, name) + return self.subwidget_list[name] + + def page(self, name): + return self.subwidget(name) + + def pages(self): + # Can't call subwidgets_all directly because we don't want .nbframe + names = self.tk.split(self.tk.call(self._w, 'pages')) + ret = [] + for x in names: + ret.append(self.subwidget(x)) + return ret + + def raise_page(self, name): # raise is a python keyword + self.tk.call(self._w, 'raise', name) + +class Meter(TixWidget): + """The Meter widget can be used to show the progress of a background + job which may take a long time to execute. + """ + + def __init__(self, master=None, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixMeter', + ['options'], cnf, kw) + +class NoteBook(TixWidget): + """NoteBook - Multi-page container widget (tabbed notebook metaphor). + + Subwidgets Class + ---------- ----- + nbframe NoteBookFrame + page widgets added dynamically with the add method""" + + def __init__ (self,master=None,cnf={}, **kw): + TixWidget.__init__(self,master,'tixNoteBook', ['options'], cnf, kw) + self.subwidget_list['nbframe'] = TixSubWidget(self, 'nbframe', + destroy_physically=0) + + def add(self, name, cnf={}, **kw): + self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) + self.subwidget_list[name] = TixSubWidget(self, name) + return self.subwidget_list[name] + + def delete(self, name): + self.tk.call(self._w, 'delete', name) + self.subwidget_list[name].destroy() + del self.subwidget_list[name] + + def page(self, name): + return self.subwidget(name) + + def pages(self): + # Can't call subwidgets_all directly because we don't want .nbframe + names = self.tk.split(self.tk.call(self._w, 'pages')) + ret = [] + for x in names: + ret.append(self.subwidget(x)) + return ret + + def raise_page(self, name): # raise is a python keyword + self.tk.call(self._w, 'raise', name) + + def raised(self): + return self.tk.call(self._w, 'raised') + +class NoteBookFrame(TixWidget): + # FIXME: This is dangerous to expose to be called on its own. + pass + +class OptionMenu(TixWidget): + """OptionMenu - creates a menu button of options. + + Subwidget Class + --------- ----- + menubutton Menubutton + menu Menu""" + + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixOptionMenu', ['options'], cnf, kw) + self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton') + self.subwidget_list['menu'] = _dummyMenu(self, 'menu') + + def add_command(self, name, cnf={}, **kw): + self.tk.call(self._w, 'add', 'command', name, *self._options(cnf, kw)) + + def add_separator(self, name, cnf={}, **kw): + self.tk.call(self._w, 'add', 'separator', name, *self._options(cnf, kw)) + + def delete(self, name): + self.tk.call(self._w, 'delete', name) + + def disable(self, name): + self.tk.call(self._w, 'disable', name) + + def enable(self, name): + self.tk.call(self._w, 'enable', name) + +class PanedWindow(TixWidget): + """PanedWindow - Multi-pane container widget + allows the user to interactively manipulate the sizes of several + panes. The panes can be arranged either vertically or horizontally.The + user changes the sizes of the panes by dragging the resize handle + between two panes. + + Subwidgets Class + ---------- ----- + g/p widgets added dynamically with the add method.""" + + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixPanedWindow', ['orientation', 'options'], cnf, kw) + + # add delete forget panecget paneconfigure panes setsize + def add(self, name, cnf={}, **kw): + self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) + self.subwidget_list[name] = TixSubWidget(self, name, + check_intermediate=0) + return self.subwidget_list[name] + + def delete(self, name): + self.tk.call(self._w, 'delete', name) + self.subwidget_list[name].destroy() + del self.subwidget_list[name] + + def forget(self, name): + self.tk.call(self._w, 'forget', name) + + def panecget(self, entry, opt): + return self.tk.call(self._w, 'panecget', entry, opt) + + def paneconfigure(self, entry, cnf={}, **kw): + if cnf is None: + return _lst2dict( + self.tk.split( + self.tk.call(self._w, 'paneconfigure', entry))) + self.tk.call(self._w, 'paneconfigure', entry, *self._options(cnf, kw)) + + def panes(self): + names = self.tk.call(self._w, 'panes') + ret = [] + for x in names: + ret.append(self.subwidget(x)) + return ret + +class PopupMenu(TixWidget): + """PopupMenu widget can be used as a replacement of the tk_popup command. + The advantage of the Tix PopupMenu widget is it requires less application + code to manipulate. + + + Subwidgets Class + ---------- ----- + menubutton Menubutton + menu Menu""" + + # FIXME: It should inherit -superclass tixShell + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixPopupMenu', ['options'], cnf, kw) + self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton') + self.subwidget_list['menu'] = _dummyMenu(self, 'menu') + + def bind_widget(self, widget): + self.tk.call(self._w, 'bind', widget._w) + + def unbind_widget(self, widget): + self.tk.call(self._w, 'unbind', widget._w) + + def post_widget(self, widget, x, y): + self.tk.call(self._w, 'post', widget._w, x, y) + +class ResizeHandle(TixWidget): + """Internal widget to draw resize handles on Scrolled widgets.""" + def __init__(self, master, cnf={}, **kw): + # There seems to be a Tix bug rejecting the configure method + # Let's try making the flags -static + flags = ['options', 'command', 'cursorfg', 'cursorbg', + 'handlesize', 'hintcolor', 'hintwidth', + 'x', 'y'] + # In fact, x y height width are configurable + TixWidget.__init__(self, master, 'tixResizeHandle', + flags, cnf, kw) + + def attach_widget(self, widget): + self.tk.call(self._w, 'attachwidget', widget._w) + + def detach_widget(self, widget): + self.tk.call(self._w, 'detachwidget', widget._w) + + def hide(self, widget): + self.tk.call(self._w, 'hide', widget._w) + + def show(self, widget): + self.tk.call(self._w, 'show', widget._w) + +class ScrolledHList(TixWidget): + """ScrolledHList - HList with automatic scrollbars.""" + + # FIXME: It should inherit -superclass tixScrolledWidget + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixScrolledHList', ['options'], + cnf, kw) + self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + +class ScrolledListBox(TixWidget): + """ScrolledListBox - Listbox with automatic scrollbars.""" + + # FIXME: It should inherit -superclass tixScrolledWidget + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixScrolledListBox', ['options'], cnf, kw) + self.subwidget_list['listbox'] = _dummyListbox(self, 'listbox') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + +class ScrolledText(TixWidget): + """ScrolledText - Text with automatic scrollbars.""" + + # FIXME: It should inherit -superclass tixScrolledWidget + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixScrolledText', ['options'], cnf, kw) + self.subwidget_list['text'] = _dummyText(self, 'text') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + +class ScrolledTList(TixWidget): + """ScrolledTList - TList with automatic scrollbars.""" + + # FIXME: It should inherit -superclass tixScrolledWidget + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixScrolledTList', ['options'], + cnf, kw) + self.subwidget_list['tlist'] = _dummyTList(self, 'tlist') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + +class ScrolledWindow(TixWidget): + """ScrolledWindow - Window with automatic scrollbars.""" + + # FIXME: It should inherit -superclass tixScrolledWidget + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixScrolledWindow', ['options'], cnf, kw) + self.subwidget_list['window'] = _dummyFrame(self, 'window') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + +class Select(TixWidget): + """Select - Container of button subwidgets. It can be used to provide + radio-box or check-box style of selection options for the user. + + Subwidgets are buttons added dynamically using the add method.""" + + # FIXME: It should inherit -superclass tixLabelWidget + def __init__(self, master, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixSelect', + ['allowzero', 'radio', 'orientation', 'labelside', + 'options'], + cnf, kw) + self.subwidget_list['label'] = _dummyLabel(self, 'label') + + def add(self, name, cnf={}, **kw): + self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) + self.subwidget_list[name] = _dummyButton(self, name) + return self.subwidget_list[name] + + def invoke(self, name): + self.tk.call(self._w, 'invoke', name) + +class Shell(TixWidget): + """Toplevel window. + + Subwidgets - None""" + + def __init__ (self,master=None,cnf={}, **kw): + TixWidget.__init__(self, master, 'tixShell', ['options', 'title'], cnf, kw) + +class DialogShell(TixWidget): + """Toplevel window, with popup popdown and center methods. + It tells the window manager that it is a dialog window and should be + treated specially. The exact treatment depends on the treatment of + the window manager. + + Subwidgets - None""" + + # FIXME: It should inherit from Shell + def __init__ (self,master=None,cnf={}, **kw): + TixWidget.__init__(self, master, + 'tixDialogShell', + ['options', 'title', 'mapped', + 'minheight', 'minwidth', + 'parent', 'transient'], cnf, kw) + + def popdown(self): + self.tk.call(self._w, 'popdown') + + def popup(self): + self.tk.call(self._w, 'popup') + + def center(self): + self.tk.call(self._w, 'center') + +class StdButtonBox(TixWidget): + """StdButtonBox - Standard Button Box (OK, Apply, Cancel and Help) """ + + def __init__(self, master=None, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixStdButtonBox', + ['orientation', 'options'], cnf, kw) + self.subwidget_list['ok'] = _dummyButton(self, 'ok') + self.subwidget_list['apply'] = _dummyButton(self, 'apply') + self.subwidget_list['cancel'] = _dummyButton(self, 'cancel') + self.subwidget_list['help'] = _dummyButton(self, 'help') + + def invoke(self, name): + if name in self.subwidget_list: + self.tk.call(self._w, 'invoke', name) + +class TList(TixWidget): + """TList - Hierarchy display widget which can be + used to display data in a tabular format. The list entries of a TList + widget are similar to the entries in the Tk listbox widget. The main + differences are (1) the TList widget can display the list entries in a + two dimensional format and (2) you can use graphical images as well as + multiple colors and fonts for the list entries. + + Subwidgets - None""" + + def __init__ (self,master=None,cnf={}, **kw): + TixWidget.__init__(self, master, 'tixTList', ['options'], cnf, kw) + + def active_set(self, index): + self.tk.call(self._w, 'active', 'set', index) + + def active_clear(self): + self.tk.call(self._w, 'active', 'clear') + + def anchor_set(self, index): + self.tk.call(self._w, 'anchor', 'set', index) + + def anchor_clear(self): + self.tk.call(self._w, 'anchor', 'clear') + + def delete(self, from_, to=None): + self.tk.call(self._w, 'delete', from_, to) + + def dragsite_set(self, index): + self.tk.call(self._w, 'dragsite', 'set', index) + + def dragsite_clear(self): + self.tk.call(self._w, 'dragsite', 'clear') + + def dropsite_set(self, index): + self.tk.call(self._w, 'dropsite', 'set', index) + + def dropsite_clear(self): + self.tk.call(self._w, 'dropsite', 'clear') + + def insert(self, index, cnf={}, **kw): + self.tk.call(self._w, 'insert', index, *self._options(cnf, kw)) + + def info_active(self): + return self.tk.call(self._w, 'info', 'active') + + def info_anchor(self): + return self.tk.call(self._w, 'info', 'anchor') + + def info_down(self, index): + return self.tk.call(self._w, 'info', 'down', index) + + def info_left(self, index): + return self.tk.call(self._w, 'info', 'left', index) + + def info_right(self, index): + return self.tk.call(self._w, 'info', 'right', index) + + def info_selection(self): + c = self.tk.call(self._w, 'info', 'selection') + return self.tk.splitlist(c) + + def info_size(self): + return self.tk.call(self._w, 'info', 'size') + + def info_up(self, index): + return self.tk.call(self._w, 'info', 'up', index) + + def nearest(self, x, y): + return self.tk.call(self._w, 'nearest', x, y) + + def see(self, index): + self.tk.call(self._w, 'see', index) + + def selection_clear(self, cnf={}, **kw): + self.tk.call(self._w, 'selection', 'clear', *self._options(cnf, kw)) + + def selection_includes(self, index): + return self.tk.call(self._w, 'selection', 'includes', index) + + def selection_set(self, first, last=None): + self.tk.call(self._w, 'selection', 'set', first, last) + + def xview(self, *args): + self.tk.call(self._w, 'xview', *args) + + def yview(self, *args): + self.tk.call(self._w, 'yview', *args) + +class Tree(TixWidget): + """Tree - The tixTree widget can be used to display hierachical + data in a tree form. The user can adjust + the view of the tree by opening or closing parts of the tree.""" + + # FIXME: It should inherit -superclass tixScrolledWidget + def __init__(self, master=None, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixTree', + ['options'], cnf, kw) + self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + + def autosetmode(self): + '''This command calls the setmode method for all the entries in this + Tree widget: if an entry has no child entries, its mode is set to + none. Otherwise, if the entry has any hidden child entries, its mode is + set to open; otherwise its mode is set to close.''' + self.tk.call(self._w, 'autosetmode') + + def close(self, entrypath): + '''Close the entry given by entryPath if its mode is close.''' + self.tk.call(self._w, 'close', entrypath) + + def getmode(self, entrypath): + '''Returns the current mode of the entry given by entryPath.''' + return self.tk.call(self._w, 'getmode', entrypath) + + def open(self, entrypath): + '''Open the entry given by entryPath if its mode is open.''' + self.tk.call(self._w, 'open', entrypath) + + def setmode(self, entrypath, mode='none'): + '''This command is used to indicate whether the entry given by + entryPath has children entries and whether the children are visible. mode + must be one of open, close or none. If mode is set to open, a (+) + indicator is drawn next the the entry. If mode is set to close, a (-) + indicator is drawn next the the entry. If mode is set to none, no + indicators will be drawn for this entry. The default mode is none. The + open mode indicates the entry has hidden children and this entry can be + opened by the user. The close mode indicates that all the children of the + entry are now visible and the entry can be closed by the user.''' + self.tk.call(self._w, 'setmode', entrypath, mode) + + +# Could try subclassing Tree for CheckList - would need another arg to init +class CheckList(TixWidget): + """The CheckList widget + displays a list of items to be selected by the user. CheckList acts + similarly to the Tk checkbutton or radiobutton widgets, except it is + capable of handling many more items than checkbuttons or radiobuttons. + """ + # FIXME: It should inherit -superclass tixTree + def __init__(self, master=None, cnf={}, **kw): + TixWidget.__init__(self, master, 'tixCheckList', + ['options'], cnf, kw) + self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + + def autosetmode(self): + '''This command calls the setmode method for all the entries in this + Tree widget: if an entry has no child entries, its mode is set to + none. Otherwise, if the entry has any hidden child entries, its mode is + set to open; otherwise its mode is set to close.''' + self.tk.call(self._w, 'autosetmode') + + def close(self, entrypath): + '''Close the entry given by entryPath if its mode is close.''' + self.tk.call(self._w, 'close', entrypath) + + def getmode(self, entrypath): + '''Returns the current mode of the entry given by entryPath.''' + return self.tk.call(self._w, 'getmode', entrypath) + + def open(self, entrypath): + '''Open the entry given by entryPath if its mode is open.''' + self.tk.call(self._w, 'open', entrypath) + + def getselection(self, mode='on'): + '''Returns a list of items whose status matches status. If status is + not specified, the list of items in the "on" status will be returned. + Mode can be on, off, default''' + c = self.tk.split(self.tk.call(self._w, 'getselection', mode)) + return self.tk.splitlist(c) + + def getstatus(self, entrypath): + '''Returns the current status of entryPath.''' + return self.tk.call(self._w, 'getstatus', entrypath) + + def setstatus(self, entrypath, mode='on'): + '''Sets the status of entryPath to be status. A bitmap will be + displayed next to the entry its status is on, off or default.''' + self.tk.call(self._w, 'setstatus', entrypath, mode) + + +########################################################################### +### The subclassing below is used to instantiate the subwidgets in each ### +### mega widget. This allows us to access their methods directly. ### +########################################################################### + +class _dummyButton(Button, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyCheckbutton(Checkbutton, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyEntry(Entry, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyFrame(Frame, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyLabel(Label, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyListbox(Listbox, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyMenu(Menu, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyMenubutton(Menubutton, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyScrollbar(Scrollbar, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyText(Text, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyScrolledListBox(ScrolledListBox, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + self.subwidget_list['listbox'] = _dummyListbox(self, 'listbox') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + +class _dummyHList(HList, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyScrolledHList(ScrolledHList, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + +class _dummyTList(TList, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyComboBox(ComboBox, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, ['fancy',destroy_physically]) + self.subwidget_list['label'] = _dummyLabel(self, 'label') + self.subwidget_list['entry'] = _dummyEntry(self, 'entry') + self.subwidget_list['arrow'] = _dummyButton(self, 'arrow') + + self.subwidget_list['slistbox'] = _dummyScrolledListBox(self, + 'slistbox') + try: + self.subwidget_list['tick'] = _dummyButton(self, 'tick') + #cross Button : present if created with the fancy option + self.subwidget_list['cross'] = _dummyButton(self, 'cross') + except TypeError: + # unavailable when -fancy not specified + pass + +class _dummyDirList(DirList, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') + self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') + self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') + +class _dummyDirSelectBox(DirSelectBox, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist') + self.subwidget_list['dircbx'] = _dummyFileComboBox(self, 'dircbx') + +class _dummyExFileSelectBox(ExFileSelectBox, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + self.subwidget_list['cancel'] = _dummyButton(self, 'cancel') + self.subwidget_list['ok'] = _dummyButton(self, 'ok') + self.subwidget_list['hidden'] = _dummyCheckbutton(self, 'hidden') + self.subwidget_list['types'] = _dummyComboBox(self, 'types') + self.subwidget_list['dir'] = _dummyComboBox(self, 'dir') + self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist') + self.subwidget_list['file'] = _dummyComboBox(self, 'file') + self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist') + +class _dummyFileSelectBox(FileSelectBox, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist') + self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist') + self.subwidget_list['filter'] = _dummyComboBox(self, 'filter') + self.subwidget_list['selection'] = _dummyComboBox(self, 'selection') + +class _dummyFileComboBox(ComboBox, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + self.subwidget_list['dircbx'] = _dummyComboBox(self, 'dircbx') + +class _dummyStdButtonBox(StdButtonBox, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + self.subwidget_list['ok'] = _dummyButton(self, 'ok') + self.subwidget_list['apply'] = _dummyButton(self, 'apply') + self.subwidget_list['cancel'] = _dummyButton(self, 'cancel') + self.subwidget_list['help'] = _dummyButton(self, 'help') + +class _dummyNoteBookFrame(NoteBookFrame, TixSubWidget): + def __init__(self, master, name, destroy_physically=0): + TixSubWidget.__init__(self, master, name, destroy_physically) + +class _dummyPanedWindow(PanedWindow, TixSubWidget): + def __init__(self, master, name, destroy_physically=1): + TixSubWidget.__init__(self, master, name, destroy_physically) + +######################## +### Utility Routines ### +######################## + +#mike Should tixDestroy be exposed as a wrapper? - but not for widgets. + +def OptionName(widget): + '''Returns the qualified path name for the widget. Normally used to set + default options for subwidgets. See tixwidgets.py''' + return widget.tk.call('tixOptionName', widget._w) + +# Called with a dictionary argument of the form +# {'*.c':'C source files', '*.txt':'Text Files', '*':'All files'} +# returns a string which can be used to configure the fsbox file types +# in an ExFileSelectBox. i.e., +# '{{*} {* - All files}} {{*.c} {*.c - C source files}} {{*.txt} {*.txt - Text Files}}' +def FileTypeList(dict): + s = '' + for type in dict.keys(): + s = s + '{{' + type + '} {' + type + ' - ' + dict[type] + '}} ' + return s + +# Still to be done: +# tixIconView +class CObjView(TixWidget): + """This file implements the Canvas Object View widget. This is a base + class of IconView. It implements automatic placement/adjustment of the + scrollbars according to the canvas objects inside the canvas subwidget. + The scrollbars are adjusted so that the canvas is just large enough + to see all the objects. + """ + # FIXME: It should inherit -superclass tixScrolledWidget + pass + + +class Grid(TixWidget): + '''The Tix Grid command creates a new window and makes it into a + tixGrid widget. Additional options, may be specified on the command + line or in the option database to configure aspects such as its cursor + and relief. + + A Grid widget displays its contents in a two dimensional grid of cells. + Each cell may contain one Tix display item, which may be in text, + graphics or other formats. See the DisplayStyle class for more information + about Tix display items. Individual cells, or groups of cells, can be + formatted with a wide range of attributes, such as its color, relief and + border. + + Subwidgets - None''' + # valid specific resources as of Tk 8.4 + # editdonecmd, editnotifycmd, floatingcols, floatingrows, formatcmd, + # highlightbackground, highlightcolor, leftmargin, itemtype, selectmode, + # selectunit, topmargin, + def __init__(self, master=None, cnf={}, **kw): + static= [] + self.cnf= cnf + TixWidget.__init__(self, master, 'tixGrid', static, cnf, kw) + + # valid options as of Tk 8.4 + # anchor, bdtype, cget, configure, delete, dragsite, dropsite, entrycget, edit + # entryconfigure, format, geometryinfo, info, index, move, nearest, selection + # set, size, unset, xview, yview + # def anchor option ?args ...? + def anchor_get(self): + "Get the (x,y) coordinate of the current anchor cell" + return self._getints(self.tk.call(self, 'anchor', 'get')) + + # def bdtype + # def delete dim from ?to? + def delete_row(self, from_, to=None): + """Delete rows between from_ and to inclusive. + If to is not provided, delete only row at from_""" + if to is None: + self.tk.call(self, 'delete', 'row', from_) + else: + self.tk.call(self, 'delete', 'row', from_, to) + def delete_column(self, from_, to=None): + """Delete columns between from_ and to inclusive. + If to is not provided, delete only column at from_""" + if to is None: + self.tk.call(self, 'delete', 'column', from_) + else: + self.tk.call(self, 'delete', 'column', from_, to) + # def edit apply + # def edit set x y + + def entrycget(self, x, y, option): + "Get the option value for cell at (x,y)" + return self.tk.call(self, 'entrycget', x, y, option) + + def entryconfigure(self, x, y, **kw): + return self.tk.call(self, 'entryconfigure', x, y, *self._options(None, kw)) + # def format + # def index + + def info_exists(self, x, y): + "Return True if display item exists at (x,y)" + return bool(int(self.tk.call(self, 'info', 'exists', x, y))) + + def info_bbox(self, x, y): + # This seems to always return '', at least for 'text' displayitems + return self.tk.call(self, 'info', 'bbox', x, y) + + def nearest(self, x, y): + "Return coordinate of cell nearest pixel coordinate (x,y)" + return self._getints(self.tk.call(self, 'nearest', x, y)) + + # def selection adjust + # def selection clear + # def selection includes + # def selection set + # def selection toggle + # def move dim from to offset + + def set(self, x, y, itemtype=None, **kw): + args= self._options(self.cnf, kw) + if itemtype is not None: + args= ('-itemtype', itemtype) + args + self.tk.call(self, 'set', x, y, *args) + + # def size dim index ?option value ...? + # def unset x y + + def xview(self): + return self._getdoubles(self.tk.call(self, 'xview')) + def xview_moveto(self, fraction): + self.tk.call(self,'xview', 'moveto', fraction) + def xview_scroll(self, count, what="units"): + "Scroll right (count>0) or left of units|pages" + self.tk.call(self, 'xview', 'scroll', count, what) + + def yview(self): + return self._getdoubles(self.tk.call(self, 'yview')) + def yview_moveto(self, fraction): + self.tk.call(self,'ysview', 'moveto', fraction) + def yview_scroll(self, count, what="units"): + "Scroll down (count>0) or up of units|pages" + self.tk.call(self, 'yview', 'scroll', count, what) + +class ScrolledGrid(Grid): + '''Scrolled Grid widgets''' + + # FIXME: It should inherit -superclass tixScrolledWidget + def __init__(self, master=None, cnf={}, **kw): + static= [] + self.cnf= cnf + TixWidget.__init__(self, master, 'tixScrolledGrid', static, cnf, kw) Index: Lib/tkinter/dnd.py =================================================================== --- Lib/tkinter/dnd.py (revision 0) +++ Lib/tkinter/dnd.py (revision 0) @@ -0,0 +1,321 @@ +"""Drag-and-drop support for Tkinter. + +This is very preliminary. I currently only support dnd *within* one +application, between different windows (or within the same window). + +I an trying to make this as generic as possible -- not dependent on +the use of a particular widget or icon type, etc. I also hope that +this will work with Pmw. + +To enable an object to be dragged, you must create an event binding +for it that starts the drag-and-drop process. Typically, you should +bind to a callback function that you write. The function +should call Tkdnd.dnd_start(source, event), where 'source' is the +object to be dragged, and 'event' is the event that invoked the call +(the argument to your callback function). Even though this is a class +instantiation, the returned instance should not be stored -- it will +be kept alive automatically for the duration of the drag-and-drop. + +When a drag-and-drop is already in process for the Tk interpreter, the +call is *ignored*; this normally averts starting multiple simultaneous +dnd processes, e.g. because different button callbacks all +dnd_start(). + +The object is *not* necessarily a widget -- it can be any +application-specific object that is meaningful to potential +drag-and-drop targets. + +Potential drag-and-drop targets are discovered as follows. Whenever +the mouse moves, and at the start and end of a drag-and-drop move, the +Tk widget directly under the mouse is inspected. This is the target +widget (not to be confused with the target object, yet to be +determined). If there is no target widget, there is no dnd target +object. If there is a target widget, and it has an attribute +dnd_accept, this should be a function (or any callable object). The +function is called as dnd_accept(source, event), where 'source' is the +object being dragged (the object passed to dnd_start() above), and +'event' is the most recent event object (generally a event; +it can also be or ). If the dnd_accept() +function returns something other than None, this is the new dnd target +object. If dnd_accept() returns None, or if the target widget has no +dnd_accept attribute, the target widget's parent is considered as the +target widget, and the search for a target object is repeated from +there. If necessary, the search is repeated all the way up to the +root widget. If none of the target widgets can produce a target +object, there is no target object (the target object is None). + +The target object thus produced, if any, is called the new target +object. It is compared with the old target object (or None, if there +was no old target widget). There are several cases ('source' is the +source object, and 'event' is the most recent event object): + +- Both the old and new target objects are None. Nothing happens. + +- The old and new target objects are the same object. Its method +dnd_motion(source, event) is called. + +- The old target object was None, and the new target object is not +None. The new target object's method dnd_enter(source, event) is +called. + +- The new target object is None, and the old target object is not +None. The old target object's method dnd_leave(source, event) is +called. + +- The old and new target objects differ and neither is None. The old +target object's method dnd_leave(source, event), and then the new +target object's method dnd_enter(source, event) is called. + +Once this is done, the new target object replaces the old one, and the +Tk mainloop proceeds. The return value of the methods mentioned above +is ignored; if they raise an exception, the normal exception handling +mechanisms take over. + +The drag-and-drop processes can end in two ways: a final target object +is selected, or no final target object is selected. When a final +target object is selected, it will always have been notified of the +potential drop by a call to its dnd_enter() method, as described +above, and possibly one or more calls to its dnd_motion() method; its +dnd_leave() method has not been called since the last call to +dnd_enter(). The target is notified of the drop by a call to its +method dnd_commit(source, event). + +If no final target object is selected, and there was an old target +object, its dnd_leave(source, event) method is called to complete the +dnd sequence. + +Finally, the source object is notified that the drag-and-drop process +is over, by a call to source.dnd_end(target, event), specifying either +the selected target object, or None if no target object was selected. +The source object can use this to implement the commit action; this is +sometimes simpler than to do it in the target's dnd_commit(). The +target's dnd_commit() method could then simply be aliased to +dnd_leave(). + +At any time during a dnd sequence, the application can cancel the +sequence by calling the cancel() method on the object returned by +dnd_start(). This will call dnd_leave() if a target is currently +active; it will never call dnd_commit(). + +""" + + +import tkinter + + +# The factory function + +def dnd_start(source, event): + h = DndHandler(source, event) + if h.root: + return h + else: + return None + + +# The class that does the work + +class DndHandler: + + root = None + + def __init__(self, source, event): + if event.num > 5: + return + root = event.widget._root() + try: + root.__dnd + return # Don't start recursive dnd + except AttributeError: + root.__dnd = self + self.root = root + self.source = source + self.target = None + self.initial_button = button = event.num + self.initial_widget = widget = event.widget + self.release_pattern = "" % (button, button) + self.save_cursor = widget['cursor'] or "" + widget.bind(self.release_pattern, self.on_release) + widget.bind("", self.on_motion) + widget['cursor'] = "hand2" + + def __del__(self): + root = self.root + self.root = None + if root: + try: + del root.__dnd + except AttributeError: + pass + + def on_motion(self, event): + x, y = event.x_root, event.y_root + target_widget = self.initial_widget.winfo_containing(x, y) + source = self.source + new_target = None + while target_widget: + try: + attr = target_widget.dnd_accept + except AttributeError: + pass + else: + new_target = attr(source, event) + if new_target: + break + target_widget = target_widget.master + old_target = self.target + if old_target is new_target: + if old_target: + old_target.dnd_motion(source, event) + else: + if old_target: + self.target = None + old_target.dnd_leave(source, event) + if new_target: + new_target.dnd_enter(source, event) + self.target = new_target + + def on_release(self, event): + self.finish(event, 1) + + def cancel(self, event=None): + self.finish(event, 0) + + def finish(self, event, commit=0): + target = self.target + source = self.source + widget = self.initial_widget + root = self.root + try: + del root.__dnd + self.initial_widget.unbind(self.release_pattern) + self.initial_widget.unbind("") + widget['cursor'] = self.save_cursor + self.target = self.source = self.initial_widget = self.root = None + if target: + if commit: + target.dnd_commit(source, event) + else: + target.dnd_leave(source, event) + finally: + source.dnd_end(target, event) + + + +# ---------------------------------------------------------------------- +# The rest is here for testing and demonstration purposes only! + +class Icon: + + def __init__(self, name): + self.name = name + self.canvas = self.label = self.id = None + + def attach(self, canvas, x=10, y=10): + if canvas is self.canvas: + self.canvas.coords(self.id, x, y) + return + if self.canvas: + self.detach() + if not canvas: + return + label = tkinter.Label(canvas, text=self.name, + borderwidth=2, relief="raised") + id = canvas.create_window(x, y, window=label, anchor="nw") + self.canvas = canvas + self.label = label + self.id = id + label.bind("", self.press) + + def detach(self): + canvas = self.canvas + if not canvas: + return + id = self.id + label = self.label + self.canvas = self.label = self.id = None + canvas.delete(id) + label.destroy() + + def press(self, event): + if dnd_start(self, event): + # where the pointer is relative to the label widget: + self.x_off = event.x + self.y_off = event.y + # where the widget is relative to the canvas: + self.x_orig, self.y_orig = self.canvas.coords(self.id) + + def move(self, event): + x, y = self.where(self.canvas, event) + self.canvas.coords(self.id, x, y) + + def putback(self): + self.canvas.coords(self.id, self.x_orig, self.y_orig) + + def where(self, canvas, event): + # where the corner of the canvas is relative to the screen: + x_org = canvas.winfo_rootx() + y_org = canvas.winfo_rooty() + # where the pointer is relative to the canvas widget: + x = event.x_root - x_org + y = event.y_root - y_org + # compensate for initial pointer offset + return x - self.x_off, y - self.y_off + + def dnd_end(self, target, event): + pass + +class Tester: + + def __init__(self, root): + self.top = tkinter.Toplevel(root) + self.canvas = tkinter.Canvas(self.top, width=100, height=100) + self.canvas.pack(fill="both", expand=1) + self.canvas.dnd_accept = self.dnd_accept + + def dnd_accept(self, source, event): + return self + + def dnd_enter(self, source, event): + self.canvas.focus_set() # Show highlight border + x, y = source.where(self.canvas, event) + x1, y1, x2, y2 = source.canvas.bbox(source.id) + dx, dy = x2-x1, y2-y1 + self.dndid = self.canvas.create_rectangle(x, y, x+dx, y+dy) + self.dnd_motion(source, event) + + def dnd_motion(self, source, event): + x, y = source.where(self.canvas, event) + x1, y1, x2, y2 = self.canvas.bbox(self.dndid) + self.canvas.move(self.dndid, x-x1, y-y1) + + def dnd_leave(self, source, event): + self.top.focus_set() # Hide highlight border + self.canvas.delete(self.dndid) + self.dndid = None + + def dnd_commit(self, source, event): + self.dnd_leave(source, event) + x, y = source.where(self.canvas, event) + source.attach(self.canvas, x, y) + +def test(): + root = tkinter.Tk() + root.geometry("+1+1") + tkinter.Button(command=root.quit, text="Quit").pack() + t1 = Tester(root) + t1.top.geometry("+1+60") + t2 = Tester(root) + t2.top.geometry("+120+60") + t3 = Tester(root) + t3.top.geometry("+240+60") + i1 = Icon("ICON1") + i2 = Icon("ICON2") + i3 = Icon("ICON3") + i1.attach(t1.canvas) + i2.attach(t2.canvas) + i3.attach(t3.canvas) + root.mainloop() + +if __name__ == '__main__': + test() Index: Lib/tkinter/_fix.py =================================================================== --- Lib/tkinter/_fix.py (revision 0) +++ Lib/tkinter/_fix.py (revision 0) @@ -0,0 +1,41 @@ +import sys, os + +# Delay import _tkinter until we have set TCL_LIBRARY, +# so that Tcl_FindExecutable has a chance to locate its +# encoding directory. + +# Unfortunately, we cannot know the TCL_LIBRARY directory +# if we don't know the tcl version, which we cannot find out +# without import Tcl. Fortunately, Tcl will itself look in +# \..\tcl, so anything close to +# the real Tcl library will do. + +prefix = os.path.join(sys.prefix,"tcl") +if not os.path.exists(prefix): + # devdir/../tcltk/lib + prefix = os.path.join(sys.prefix, os.path.pardir, "tcltk", "lib") + prefix = os.path.abspath(prefix) +# if this does not exist, no further search is needed +if os.path.exists(prefix): + if "TCL_LIBRARY" not in os.environ: + for name in os.listdir(prefix): + if name.startswith("tcl"): + tcldir = os.path.join(prefix,name) + if os.path.isdir(tcldir): + os.environ["TCL_LIBRARY"] = tcldir + # Compute TK_LIBRARY, knowing that it has the same version + # as Tcl + import _tkinter + ver = str(_tkinter.TCL_VERSION) + if "TK_LIBRARY" not in os.environ: + v = os.path.join(prefix, 'tk'+ver) + if os.path.exists(os.path.join(v, "tclIndex")): + os.environ['TK_LIBRARY'] = v + # We don't know the Tix version, so we must search the entire + # directory + if "TIX_LIBRARY" not in os.environ: + for name in os.listdir(prefix): + if name.startswith("tix"): + tixdir = os.path.join(prefix,name) + if os.path.isdir(tixdir): + os.environ["TIX_LIBRARY"] = tixdir Index: Lib/tkinter/font.py =================================================================== --- Lib/tkinter/font.py (revision 0) +++ Lib/tkinter/font.py (revision 0) @@ -0,0 +1,216 @@ +# tkinter font wrapper +# +# written by Fredrik Lundh, February 1998 +# +# FIXME: should add 'displayof' option where relevant (actual, families, +# measure, and metrics) +# + +__version__ = "0.9" + +import tkinter + +# weight/slant +NORMAL = "normal" +ROMAN = "roman" +BOLD = "bold" +ITALIC = "italic" + +def nametofont(name): + """Given the name of a tk named font, returns a Font representation. + """ + return Font(name=name, exists=True) + +class Font: + + """Represents a named font. + + Constructor options are: + + font -- font specifier (name, system font, or (family, size, style)-tuple) + name -- name to use for this font configuration (defaults to a unique name) + exists -- does a named font by this name already exist? + Creates a new named font if False, points to the existing font if True. + Raises _tkinter.TclError if the assertion is false. + + the following are ignored if font is specified: + + family -- font 'family', e.g. Courier, Times, Helvetica + size -- font size in points + weight -- font thickness: NORMAL, BOLD + slant -- font slant: ROMAN, ITALIC + underline -- font underlining: false (0), true (1) + overstrike -- font strikeout: false (0), true (1) + + """ + + def _set(self, kw): + options = [] + for k, v in kw.items(): + options.append("-"+k) + options.append(str(v)) + return tuple(options) + + def _get(self, args): + options = [] + for k in args: + options.append("-"+k) + return tuple(options) + + def _mkdict(self, args): + options = {} + for i in range(0, len(args), 2): + options[args[i][1:]] = args[i+1] + return options + + def __init__(self, root=None, font=None, name=None, exists=False, **options): + if not root: + root = tkinter._default_root + if font: + # get actual settings corresponding to the given font + font = root.tk.splitlist(root.tk.call("font", "actual", font)) + else: + font = self._set(options) + if not name: + name = "font" + str(id(self)) + self.name = name + + if exists: + self.delete_font = False + # confirm font exists + if self.name not in root.tk.call("font", "names"): + raise tkinter._tkinter.TclError("named font %s does not already exist" % (self.name,)) + # if font config info supplied, apply it + if font: + root.tk.call("font", "configure", self.name, *font) + else: + # create new font (raises TclError if the font exists) + root.tk.call("font", "create", self.name, *font) + self.delete_font = True + # backlinks! + self._root = root + self._split = root.tk.splitlist + self._call = root.tk.call + + def __str__(self): + return self.name + + def __eq__(self, other): + return self.name == other.name and isinstance(other, Font) + + def __getitem__(self, key): + return self.cget(key) + + def __setitem__(self, key, value): + self.configure(**{key: value}) + + def __del__(self): + try: + if self.delete_font: + self._call("font", "delete", self.name) + except (KeyboardInterrupt, SystemExit): + raise + except Exception: + pass + + def copy(self): + "Return a distinct copy of the current font" + return Font(self._root, **self.actual()) + + def actual(self, option=None): + "Return actual font attributes" + if option: + return self._call("font", "actual", self.name, "-"+option) + else: + return self._mkdict( + self._split(self._call("font", "actual", self.name)) + ) + + def cget(self, option): + "Get font attribute" + return self._call("font", "config", self.name, "-"+option) + + def config(self, **options): + "Modify font attributes" + if options: + self._call("font", "config", self.name, + *self._set(options)) + else: + return self._mkdict( + self._split(self._call("font", "config", self.name)) + ) + + configure = config + + def measure(self, text): + "Return text width" + return int(self._call("font", "measure", self.name, text)) + + def metrics(self, *options): + """Return font metrics. + + For best performance, create a dummy widget + using this font before calling this method.""" + + if options: + return int( + self._call("font", "metrics", self.name, self._get(options)) + ) + else: + res = self._split(self._call("font", "metrics", self.name)) + options = {} + for i in range(0, len(res), 2): + options[res[i][1:]] = int(res[i+1]) + return options + +def families(root=None): + "Get font families (as a tuple)" + if not root: + root = tkinter._default_root + return root.tk.splitlist(root.tk.call("font", "families")) + +def names(root=None): + "Get names of defined fonts (as a tuple)" + if not root: + root = tkinter._default_root + return root.tk.splitlist(root.tk.call("font", "names")) + +# -------------------------------------------------------------------- +# test stuff + +if __name__ == "__main__": + + root = tkinter.Tk() + + # create a font + f = Font(family="times", size=30, weight=NORMAL) + + print(f.actual()) + print(f.actual("family")) + print(f.actual("weight")) + + print(f.config()) + print(f.cget("family")) + print(f.cget("weight")) + + print(names()) + + print(f.measure("hello"), f.metrics("linespace")) + + print(f.metrics()) + + f = Font(font=("Courier", 20, "bold")) + print(f.measure("hello"), f.metrics("linespace")) + + w = tkinter.Label(root, text="Hello, world", font=f) + w.pack() + + w = tkinter.Button(root, text="Quit!", command=root.destroy) + w.pack() + + fb = Font(font=w["font"]).copy() + fb.config(weight=BOLD) + + w.config(font=fb) + + tkinter.mainloop() Index: Lib/pydoc.py =================================================================== --- Lib/pydoc.py (revision 63077) +++ Lib/pydoc.py (working copy) @@ -2018,20 +2018,20 @@ self.server = None self.scanner = None - import Tkinter - self.server_frm = Tkinter.Frame(window) - self.title_lbl = Tkinter.Label(self.server_frm, + import tkinter + self.server_frm = tkinter.Frame(window) + self.title_lbl = tkinter.Label(self.server_frm, text='Starting server...\n ') - self.open_btn = Tkinter.Button(self.server_frm, + self.open_btn = tkinter.Button(self.server_frm, text='open browser', command=self.open, state='disabled') - self.quit_btn = Tkinter.Button(self.server_frm, + self.quit_btn = tkinter.Button(self.server_frm, text='quit serving', command=self.quit, state='disabled') - self.search_frm = Tkinter.Frame(window) - self.search_lbl = Tkinter.Label(self.search_frm, text='Search for') - self.search_ent = Tkinter.Entry(self.search_frm) + self.search_frm = tkinter.Frame(window) + self.search_lbl = tkinter.Label(self.search_frm, text='Search for') + self.search_ent = tkinter.Entry(self.search_frm) self.search_ent.bind('', self.search) - self.stop_btn = Tkinter.Button(self.search_frm, + self.stop_btn = tkinter.Button(self.search_frm, text='stop', pady=0, command=self.stop, state='disabled') if sys.platform == 'win32': # Trying to hide and show this button crashes under Windows. @@ -2050,17 +2050,17 @@ self.search_ent.focus_set() font = ('helvetica', sys.platform == 'win32' and 8 or 10) - self.result_lst = Tkinter.Listbox(window, font=font, height=6) + self.result_lst = tkinter.Listbox(window, font=font, height=6) self.result_lst.bind('', self.select) self.result_lst.bind('', self.goto) - self.result_scr = Tkinter.Scrollbar(window, + self.result_scr = tkinter.Scrollbar(window, orient='vertical', command=self.result_lst.yview) self.result_lst.config(yscrollcommand=self.result_scr.set) - self.result_frm = Tkinter.Frame(window) - self.goto_btn = Tkinter.Button(self.result_frm, + self.result_frm = tkinter.Frame(window) + self.goto_btn = tkinter.Button(self.result_frm, text='go to selected', command=self.goto) - self.hide_btn = Tkinter.Button(self.result_frm, + self.hide_btn = tkinter.Button(self.result_frm, text='hide results', command=self.hide) self.goto_btn.pack(side='left', fill='x', expand=1) self.hide_btn.pack(side='right', fill='x', expand=1) @@ -2180,9 +2180,9 @@ self.stop() self.collapse() - import Tkinter + import tkinter try: - root = Tkinter.Tk() + root = tkinter.Tk() # Tk will crash if pythonw.exe has an XP .manifest # file and the root has is not destroyed explicitly. # If the problem is ever fixed in Tk, the explicit Index: Lib/lib-tk/tkMessageBox.py =================================================================== --- Lib/lib-tk/tkMessageBox.py (revision 63074) +++ Lib/lib-tk/tkMessageBox.py (working copy) @@ -1,132 +0,0 @@ -# tk common message boxes -# -# this module provides an interface to the native message boxes -# available in Tk 4.2 and newer. -# -# written by Fredrik Lundh, May 1997 -# - -# -# options (all have default values): -# -# - default: which button to make default (one of the reply codes) -# -# - icon: which icon to display (see below) -# -# - message: the message to display -# -# - parent: which window to place the dialog on top of -# -# - title: dialog title -# -# - type: dialog type; that is, which buttons to display (see below) -# - -from tkCommonDialog import Dialog - -# -# constants - -# icons -ERROR = "error" -INFO = "info" -QUESTION = "question" -WARNING = "warning" - -# types -ABORTRETRYIGNORE = "abortretryignore" -OK = "ok" -OKCANCEL = "okcancel" -RETRYCANCEL = "retrycancel" -YESNO = "yesno" -YESNOCANCEL = "yesnocancel" - -# replies -ABORT = "abort" -RETRY = "retry" -IGNORE = "ignore" -OK = "ok" -CANCEL = "cancel" -YES = "yes" -NO = "no" - - -# -# message dialog class - -class Message(Dialog): - "A message box" - - command = "tk_messageBox" - - -# -# convenience stuff - -# Rename _icon and _type options to allow overriding them in options -def _show(title=None, message=None, _icon=None, _type=None, **options): - if _icon and "icon" not in options: options["icon"] = _icon - if _type and "type" not in options: options["type"] = _type - if title: options["title"] = title - if message: options["message"] = message - res = Message(**options).show() - # In some Tcl installations, Tcl converts yes/no into a boolean - if isinstance(res, bool): - if res: return YES - return NO - return res - -def showinfo(title=None, message=None, **options): - "Show an info message" - return _show(title, message, INFO, OK, **options) - -def showwarning(title=None, message=None, **options): - "Show a warning message" - return _show(title, message, WARNING, OK, **options) - -def showerror(title=None, message=None, **options): - "Show an error message" - return _show(title, message, ERROR, OK, **options) - -def askquestion(title=None, message=None, **options): - "Ask a question" - return _show(title, message, QUESTION, YESNO, **options) - -def askokcancel(title=None, message=None, **options): - "Ask if operation should proceed; return true if the answer is ok" - s = _show(title, message, QUESTION, OKCANCEL, **options) - return s == OK - -def askyesno(title=None, message=None, **options): - "Ask a question; return true if the answer is yes" - s = _show(title, message, QUESTION, YESNO, **options) - return s == YES - -def askyesnocancel(title=None, message=None, **options): - "Ask a question; return true if the answer is yes, None if cancelled." - s = _show(title, message, QUESTION, YESNOCANCEL, **options) - # s might be a Tcl index object, so convert it to a string - s = str(s) - if s == CANCEL: - return None - return s == YES - -def askretrycancel(title=None, message=None, **options): - "Ask if operation should be retried; return true if the answer is yes" - s = _show(title, message, WARNING, RETRYCANCEL, **options) - return s == RETRY - - -# -------------------------------------------------------------------- -# test stuff - -if __name__ == "__main__": - - print("info", showinfo("Spam", "Egg Information")) - print("warning", showwarning("Spam", "Egg Warning")) - print("error", showerror("Spam", "Egg Alert")) - print("question", askquestion("Spam", "Question?")) - print("proceed", askokcancel("Spam", "Proceed?")) - print("yes/no", askyesno("Spam", "Got it?")) - print("yes/no/cancel", askyesnocancel("Spam", "Want it?")) - print("try again", askretrycancel("Spam", "Try again?")) Index: Lib/lib-tk/tkFileDialog.py =================================================================== --- Lib/lib-tk/tkFileDialog.py (revision 63074) +++ Lib/lib-tk/tkFileDialog.py (working copy) @@ -1,215 +0,0 @@ -# -# Instant Python -# $Id$ -# -# tk common file dialogues -# -# this module provides interfaces to the native file dialogues -# available in Tk 4.2 and newer, and the directory dialogue available -# in Tk 8.3 and newer. -# -# written by Fredrik Lundh, May 1997. -# - -# -# options (all have default values): -# -# - defaultextension: added to filename if not explicitly given -# -# - filetypes: sequence of (label, pattern) tuples. the same pattern -# may occur with several patterns. use "*" as pattern to indicate -# all files. -# -# - initialdir: initial directory. preserved by dialog instance. -# -# - initialfile: initial file (ignored by the open dialog). preserved -# by dialog instance. -# -# - parent: which window to place the dialog on top of -# -# - title: dialog title -# -# - multiple: if true user may select more than one file -# -# options for the directory chooser: -# -# - initialdir, parent, title: see above -# -# - mustexist: if true, user must pick an existing directory -# -# - - -from tkCommonDialog import Dialog - -class _Dialog(Dialog): - - def _fixoptions(self): - try: - # make sure "filetypes" is a tuple - self.options["filetypes"] = tuple(self.options["filetypes"]) - except KeyError: - pass - - def _fixresult(self, widget, result): - if result: - # keep directory and filename until next time - import os - # convert Tcl path objects to strings - try: - result = result.string - except AttributeError: - # it already is a string - pass - path, file = os.path.split(result) - self.options["initialdir"] = path - self.options["initialfile"] = file - self.filename = result # compatibility - return result - - -# -# file dialogs - -class Open(_Dialog): - "Ask for a filename to open" - - command = "tk_getOpenFile" - - def _fixresult(self, widget, result): - if isinstance(result, tuple): - # multiple results: - result = tuple([getattr(r, "string", r) for r in result]) - if result: - import os - path, file = os.path.split(result[0]) - self.options["initialdir"] = path - # don't set initialfile or filename, as we have multiple of these - return result - if not widget.tk.wantobjects() and "multiple" in self.options: - # Need to split result explicitly - return self._fixresult(widget, widget.tk.splitlist(result)) - return _Dialog._fixresult(self, widget, result) - -class SaveAs(_Dialog): - "Ask for a filename to save as" - - command = "tk_getSaveFile" - - -# the directory dialog has its own _fix routines. -class Directory(Dialog): - "Ask for a directory" - - command = "tk_chooseDirectory" - - def _fixresult(self, widget, result): - if result: - # convert Tcl path objects to strings - try: - result = result.string - except AttributeError: - # it already is a string - pass - # keep directory until next time - self.options["initialdir"] = result - self.directory = result # compatibility - return result - -# -# convenience stuff - -def askopenfilename(**options): - "Ask for a filename to open" - - return Open(**options).show() - -def asksaveasfilename(**options): - "Ask for a filename to save as" - - return SaveAs(**options).show() - -def askopenfilenames(**options): - """Ask for multiple filenames to open - - Returns a list of filenames or empty list if - cancel button selected - """ - options["multiple"]=1 - return Open(**options).show() - -# FIXME: are the following perhaps a bit too convenient? - -def askopenfile(mode = "r", **options): - "Ask for a filename to open, and returned the opened file" - - filename = Open(**options).show() - if filename: - return open(filename, mode) - return None - -def askopenfiles(mode = "r", **options): - """Ask for multiple filenames and return the open file - objects - - returns a list of open file objects or an empty list if - cancel selected - """ - - files = askopenfilenames(**options) - if files: - ofiles=[] - for filename in files: - ofiles.append(open(filename, mode)) - files=ofiles - return files - - -def asksaveasfile(mode = "w", **options): - "Ask for a filename to save as, and returned the opened file" - - filename = SaveAs(**options).show() - if filename: - return open(filename, mode) - return None - -def askdirectory (**options): - "Ask for a directory, and return the file name" - return Directory(**options).show() - -# -------------------------------------------------------------------- -# test stuff - -if __name__ == "__main__": - # Since the file name may contain non-ASCII characters, we need - # to find an encoding that likely supports the file name, and - # displays correctly on the terminal. - - # Start off with UTF-8 - enc = "utf-8" - import sys - - # See whether CODESET is defined - try: - import locale - locale.setlocale(locale.LC_ALL,'') - enc = locale.nl_langinfo(locale.CODESET) - except (ImportError, AttributeError): - pass - - # dialog for openening files - - openfilename=askopenfilename(filetypes=[("all files", "*")]) - try: - fp=open(openfilename,"r") - fp.close() - except: - print("Could not open File: ") - print(sys.exc_info()[1]) - - print("open", openfilename.encode(enc)) - - # dialog for saving files - - saveasfilename=asksaveasfilename() - print("saveas", saveasfilename.encode(enc)) Index: Lib/lib-tk/Dialog.py =================================================================== --- Lib/lib-tk/Dialog.py (revision 63074) +++ Lib/lib-tk/Dialog.py (working copy) @@ -1,49 +0,0 @@ -# Dialog.py -- Tkinter interface to the tk_dialog script. - -from Tkinter import * -from Tkinter import _cnfmerge - -if TkVersion <= 3.6: - DIALOG_ICON = 'warning' -else: - DIALOG_ICON = 'questhead' - - -class Dialog(Widget): - def __init__(self, master=None, cnf={}, **kw): - cnf = _cnfmerge((cnf, kw)) - self.widgetName = '__dialog__' - Widget._setup(self, master, cnf) - self.num = self.tk.getint( - self.tk.call( - 'tk_dialog', self._w, - cnf['title'], cnf['text'], - cnf['bitmap'], cnf['default'], - *cnf['strings'])) - try: Widget.destroy(self) - except TclError: pass - def destroy(self): pass - -def _test(): - d = Dialog(None, {'title': 'File Modified', - 'text': - 'File "Python.h" has been modified' - ' since the last time it was saved.' - ' Do you want to save it before' - ' exiting the application.', - 'bitmap': DIALOG_ICON, - 'default': 0, - 'strings': ('Save File', - 'Discard Changes', - 'Return to Editor')}) - print(d.num) - - -if __name__ == '__main__': - t = Button(None, {'text': 'Test', - 'command': _test, - Pack: {}}) - q = Button(None, {'text': 'Quit', - 'command': t.quit, - Pack: {}}) - t.mainloop() Index: Lib/lib-tk/FileDialog.py =================================================================== --- Lib/lib-tk/FileDialog.py (revision 63074) +++ Lib/lib-tk/FileDialog.py (working copy) @@ -1,274 +0,0 @@ -"""File selection dialog classes. - -Classes: - -- FileDialog -- LoadFileDialog -- SaveFileDialog - -""" - -from Tkinter import * -from Dialog import Dialog - -import os -import fnmatch - - -dialogstates = {} - - -class FileDialog: - - """Standard file selection dialog -- no checks on selected file. - - Usage: - - d = FileDialog(master) - fname = d.go(dir_or_file, pattern, default, key) - if fname is None: ...canceled... - else: ...open file... - - All arguments to go() are optional. - - The 'key' argument specifies a key in the global dictionary - 'dialogstates', which keeps track of the values for the directory - and pattern arguments, overriding the values passed in (it does - not keep track of the default argument!). If no key is specified, - the dialog keeps no memory of previous state. Note that memory is - kept even when the dialog is canceled. (All this emulates the - behavior of the Macintosh file selection dialogs.) - - """ - - title = "File Selection Dialog" - - def __init__(self, master, title=None): - if title is None: title = self.title - self.master = master - self.directory = None - - self.top = Toplevel(master) - self.top.title(title) - self.top.iconname(title) - - self.botframe = Frame(self.top) - self.botframe.pack(side=BOTTOM, fill=X) - - self.selection = Entry(self.top) - self.selection.pack(side=BOTTOM, fill=X) - self.selection.bind('', self.ok_event) - - self.filter = Entry(self.top) - self.filter.pack(side=TOP, fill=X) - self.filter.bind('', self.filter_command) - - self.midframe = Frame(self.top) - self.midframe.pack(expand=YES, fill=BOTH) - - self.filesbar = Scrollbar(self.midframe) - self.filesbar.pack(side=RIGHT, fill=Y) - self.files = Listbox(self.midframe, exportselection=0, - yscrollcommand=(self.filesbar, 'set')) - self.files.pack(side=RIGHT, expand=YES, fill=BOTH) - btags = self.files.bindtags() - self.files.bindtags(btags[1:] + btags[:1]) - self.files.bind('', self.files_select_event) - self.files.bind('', self.files_double_event) - self.filesbar.config(command=(self.files, 'yview')) - - self.dirsbar = Scrollbar(self.midframe) - self.dirsbar.pack(side=LEFT, fill=Y) - self.dirs = Listbox(self.midframe, exportselection=0, - yscrollcommand=(self.dirsbar, 'set')) - self.dirs.pack(side=LEFT, expand=YES, fill=BOTH) - self.dirsbar.config(command=(self.dirs, 'yview')) - btags = self.dirs.bindtags() - self.dirs.bindtags(btags[1:] + btags[:1]) - self.dirs.bind('', self.dirs_select_event) - self.dirs.bind('', self.dirs_double_event) - - self.ok_button = Button(self.botframe, - text="OK", - command=self.ok_command) - self.ok_button.pack(side=LEFT) - self.filter_button = Button(self.botframe, - text="Filter", - command=self.filter_command) - self.filter_button.pack(side=LEFT, expand=YES) - self.cancel_button = Button(self.botframe, - text="Cancel", - command=self.cancel_command) - self.cancel_button.pack(side=RIGHT) - - self.top.protocol('WM_DELETE_WINDOW', self.cancel_command) - # XXX Are the following okay for a general audience? - self.top.bind('', self.cancel_command) - self.top.bind('', self.cancel_command) - - def go(self, dir_or_file=os.curdir, pattern="*", default="", key=None): - if key and key in dialogstates: - self.directory, pattern = dialogstates[key] - else: - dir_or_file = os.path.expanduser(dir_or_file) - if os.path.isdir(dir_or_file): - self.directory = dir_or_file - else: - self.directory, default = os.path.split(dir_or_file) - self.set_filter(self.directory, pattern) - self.set_selection(default) - self.filter_command() - self.selection.focus_set() - self.top.wait_visibility() # window needs to be visible for the grab - self.top.grab_set() - self.how = None - self.master.mainloop() # Exited by self.quit(how) - if key: - directory, pattern = self.get_filter() - if self.how: - directory = os.path.dirname(self.how) - dialogstates[key] = directory, pattern - self.top.destroy() - return self.how - - def quit(self, how=None): - self.how = how - self.master.quit() # Exit mainloop() - - def dirs_double_event(self, event): - self.filter_command() - - def dirs_select_event(self, event): - dir, pat = self.get_filter() - subdir = self.dirs.get('active') - dir = os.path.normpath(os.path.join(self.directory, subdir)) - self.set_filter(dir, pat) - - def files_double_event(self, event): - self.ok_command() - - def files_select_event(self, event): - file = self.files.get('active') - self.set_selection(file) - - def ok_event(self, event): - self.ok_command() - - def ok_command(self): - self.quit(self.get_selection()) - - def filter_command(self, event=None): - dir, pat = self.get_filter() - try: - names = os.listdir(dir) - except os.error: - self.master.bell() - return - self.directory = dir - self.set_filter(dir, pat) - names.sort() - subdirs = [os.pardir] - matchingfiles = [] - for name in names: - fullname = os.path.join(dir, name) - if os.path.isdir(fullname): - subdirs.append(name) - elif fnmatch.fnmatch(name, pat): - matchingfiles.append(name) - self.dirs.delete(0, END) - for name in subdirs: - self.dirs.insert(END, name) - self.files.delete(0, END) - for name in matchingfiles: - self.files.insert(END, name) - head, tail = os.path.split(self.get_selection()) - if tail == os.curdir: tail = '' - self.set_selection(tail) - - def get_filter(self): - filter = self.filter.get() - filter = os.path.expanduser(filter) - if filter[-1:] == os.sep or os.path.isdir(filter): - filter = os.path.join(filter, "*") - return os.path.split(filter) - - def get_selection(self): - file = self.selection.get() - file = os.path.expanduser(file) - return file - - def cancel_command(self, event=None): - self.quit() - - def set_filter(self, dir, pat): - if not os.path.isabs(dir): - try: - pwd = os.getcwd() - except os.error: - pwd = None - if pwd: - dir = os.path.join(pwd, dir) - dir = os.path.normpath(dir) - self.filter.delete(0, END) - self.filter.insert(END, os.path.join(dir or os.curdir, pat or "*")) - - def set_selection(self, file): - self.selection.delete(0, END) - self.selection.insert(END, os.path.join(self.directory, file)) - - -class LoadFileDialog(FileDialog): - - """File selection dialog which checks that the file exists.""" - - title = "Load File Selection Dialog" - - def ok_command(self): - file = self.get_selection() - if not os.path.isfile(file): - self.master.bell() - else: - self.quit(file) - - -class SaveFileDialog(FileDialog): - - """File selection dialog which checks that the file may be created.""" - - title = "Save File Selection Dialog" - - def ok_command(self): - file = self.get_selection() - if os.path.exists(file): - if os.path.isdir(file): - self.master.bell() - return - d = Dialog(self.top, - title="Overwrite Existing File Question", - text="Overwrite existing file %r?" % (file,), - bitmap='questhead', - default=1, - strings=("Yes", "Cancel")) - if d.num != 0: - return - else: - head, tail = os.path.split(file) - if not os.path.isdir(head): - self.master.bell() - return - self.quit(file) - - -def test(): - """Simple test program.""" - root = Tk() - root.withdraw() - fd = LoadFileDialog(root) - loadfile = fd.go(key="test") - fd = SaveFileDialog(root) - savefile = fd.go(key="test") - print(loadfile, savefile) - - -if __name__ == '__main__': - test() Index: Lib/lib-tk/tkColorChooser.py =================================================================== --- Lib/lib-tk/tkColorChooser.py (revision 63074) +++ Lib/lib-tk/tkColorChooser.py (working copy) @@ -1,70 +0,0 @@ -# tk common colour chooser dialogue -# -# this module provides an interface to the native color dialogue -# available in Tk 4.2 and newer. -# -# written by Fredrik Lundh, May 1997 -# -# fixed initialcolor handling in August 1998 -# - -# -# options (all have default values): -# -# - initialcolor: colour to mark as selected when dialog is displayed -# (given as an RGB triplet or a Tk color string) -# -# - parent: which window to place the dialog on top of -# -# - title: dialog title -# - -from tkCommonDialog import Dialog - - -# -# color chooser class - -class Chooser(Dialog): - "Ask for a color" - - command = "tk_chooseColor" - - def _fixoptions(self): - try: - # make sure initialcolor is a tk color string - color = self.options["initialcolor"] - if type(color) == type(()): - # assume an RGB triplet - self.options["initialcolor"] = "#%02x%02x%02x" % color - except KeyError: - pass - - def _fixresult(self, widget, result): - # to simplify application code, the color chooser returns - # an RGB tuple together with the Tk color string - if not result: - return None, None # canceled - r, g, b = widget.winfo_rgb(result) - return (r/256, g/256, b/256), result - - -# -# convenience stuff - -def askcolor(color = None, **options): - "Ask for a color" - - if color: - options = options.copy() - options["initialcolor"] = color - - return Chooser(**options).show() - - -# -------------------------------------------------------------------- -# test stuff - -if __name__ == "__main__": - - print("color", askcolor()) Index: Lib/lib-tk/Tix.py =================================================================== --- Lib/lib-tk/Tix.py (revision 63074) +++ Lib/lib-tk/Tix.py (working copy) @@ -1,1891 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8 -*- -# -# $Id$ -# -# Tix.py -- Tix widget wrappers. -# -# For Tix, see http://tix.sourceforge.net -# -# - Sudhir Shenoy (sshenoy@gol.com), Dec. 1995. -# based on an idea of Jean-Marc Lugrin (lugrin@ms.com) -# -# NOTE: In order to minimize changes to Tkinter.py, some of the code here -# (TixWidget.__init__) has been taken from Tkinter (Widget.__init__) -# and will break if there are major changes in Tkinter. -# -# The Tix widgets are represented by a class hierarchy in python with proper -# inheritance of base classes. -# -# As a result after creating a 'w = StdButtonBox', I can write -# w.ok['text'] = 'Who Cares' -# or w.ok['bg'] = w['bg'] -# or even w.ok.invoke() -# etc. -# -# Compare the demo tixwidgets.py to the original Tcl program and you will -# appreciate the advantages. -# - -from Tkinter import * -from Tkinter import _flatten, _cnfmerge, _default_root - -# WARNING - TkVersion is a limited precision floating point number -if TkVersion < 3.999: - raise ImportError("This version of Tix.py requires Tk 4.0 or higher") - -import _tkinter # If this fails your Python may not be configured for Tk - -# Some more constants (for consistency with Tkinter) -WINDOW = 'window' -TEXT = 'text' -STATUS = 'status' -IMMEDIATE = 'immediate' -IMAGE = 'image' -IMAGETEXT = 'imagetext' -BALLOON = 'balloon' -AUTO = 'auto' -ACROSSTOP = 'acrosstop' - -# Some constants used by Tkinter dooneevent() -TCL_DONT_WAIT = 1 << 1 -TCL_WINDOW_EVENTS = 1 << 2 -TCL_FILE_EVENTS = 1 << 3 -TCL_TIMER_EVENTS = 1 << 4 -TCL_IDLE_EVENTS = 1 << 5 -TCL_ALL_EVENTS = 0 - -# BEWARE - this is implemented by copying some code from the Widget class -# in Tkinter (to override Widget initialization) and is therefore -# liable to break. -import Tkinter, os - -# Could probably add this to Tkinter.Misc -class tixCommand: - """The tix commands provide access to miscellaneous elements - of Tix's internal state and the Tix application context. - Most of the information manipulated by these commands pertains - to the application as a whole, or to a screen or - display, rather than to a particular window. - - This is a mixin class, assumed to be mixed to Tkinter.Tk - that supports the self.tk.call method. - """ - - def tix_addbitmapdir(self, directory): - """Tix maintains a list of directories under which - the tix_getimage and tix_getbitmap commands will - search for image files. The standard bitmap directory - is $TIX_LIBRARY/bitmaps. The addbitmapdir command - adds directory into this list. By using this - command, the image files of an applications can - also be located using the tix_getimage or tix_getbitmap - command. - """ - return self.tk.call('tix', 'addbitmapdir', directory) - - def tix_cget(self, option): - """Returns the current value of the configuration - option given by option. Option may be any of the - options described in the CONFIGURATION OPTIONS section. - """ - return self.tk.call('tix', 'cget', option) - - def tix_configure(self, cnf=None, **kw): - """Query or modify the configuration options of the Tix application - context. If no option is specified, returns a dictionary all of the - available options. If option is specified with no value, then the - command returns a list describing the one named option (this list - will be identical to the corresponding sublist of the value - returned if no option is specified). If one or more option-value - pairs are specified, then the command modifies the given option(s) - to have the given value(s); in this case the command returns an - empty string. Option may be any of the configuration options. - """ - # Copied from Tkinter.py - if kw: - cnf = _cnfmerge((cnf, kw)) - elif cnf: - cnf = _cnfmerge(cnf) - if cnf is None: - cnf = {} - for x in self.tk.split(self.tk.call('tix', 'configure')): - cnf[x[0][1:]] = (x[0][1:],) + x[1:] - return cnf - if isinstance(cnf, StringType): - x = self.tk.split(self.tk.call('tix', 'configure', '-'+cnf)) - return (x[0][1:],) + x[1:] - return self.tk.call(('tix', 'configure') + self._options(cnf)) - - def tix_filedialog(self, dlgclass=None): - """Returns the file selection dialog that may be shared among - different calls from this application. This command will create a - file selection dialog widget when it is called the first time. This - dialog will be returned by all subsequent calls to tix_filedialog. - An optional dlgclass parameter can be passed to specified what type - of file selection dialog widget is desired. Possible options are - tix FileSelectDialog or tixExFileSelectDialog. - """ - if dlgclass is not None: - return self.tk.call('tix', 'filedialog', dlgclass) - else: - return self.tk.call('tix', 'filedialog') - - def tix_getbitmap(self, name): - """Locates a bitmap file of the name name.xpm or name in one of the - bitmap directories (see the tix_addbitmapdir command above). By - using tix_getbitmap, you can avoid hard coding the pathnames of the - bitmap files in your application. When successful, it returns the - complete pathname of the bitmap file, prefixed with the character - '@'. The returned value can be used to configure the -bitmap - option of the TK and Tix widgets. - """ - return self.tk.call('tix', 'getbitmap', name) - - def tix_getimage(self, name): - """Locates an image file of the name name.xpm, name.xbm or name.ppm - in one of the bitmap directories (see the addbitmapdir command - above). If more than one file with the same name (but different - extensions) exist, then the image type is chosen according to the - depth of the X display: xbm images are chosen on monochrome - displays and color images are chosen on color displays. By using - tix_ getimage, you can advoid hard coding the pathnames of the - image files in your application. When successful, this command - returns the name of the newly created image, which can be used to - configure the -image option of the Tk and Tix widgets. - """ - return self.tk.call('tix', 'getimage', name) - - def tix_option_get(self, name): - """Gets the options manitained by the Tix - scheme mechanism. Available options include: - - active_bg active_fg bg - bold_font dark1_bg dark1_fg - dark2_bg dark2_fg disabled_fg - fg fixed_font font - inactive_bg inactive_fg input1_bg - input2_bg italic_font light1_bg - light1_fg light2_bg light2_fg - menu_font output1_bg output2_bg - select_bg select_fg selector - """ - # could use self.tk.globalgetvar('tixOption', name) - return self.tk.call('tix', 'option', 'get', name) - - def tix_resetoptions(self, newScheme, newFontSet, newScmPrio=None): - """Resets the scheme and fontset of the Tix application to - newScheme and newFontSet, respectively. This affects only those - widgets created after this call. Therefore, it is best to call the - resetoptions command before the creation of any widgets in a Tix - application. - - The optional parameter newScmPrio can be given to reset the - priority level of the Tk options set by the Tix schemes. - - Because of the way Tk handles the X option database, after Tix has - been has imported and inited, it is not possible to reset the color - schemes and font sets using the tix config command. Instead, the - tix_resetoptions command must be used. - """ - if newScmPrio is not None: - return self.tk.call('tix', 'resetoptions', newScheme, newFontSet, newScmPrio) - else: - return self.tk.call('tix', 'resetoptions', newScheme, newFontSet) - -class Tk(Tkinter.Tk, tixCommand): - """Toplevel widget of Tix which represents mostly the main window - of an application. It has an associated Tcl interpreter.""" - def __init__(self, screenName=None, baseName=None, className='Tix'): - Tkinter.Tk.__init__(self, screenName, baseName, className) - tixlib = os.environ.get('TIX_LIBRARY') - self.tk.eval('global auto_path; lappend auto_path [file dir [info nameof]]') - if tixlib is not None: - self.tk.eval('global auto_path; lappend auto_path {%s}' % tixlib) - self.tk.eval('global tcl_pkgPath; lappend tcl_pkgPath {%s}' % tixlib) - # Load Tix - this should work dynamically or statically - # If it's static, tcl/tix8.1/pkgIndex.tcl should have - # 'load {} Tix' - # If it's dynamic under Unix, tcl/tix8.1/pkgIndex.tcl should have - # 'load libtix8.1.8.3.so Tix' - self.tk.eval('package require Tix') - - def destroy(self): - # For safety, remove an delete_window binding before destroy - self.protocol("WM_DELETE_WINDOW", "") - Tkinter.Tk.destroy(self) - -# The Tix 'tixForm' geometry manager -class Form: - """The Tix Form geometry manager - - Widgets can be arranged by specifying attachments to other widgets. - See Tix documentation for complete details""" - - def config(self, cnf={}, **kw): - self.tk.call('tixForm', self._w, *self._options(cnf, kw)) - - form = config - - def __setitem__(self, key, value): - Form.form(self, {key: value}) - - def check(self): - return self.tk.call('tixForm', 'check', self._w) - - def forget(self): - self.tk.call('tixForm', 'forget', self._w) - - def grid(self, xsize=0, ysize=0): - if (not xsize) and (not ysize): - x = self.tk.call('tixForm', 'grid', self._w) - y = self.tk.splitlist(x) - z = () - for x in y: - z = z + (self.tk.getint(x),) - return z - return self.tk.call('tixForm', 'grid', self._w, xsize, ysize) - - def info(self, option=None): - if not option: - return self.tk.call('tixForm', 'info', self._w) - if option[0] != '-': - option = '-' + option - return self.tk.call('tixForm', 'info', self._w, option) - - def slaves(self): - return map(self._nametowidget, - self.tk.splitlist( - self.tk.call( - 'tixForm', 'slaves', self._w))) - - - -Tkinter.Widget.__bases__ = Tkinter.Widget.__bases__ + (Form,) - -class TixWidget(Tkinter.Widget): - """A TixWidget class is used to package all (or most) Tix widgets. - - Widget initialization is extended in two ways: - 1) It is possible to give a list of options which must be part of - the creation command (so called Tix 'static' options). These cannot be - given as a 'config' command later. - 2) It is possible to give the name of an existing TK widget. These are - child widgets created automatically by a Tix mega-widget. The Tk call - to create these widgets is therefore bypassed in TixWidget.__init__ - - Both options are for use by subclasses only. - """ - def __init__ (self, master=None, widgetName=None, - static_options=None, cnf={}, kw={}): - # Merge keywords and dictionary arguments - if kw: - cnf = _cnfmerge((cnf, kw)) - else: - cnf = _cnfmerge(cnf) - - # Move static options into extra. static_options must be - # a list of keywords (or None). - extra=() - - # 'options' is always a static option - if static_options: - static_options.append('options') - else: - static_options = ['options'] - - for k,v in cnf.items()[:]: - if k in static_options: - extra = extra + ('-' + k, v) - del cnf[k] - - self.widgetName = widgetName - Widget._setup(self, master, cnf) - - # If widgetName is None, this is a dummy creation call where the - # corresponding Tk widget has already been created by Tix - if widgetName: - self.tk.call(widgetName, self._w, *extra) - - # Non-static options - to be done via a 'config' command - if cnf: - Widget.config(self, cnf) - - # Dictionary to hold subwidget names for easier access. We can't - # use the children list because the public Tix names may not be the - # same as the pathname component - self.subwidget_list = {} - - # We set up an attribute access function so that it is possible to - # do w.ok['text'] = 'Hello' rather than w.subwidget('ok')['text'] = 'Hello' - # when w is a StdButtonBox. - # We can even do w.ok.invoke() because w.ok is subclassed from the - # Button class if you go through the proper constructors - def __getattr__(self, name): - if name in self.subwidget_list: - return self.subwidget_list[name] - raise AttributeError(name) - - def set_silent(self, value): - """Set a variable without calling its action routine""" - self.tk.call('tixSetSilent', self._w, value) - - def subwidget(self, name): - """Return the named subwidget (which must have been created by - the sub-class).""" - n = self._subwidget_name(name) - if not n: - raise TclError("Subwidget " + name + " not child of " + self._name) - # Remove header of name and leading dot - n = n[len(self._w)+1:] - return self._nametowidget(n) - - def subwidgets_all(self): - """Return all subwidgets.""" - names = self._subwidget_names() - if not names: - return [] - retlist = [] - for name in names: - name = name[len(self._w)+1:] - try: - retlist.append(self._nametowidget(name)) - except: - # some of the widgets are unknown e.g. border in LabelFrame - pass - return retlist - - def _subwidget_name(self,name): - """Get a subwidget name (returns a String, not a Widget !)""" - try: - return self.tk.call(self._w, 'subwidget', name) - except TclError: - return None - - def _subwidget_names(self): - """Return the name of all subwidgets.""" - try: - x = self.tk.call(self._w, 'subwidgets', '-all') - return self.tk.split(x) - except TclError: - return None - - def config_all(self, option, value): - """Set configuration options for all subwidgets (and self).""" - if option == '': - return - elif not isinstance(option, StringType): - option = repr(option) - if not isinstance(value, StringType): - value = repr(value) - names = self._subwidget_names() - for name in names: - self.tk.call(name, 'configure', '-' + option, value) - # These are missing from Tkinter - def image_create(self, imgtype, cnf={}, master=None, **kw): - if not master: - master = Tkinter._default_root - if not master: - raise RuntimeError('Too early to create image') - if kw and cnf: cnf = _cnfmerge((cnf, kw)) - elif kw: cnf = kw - options = () - for k, v in cnf.items(): - if hasattr(v, '__call__'): - v = self._register(v) - options = options + ('-'+k, v) - return master.tk.call(('image', 'create', imgtype,) + options) - def image_delete(self, imgname): - try: - self.tk.call('image', 'delete', imgname) - except TclError: - # May happen if the root was destroyed - pass - -# Subwidgets are child widgets created automatically by mega-widgets. -# In python, we have to create these subwidgets manually to mirror their -# existence in Tk/Tix. -class TixSubWidget(TixWidget): - """Subwidget class. - - This is used to mirror child widgets automatically created - by Tix/Tk as part of a mega-widget in Python (which is not informed - of this)""" - - def __init__(self, master, name, - destroy_physically=1, check_intermediate=1): - if check_intermediate: - path = master._subwidget_name(name) - try: - path = path[len(master._w)+1:] - plist = path.split('.') - except: - plist = [] - - if not check_intermediate: - # immediate descendant - TixWidget.__init__(self, master, None, None, {'name' : name}) - else: - # Ensure that the intermediate widgets exist - parent = master - for i in range(len(plist) - 1): - n = '.'.join(plist[:i+1]) - try: - w = master._nametowidget(n) - parent = w - except KeyError: - # Create the intermediate widget - parent = TixSubWidget(parent, plist[i], - destroy_physically=0, - check_intermediate=0) - # The Tk widget name is in plist, not in name - if plist: - name = plist[-1] - TixWidget.__init__(self, parent, None, None, {'name' : name}) - self.destroy_physically = destroy_physically - - def destroy(self): - # For some widgets e.g., a NoteBook, when we call destructors, - # we must be careful not to destroy the frame widget since this - # also destroys the parent NoteBook thus leading to an exception - # in Tkinter when it finally calls Tcl to destroy the NoteBook - for c in self.children.values(): c.destroy() - if self._name in self.master.children: - del self.master.children[self._name] - if self._name in self.master.subwidget_list: - del self.master.subwidget_list[self._name] - if self.destroy_physically: - # This is bypassed only for a few widgets - self.tk.call('destroy', self._w) - - -# Useful func. to split Tcl lists and return as a dict. From Tkinter.py -def _lst2dict(lst): - dict = {} - for x in lst: - dict[x[0][1:]] = (x[0][1:],) + x[1:] - return dict - -# Useful class to create a display style - later shared by many items. -# Contributed by Steffen Kremser -class DisplayStyle: - """DisplayStyle - handle configuration options shared by - (multiple) Display Items""" - - def __init__(self, itemtype, cnf={}, **kw): - master = _default_root # global from Tkinter - if not master and 'refwindow' in cnf: master=cnf['refwindow'] - elif not master and 'refwindow' in kw: master= kw['refwindow'] - elif not master: raise RuntimeError("Too early to create display style: no root window") - self.tk = master.tk - self.stylename = self.tk.call('tixDisplayStyle', itemtype, - *self._options(cnf,kw) ) - - def __str__(self): - return self.stylename - - def _options(self, cnf, kw): - if kw and cnf: - cnf = _cnfmerge((cnf, kw)) - elif kw: - cnf = kw - opts = () - for k, v in cnf.items(): - opts = opts + ('-'+k, v) - return opts - - def delete(self): - self.tk.call(self.stylename, 'delete') - - def __setitem__(self,key,value): - self.tk.call(self.stylename, 'configure', '-%s'%key, value) - - def config(self, cnf={}, **kw): - return _lst2dict( - self.tk.split( - self.tk.call( - self.stylename, 'configure', *self._options(cnf,kw)))) - - def __getitem__(self,key): - return self.tk.call(self.stylename, 'cget', '-%s'%key) - - -###################################################### -### The Tix Widget classes - in alphabetical order ### -###################################################### - -class Balloon(TixWidget): - """Balloon help widget. - - Subwidget Class - --------- ----- - label Label - message Message""" - - # FIXME: It should inherit -superclass tixShell - def __init__(self, master=None, cnf={}, **kw): - # static seem to be -installcolormap -initwait -statusbar -cursor - static = ['options', 'installcolormap', 'initwait', 'statusbar', - 'cursor'] - TixWidget.__init__(self, master, 'tixBalloon', static, cnf, kw) - self.subwidget_list['label'] = _dummyLabel(self, 'label', - destroy_physically=0) - self.subwidget_list['message'] = _dummyLabel(self, 'message', - destroy_physically=0) - - def bind_widget(self, widget, cnf={}, **kw): - """Bind balloon widget to another. - One balloon widget may be bound to several widgets at the same time""" - self.tk.call(self._w, 'bind', widget._w, *self._options(cnf, kw)) - - def unbind_widget(self, widget): - self.tk.call(self._w, 'unbind', widget._w) - -class ButtonBox(TixWidget): - """ButtonBox - A container for pushbuttons. - Subwidgets are the buttons added with the add method. - """ - def __init__(self, master=None, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixButtonBox', - ['orientation', 'options'], cnf, kw) - - def add(self, name, cnf={}, **kw): - """Add a button with given name to box.""" - - btn = self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) - self.subwidget_list[name] = _dummyButton(self, name) - return btn - - def invoke(self, name): - if name in self.subwidget_list: - self.tk.call(self._w, 'invoke', name) - -class ComboBox(TixWidget): - """ComboBox - an Entry field with a dropdown menu. The user can select a - choice by either typing in the entry subwdget or selecting from the - listbox subwidget. - - Subwidget Class - --------- ----- - entry Entry - arrow Button - slistbox ScrolledListBox - tick Button - cross Button : present if created with the fancy option""" - - # FIXME: It should inherit -superclass tixLabelWidget - def __init__ (self, master=None, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixComboBox', - ['editable', 'dropdown', 'fancy', 'options'], - cnf, kw) - self.subwidget_list['label'] = _dummyLabel(self, 'label') - self.subwidget_list['entry'] = _dummyEntry(self, 'entry') - self.subwidget_list['arrow'] = _dummyButton(self, 'arrow') - self.subwidget_list['slistbox'] = _dummyScrolledListBox(self, - 'slistbox') - try: - self.subwidget_list['tick'] = _dummyButton(self, 'tick') - self.subwidget_list['cross'] = _dummyButton(self, 'cross') - except TypeError: - # unavailable when -fancy not specified - pass - - # align - - def add_history(self, str): - self.tk.call(self._w, 'addhistory', str) - - def append_history(self, str): - self.tk.call(self._w, 'appendhistory', str) - - def insert(self, index, str): - self.tk.call(self._w, 'insert', index, str) - - def pick(self, index): - self.tk.call(self._w, 'pick', index) - -class Control(TixWidget): - """Control - An entry field with value change arrows. The user can - adjust the value by pressing the two arrow buttons or by entering - the value directly into the entry. The new value will be checked - against the user-defined upper and lower limits. - - Subwidget Class - --------- ----- - incr Button - decr Button - entry Entry - label Label""" - - # FIXME: It should inherit -superclass tixLabelWidget - def __init__ (self, master=None, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixControl', ['options'], cnf, kw) - self.subwidget_list['incr'] = _dummyButton(self, 'incr') - self.subwidget_list['decr'] = _dummyButton(self, 'decr') - self.subwidget_list['label'] = _dummyLabel(self, 'label') - self.subwidget_list['entry'] = _dummyEntry(self, 'entry') - - def decrement(self): - self.tk.call(self._w, 'decr') - - def increment(self): - self.tk.call(self._w, 'incr') - - def invoke(self): - self.tk.call(self._w, 'invoke') - - def update(self): - self.tk.call(self._w, 'update') - -class DirList(TixWidget): - """DirList - displays a list view of a directory, its previous - directories and its sub-directories. The user can choose one of - the directories displayed in the list or change to another directory. - - Subwidget Class - --------- ----- - hlist HList - hsb Scrollbar - vsb Scrollbar""" - - # FIXME: It should inherit -superclass tixScrolledHList - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixDirList', ['options'], cnf, kw) - self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') - self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') - self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') - - def chdir(self, dir): - self.tk.call(self._w, 'chdir', dir) - -class DirTree(TixWidget): - """DirTree - Directory Listing in a hierarchical view. - Displays a tree view of a directory, its previous directories and its - sub-directories. The user can choose one of the directories displayed - in the list or change to another directory. - - Subwidget Class - --------- ----- - hlist HList - hsb Scrollbar - vsb Scrollbar""" - - # FIXME: It should inherit -superclass tixScrolledHList - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixDirTree', ['options'], cnf, kw) - self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') - self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') - self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') - - def chdir(self, dir): - self.tk.call(self._w, 'chdir', dir) - -class DirSelectBox(TixWidget): - """DirSelectBox - Motif style file select box. - It is generally used for - the user to choose a file. FileSelectBox stores the files mostly - recently selected into a ComboBox widget so that they can be quickly - selected again. - - Subwidget Class - --------- ----- - selection ComboBox - filter ComboBox - dirlist ScrolledListBox - filelist ScrolledListBox""" - - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixDirSelectBox', ['options'], cnf, kw) - self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist') - self.subwidget_list['dircbx'] = _dummyFileComboBox(self, 'dircbx') - -class ExFileSelectBox(TixWidget): - """ExFileSelectBox - MS Windows style file select box. - It provides an convenient method for the user to select files. - - Subwidget Class - --------- ----- - cancel Button - ok Button - hidden Checkbutton - types ComboBox - dir ComboBox - file ComboBox - dirlist ScrolledListBox - filelist ScrolledListBox""" - - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixExFileSelectBox', ['options'], cnf, kw) - self.subwidget_list['cancel'] = _dummyButton(self, 'cancel') - self.subwidget_list['ok'] = _dummyButton(self, 'ok') - self.subwidget_list['hidden'] = _dummyCheckbutton(self, 'hidden') - self.subwidget_list['types'] = _dummyComboBox(self, 'types') - self.subwidget_list['dir'] = _dummyComboBox(self, 'dir') - self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist') - self.subwidget_list['file'] = _dummyComboBox(self, 'file') - self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist') - - def filter(self): - self.tk.call(self._w, 'filter') - - def invoke(self): - self.tk.call(self._w, 'invoke') - - -# Should inherit from a Dialog class -class DirSelectDialog(TixWidget): - """The DirSelectDialog widget presents the directories in the file - system in a dialog window. The user can use this dialog window to - navigate through the file system to select the desired directory. - - Subwidgets Class - ---------- ----- - dirbox DirSelectDialog""" - - # FIXME: It should inherit -superclass tixDialogShell - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixDirSelectDialog', - ['options'], cnf, kw) - self.subwidget_list['dirbox'] = _dummyDirSelectBox(self, 'dirbox') - # cancel and ok buttons are missing - - def popup(self): - self.tk.call(self._w, 'popup') - - def popdown(self): - self.tk.call(self._w, 'popdown') - - -# Should inherit from a Dialog class -class ExFileSelectDialog(TixWidget): - """ExFileSelectDialog - MS Windows style file select dialog. - It provides an convenient method for the user to select files. - - Subwidgets Class - ---------- ----- - fsbox ExFileSelectBox""" - - # FIXME: It should inherit -superclass tixDialogShell - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixExFileSelectDialog', - ['options'], cnf, kw) - self.subwidget_list['fsbox'] = _dummyExFileSelectBox(self, 'fsbox') - - def popup(self): - self.tk.call(self._w, 'popup') - - def popdown(self): - self.tk.call(self._w, 'popdown') - -class FileSelectBox(TixWidget): - """ExFileSelectBox - Motif style file select box. - It is generally used for - the user to choose a file. FileSelectBox stores the files mostly - recently selected into a ComboBox widget so that they can be quickly - selected again. - - Subwidget Class - --------- ----- - selection ComboBox - filter ComboBox - dirlist ScrolledListBox - filelist ScrolledListBox""" - - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixFileSelectBox', ['options'], cnf, kw) - self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist') - self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist') - self.subwidget_list['filter'] = _dummyComboBox(self, 'filter') - self.subwidget_list['selection'] = _dummyComboBox(self, 'selection') - - def apply_filter(self): # name of subwidget is same as command - self.tk.call(self._w, 'filter') - - def invoke(self): - self.tk.call(self._w, 'invoke') - -# Should inherit from a Dialog class -class FileSelectDialog(TixWidget): - """FileSelectDialog - Motif style file select dialog. - - Subwidgets Class - ---------- ----- - btns StdButtonBox - fsbox FileSelectBox""" - - # FIXME: It should inherit -superclass tixStdDialogShell - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixFileSelectDialog', - ['options'], cnf, kw) - self.subwidget_list['btns'] = _dummyStdButtonBox(self, 'btns') - self.subwidget_list['fsbox'] = _dummyFileSelectBox(self, 'fsbox') - - def popup(self): - self.tk.call(self._w, 'popup') - - def popdown(self): - self.tk.call(self._w, 'popdown') - -class FileEntry(TixWidget): - """FileEntry - Entry field with button that invokes a FileSelectDialog. - The user can type in the filename manually. Alternatively, the user can - press the button widget that sits next to the entry, which will bring - up a file selection dialog. - - Subwidgets Class - ---------- ----- - button Button - entry Entry""" - - # FIXME: It should inherit -superclass tixLabelWidget - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixFileEntry', - ['dialogtype', 'options'], cnf, kw) - self.subwidget_list['button'] = _dummyButton(self, 'button') - self.subwidget_list['entry'] = _dummyEntry(self, 'entry') - - def invoke(self): - self.tk.call(self._w, 'invoke') - - def file_dialog(self): - # FIXME: return python object - pass - -class HList(TixWidget): - """HList - Hierarchy display widget can be used to display any data - that have a hierarchical structure, for example, file system directory - trees. The list entries are indented and connected by branch lines - according to their places in the hierachy. - - Subwidgets - None""" - - def __init__ (self,master=None,cnf={}, **kw): - TixWidget.__init__(self, master, 'tixHList', - ['columns', 'options'], cnf, kw) - - def add(self, entry, cnf={}, **kw): - return self.tk.call(self._w, 'add', entry, *self._options(cnf, kw)) - - def add_child(self, parent=None, cnf={}, **kw): - if not parent: - parent = '' - return self.tk.call( - self._w, 'addchild', parent, *self._options(cnf, kw)) - - def anchor_set(self, entry): - self.tk.call(self._w, 'anchor', 'set', entry) - - def anchor_clear(self): - self.tk.call(self._w, 'anchor', 'clear') - - def column_width(self, col=0, width=None, chars=None): - if not chars: - return self.tk.call(self._w, 'column', 'width', col, width) - else: - return self.tk.call(self._w, 'column', 'width', col, - '-char', chars) - - def delete_all(self): - self.tk.call(self._w, 'delete', 'all') - - def delete_entry(self, entry): - self.tk.call(self._w, 'delete', 'entry', entry) - - def delete_offsprings(self, entry): - self.tk.call(self._w, 'delete', 'offsprings', entry) - - def delete_siblings(self, entry): - self.tk.call(self._w, 'delete', 'siblings', entry) - - def dragsite_set(self, index): - self.tk.call(self._w, 'dragsite', 'set', index) - - def dragsite_clear(self): - self.tk.call(self._w, 'dragsite', 'clear') - - def dropsite_set(self, index): - self.tk.call(self._w, 'dropsite', 'set', index) - - def dropsite_clear(self): - self.tk.call(self._w, 'dropsite', 'clear') - - def header_create(self, col, cnf={}, **kw): - self.tk.call(self._w, 'header', 'create', col, *self._options(cnf, kw)) - - def header_configure(self, col, cnf={}, **kw): - if cnf is None: - return _lst2dict( - self.tk.split( - self.tk.call(self._w, 'header', 'configure', col))) - self.tk.call(self._w, 'header', 'configure', col, - *self._options(cnf, kw)) - - def header_cget(self, col, opt): - return self.tk.call(self._w, 'header', 'cget', col, opt) - - def header_exists(self, col): - return self.tk.call(self._w, 'header', 'exists', col) - - def header_delete(self, col): - self.tk.call(self._w, 'header', 'delete', col) - - def header_size(self, col): - return self.tk.call(self._w, 'header', 'size', col) - - def hide_entry(self, entry): - self.tk.call(self._w, 'hide', 'entry', entry) - - def indicator_create(self, entry, cnf={}, **kw): - self.tk.call( - self._w, 'indicator', 'create', entry, *self._options(cnf, kw)) - - def indicator_configure(self, entry, cnf={}, **kw): - if cnf is None: - return _lst2dict( - self.tk.split( - self.tk.call(self._w, 'indicator', 'configure', entry))) - self.tk.call( - self._w, 'indicator', 'configure', entry, *self._options(cnf, kw)) - - def indicator_cget(self, entry, opt): - return self.tk.call(self._w, 'indicator', 'cget', entry, opt) - - def indicator_exists(self, entry): - return self.tk.call (self._w, 'indicator', 'exists', entry) - - def indicator_delete(self, entry): - self.tk.call(self._w, 'indicator', 'delete', entry) - - def indicator_size(self, entry): - return self.tk.call(self._w, 'indicator', 'size', entry) - - def info_anchor(self): - return self.tk.call(self._w, 'info', 'anchor') - - def info_children(self, entry=None): - c = self.tk.call(self._w, 'info', 'children', entry) - return self.tk.splitlist(c) - - def info_data(self, entry): - return self.tk.call(self._w, 'info', 'data', entry) - - def info_exists(self, entry): - return self.tk.call(self._w, 'info', 'exists', entry) - - def info_hidden(self, entry): - return self.tk.call(self._w, 'info', 'hidden', entry) - - def info_next(self, entry): - return self.tk.call(self._w, 'info', 'next', entry) - - def info_parent(self, entry): - return self.tk.call(self._w, 'info', 'parent', entry) - - def info_prev(self, entry): - return self.tk.call(self._w, 'info', 'prev', entry) - - def info_selection(self): - c = self.tk.call(self._w, 'info', 'selection') - return self.tk.splitlist(c) - - def item_cget(self, entry, col, opt): - return self.tk.call(self._w, 'item', 'cget', entry, col, opt) - - def item_configure(self, entry, col, cnf={}, **kw): - if cnf is None: - return _lst2dict( - self.tk.split( - self.tk.call(self._w, 'item', 'configure', entry, col))) - self.tk.call(self._w, 'item', 'configure', entry, col, - *self._options(cnf, kw)) - - def item_create(self, entry, col, cnf={}, **kw): - self.tk.call( - self._w, 'item', 'create', entry, col, *self._options(cnf, kw)) - - def item_exists(self, entry, col): - return self.tk.call(self._w, 'item', 'exists', entry, col) - - def item_delete(self, entry, col): - self.tk.call(self._w, 'item', 'delete', entry, col) - - def entrycget(self, entry, opt): - return self.tk.call(self._w, 'entrycget', entry, opt) - - def entryconfigure(self, entry, cnf={}, **kw): - if cnf is None: - return _lst2dict( - self.tk.split( - self.tk.call(self._w, 'entryconfigure', entry))) - self.tk.call(self._w, 'entryconfigure', entry, - *self._options(cnf, kw)) - - def nearest(self, y): - return self.tk.call(self._w, 'nearest', y) - - def see(self, entry): - self.tk.call(self._w, 'see', entry) - - def selection_clear(self, cnf={}, **kw): - self.tk.call(self._w, 'selection', 'clear', *self._options(cnf, kw)) - - def selection_includes(self, entry): - return self.tk.call(self._w, 'selection', 'includes', entry) - - def selection_set(self, first, last=None): - self.tk.call(self._w, 'selection', 'set', first, last) - - def show_entry(self, entry): - return self.tk.call(self._w, 'show', 'entry', entry) - - def xview(self, *args): - self.tk.call(self._w, 'xview', *args) - - def yview(self, *args): - self.tk.call(self._w, 'yview', *args) - -class InputOnly(TixWidget): - """InputOnly - Invisible widget. Unix only. - - Subwidgets - None""" - - def __init__ (self,master=None,cnf={}, **kw): - TixWidget.__init__(self, master, 'tixInputOnly', None, cnf, kw) - -class LabelEntry(TixWidget): - """LabelEntry - Entry field with label. Packages an entry widget - and a label into one mega widget. It can beused be used to simplify - the creation of ``entry-form'' type of interface. - - Subwidgets Class - ---------- ----- - label Label - entry Entry""" - - def __init__ (self,master=None,cnf={}, **kw): - TixWidget.__init__(self, master, 'tixLabelEntry', - ['labelside','options'], cnf, kw) - self.subwidget_list['label'] = _dummyLabel(self, 'label') - self.subwidget_list['entry'] = _dummyEntry(self, 'entry') - -class LabelFrame(TixWidget): - """LabelFrame - Labelled Frame container. Packages a frame widget - and a label into one mega widget. To create widgets inside a - LabelFrame widget, one creates the new widgets relative to the - frame subwidget and manage them inside the frame subwidget. - - Subwidgets Class - ---------- ----- - label Label - frame Frame""" - - def __init__ (self,master=None,cnf={}, **kw): - TixWidget.__init__(self, master, 'tixLabelFrame', - ['labelside','options'], cnf, kw) - self.subwidget_list['label'] = _dummyLabel(self, 'label') - self.subwidget_list['frame'] = _dummyFrame(self, 'frame') - - -class ListNoteBook(TixWidget): - """A ListNoteBook widget is very similar to the TixNoteBook widget: - it can be used to display many windows in a limited space using a - notebook metaphor. The notebook is divided into a stack of pages - (windows). At one time only one of these pages can be shown. - The user can navigate through these pages by - choosing the name of the desired page in the hlist subwidget.""" - - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixListNoteBook', ['options'], cnf, kw) - # Is this necessary? It's not an exposed subwidget in Tix. - self.subwidget_list['pane'] = _dummyPanedWindow(self, 'pane', - destroy_physically=0) - self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') - self.subwidget_list['shlist'] = _dummyScrolledHList(self, 'shlist') - - def add(self, name, cnf={}, **kw): - self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) - self.subwidget_list[name] = TixSubWidget(self, name) - return self.subwidget_list[name] - - def page(self, name): - return self.subwidget(name) - - def pages(self): - # Can't call subwidgets_all directly because we don't want .nbframe - names = self.tk.split(self.tk.call(self._w, 'pages')) - ret = [] - for x in names: - ret.append(self.subwidget(x)) - return ret - - def raise_page(self, name): # raise is a python keyword - self.tk.call(self._w, 'raise', name) - -class Meter(TixWidget): - """The Meter widget can be used to show the progress of a background - job which may take a long time to execute. - """ - - def __init__(self, master=None, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixMeter', - ['options'], cnf, kw) - -class NoteBook(TixWidget): - """NoteBook - Multi-page container widget (tabbed notebook metaphor). - - Subwidgets Class - ---------- ----- - nbframe NoteBookFrame - page widgets added dynamically with the add method""" - - def __init__ (self,master=None,cnf={}, **kw): - TixWidget.__init__(self,master,'tixNoteBook', ['options'], cnf, kw) - self.subwidget_list['nbframe'] = TixSubWidget(self, 'nbframe', - destroy_physically=0) - - def add(self, name, cnf={}, **kw): - self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) - self.subwidget_list[name] = TixSubWidget(self, name) - return self.subwidget_list[name] - - def delete(self, name): - self.tk.call(self._w, 'delete', name) - self.subwidget_list[name].destroy() - del self.subwidget_list[name] - - def page(self, name): - return self.subwidget(name) - - def pages(self): - # Can't call subwidgets_all directly because we don't want .nbframe - names = self.tk.split(self.tk.call(self._w, 'pages')) - ret = [] - for x in names: - ret.append(self.subwidget(x)) - return ret - - def raise_page(self, name): # raise is a python keyword - self.tk.call(self._w, 'raise', name) - - def raised(self): - return self.tk.call(self._w, 'raised') - -class NoteBookFrame(TixWidget): - # FIXME: This is dangerous to expose to be called on its own. - pass - -class OptionMenu(TixWidget): - """OptionMenu - creates a menu button of options. - - Subwidget Class - --------- ----- - menubutton Menubutton - menu Menu""" - - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixOptionMenu', ['options'], cnf, kw) - self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton') - self.subwidget_list['menu'] = _dummyMenu(self, 'menu') - - def add_command(self, name, cnf={}, **kw): - self.tk.call(self._w, 'add', 'command', name, *self._options(cnf, kw)) - - def add_separator(self, name, cnf={}, **kw): - self.tk.call(self._w, 'add', 'separator', name, *self._options(cnf, kw)) - - def delete(self, name): - self.tk.call(self._w, 'delete', name) - - def disable(self, name): - self.tk.call(self._w, 'disable', name) - - def enable(self, name): - self.tk.call(self._w, 'enable', name) - -class PanedWindow(TixWidget): - """PanedWindow - Multi-pane container widget - allows the user to interactively manipulate the sizes of several - panes. The panes can be arranged either vertically or horizontally.The - user changes the sizes of the panes by dragging the resize handle - between two panes. - - Subwidgets Class - ---------- ----- - g/p widgets added dynamically with the add method.""" - - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixPanedWindow', ['orientation', 'options'], cnf, kw) - - # add delete forget panecget paneconfigure panes setsize - def add(self, name, cnf={}, **kw): - self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) - self.subwidget_list[name] = TixSubWidget(self, name, - check_intermediate=0) - return self.subwidget_list[name] - - def delete(self, name): - self.tk.call(self._w, 'delete', name) - self.subwidget_list[name].destroy() - del self.subwidget_list[name] - - def forget(self, name): - self.tk.call(self._w, 'forget', name) - - def panecget(self, entry, opt): - return self.tk.call(self._w, 'panecget', entry, opt) - - def paneconfigure(self, entry, cnf={}, **kw): - if cnf is None: - return _lst2dict( - self.tk.split( - self.tk.call(self._w, 'paneconfigure', entry))) - self.tk.call(self._w, 'paneconfigure', entry, *self._options(cnf, kw)) - - def panes(self): - names = self.tk.call(self._w, 'panes') - ret = [] - for x in names: - ret.append(self.subwidget(x)) - return ret - -class PopupMenu(TixWidget): - """PopupMenu widget can be used as a replacement of the tk_popup command. - The advantage of the Tix PopupMenu widget is it requires less application - code to manipulate. - - - Subwidgets Class - ---------- ----- - menubutton Menubutton - menu Menu""" - - # FIXME: It should inherit -superclass tixShell - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixPopupMenu', ['options'], cnf, kw) - self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton') - self.subwidget_list['menu'] = _dummyMenu(self, 'menu') - - def bind_widget(self, widget): - self.tk.call(self._w, 'bind', widget._w) - - def unbind_widget(self, widget): - self.tk.call(self._w, 'unbind', widget._w) - - def post_widget(self, widget, x, y): - self.tk.call(self._w, 'post', widget._w, x, y) - -class ResizeHandle(TixWidget): - """Internal widget to draw resize handles on Scrolled widgets.""" - def __init__(self, master, cnf={}, **kw): - # There seems to be a Tix bug rejecting the configure method - # Let's try making the flags -static - flags = ['options', 'command', 'cursorfg', 'cursorbg', - 'handlesize', 'hintcolor', 'hintwidth', - 'x', 'y'] - # In fact, x y height width are configurable - TixWidget.__init__(self, master, 'tixResizeHandle', - flags, cnf, kw) - - def attach_widget(self, widget): - self.tk.call(self._w, 'attachwidget', widget._w) - - def detach_widget(self, widget): - self.tk.call(self._w, 'detachwidget', widget._w) - - def hide(self, widget): - self.tk.call(self._w, 'hide', widget._w) - - def show(self, widget): - self.tk.call(self._w, 'show', widget._w) - -class ScrolledHList(TixWidget): - """ScrolledHList - HList with automatic scrollbars.""" - - # FIXME: It should inherit -superclass tixScrolledWidget - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixScrolledHList', ['options'], - cnf, kw) - self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') - self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') - self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') - -class ScrolledListBox(TixWidget): - """ScrolledListBox - Listbox with automatic scrollbars.""" - - # FIXME: It should inherit -superclass tixScrolledWidget - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixScrolledListBox', ['options'], cnf, kw) - self.subwidget_list['listbox'] = _dummyListbox(self, 'listbox') - self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') - self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') - -class ScrolledText(TixWidget): - """ScrolledText - Text with automatic scrollbars.""" - - # FIXME: It should inherit -superclass tixScrolledWidget - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixScrolledText', ['options'], cnf, kw) - self.subwidget_list['text'] = _dummyText(self, 'text') - self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') - self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') - -class ScrolledTList(TixWidget): - """ScrolledTList - TList with automatic scrollbars.""" - - # FIXME: It should inherit -superclass tixScrolledWidget - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixScrolledTList', ['options'], - cnf, kw) - self.subwidget_list['tlist'] = _dummyTList(self, 'tlist') - self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') - self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') - -class ScrolledWindow(TixWidget): - """ScrolledWindow - Window with automatic scrollbars.""" - - # FIXME: It should inherit -superclass tixScrolledWidget - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixScrolledWindow', ['options'], cnf, kw) - self.subwidget_list['window'] = _dummyFrame(self, 'window') - self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') - self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') - -class Select(TixWidget): - """Select - Container of button subwidgets. It can be used to provide - radio-box or check-box style of selection options for the user. - - Subwidgets are buttons added dynamically using the add method.""" - - # FIXME: It should inherit -superclass tixLabelWidget - def __init__(self, master, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixSelect', - ['allowzero', 'radio', 'orientation', 'labelside', - 'options'], - cnf, kw) - self.subwidget_list['label'] = _dummyLabel(self, 'label') - - def add(self, name, cnf={}, **kw): - self.tk.call(self._w, 'add', name, *self._options(cnf, kw)) - self.subwidget_list[name] = _dummyButton(self, name) - return self.subwidget_list[name] - - def invoke(self, name): - self.tk.call(self._w, 'invoke', name) - -class Shell(TixWidget): - """Toplevel window. - - Subwidgets - None""" - - def __init__ (self,master=None,cnf={}, **kw): - TixWidget.__init__(self, master, 'tixShell', ['options', 'title'], cnf, kw) - -class DialogShell(TixWidget): - """Toplevel window, with popup popdown and center methods. - It tells the window manager that it is a dialog window and should be - treated specially. The exact treatment depends on the treatment of - the window manager. - - Subwidgets - None""" - - # FIXME: It should inherit from Shell - def __init__ (self,master=None,cnf={}, **kw): - TixWidget.__init__(self, master, - 'tixDialogShell', - ['options', 'title', 'mapped', - 'minheight', 'minwidth', - 'parent', 'transient'], cnf, kw) - - def popdown(self): - self.tk.call(self._w, 'popdown') - - def popup(self): - self.tk.call(self._w, 'popup') - - def center(self): - self.tk.call(self._w, 'center') - -class StdButtonBox(TixWidget): - """StdButtonBox - Standard Button Box (OK, Apply, Cancel and Help) """ - - def __init__(self, master=None, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixStdButtonBox', - ['orientation', 'options'], cnf, kw) - self.subwidget_list['ok'] = _dummyButton(self, 'ok') - self.subwidget_list['apply'] = _dummyButton(self, 'apply') - self.subwidget_list['cancel'] = _dummyButton(self, 'cancel') - self.subwidget_list['help'] = _dummyButton(self, 'help') - - def invoke(self, name): - if name in self.subwidget_list: - self.tk.call(self._w, 'invoke', name) - -class TList(TixWidget): - """TList - Hierarchy display widget which can be - used to display data in a tabular format. The list entries of a TList - widget are similar to the entries in the Tk listbox widget. The main - differences are (1) the TList widget can display the list entries in a - two dimensional format and (2) you can use graphical images as well as - multiple colors and fonts for the list entries. - - Subwidgets - None""" - - def __init__ (self,master=None,cnf={}, **kw): - TixWidget.__init__(self, master, 'tixTList', ['options'], cnf, kw) - - def active_set(self, index): - self.tk.call(self._w, 'active', 'set', index) - - def active_clear(self): - self.tk.call(self._w, 'active', 'clear') - - def anchor_set(self, index): - self.tk.call(self._w, 'anchor', 'set', index) - - def anchor_clear(self): - self.tk.call(self._w, 'anchor', 'clear') - - def delete(self, from_, to=None): - self.tk.call(self._w, 'delete', from_, to) - - def dragsite_set(self, index): - self.tk.call(self._w, 'dragsite', 'set', index) - - def dragsite_clear(self): - self.tk.call(self._w, 'dragsite', 'clear') - - def dropsite_set(self, index): - self.tk.call(self._w, 'dropsite', 'set', index) - - def dropsite_clear(self): - self.tk.call(self._w, 'dropsite', 'clear') - - def insert(self, index, cnf={}, **kw): - self.tk.call(self._w, 'insert', index, *self._options(cnf, kw)) - - def info_active(self): - return self.tk.call(self._w, 'info', 'active') - - def info_anchor(self): - return self.tk.call(self._w, 'info', 'anchor') - - def info_down(self, index): - return self.tk.call(self._w, 'info', 'down', index) - - def info_left(self, index): - return self.tk.call(self._w, 'info', 'left', index) - - def info_right(self, index): - return self.tk.call(self._w, 'info', 'right', index) - - def info_selection(self): - c = self.tk.call(self._w, 'info', 'selection') - return self.tk.splitlist(c) - - def info_size(self): - return self.tk.call(self._w, 'info', 'size') - - def info_up(self, index): - return self.tk.call(self._w, 'info', 'up', index) - - def nearest(self, x, y): - return self.tk.call(self._w, 'nearest', x, y) - - def see(self, index): - self.tk.call(self._w, 'see', index) - - def selection_clear(self, cnf={}, **kw): - self.tk.call(self._w, 'selection', 'clear', *self._options(cnf, kw)) - - def selection_includes(self, index): - return self.tk.call(self._w, 'selection', 'includes', index) - - def selection_set(self, first, last=None): - self.tk.call(self._w, 'selection', 'set', first, last) - - def xview(self, *args): - self.tk.call(self._w, 'xview', *args) - - def yview(self, *args): - self.tk.call(self._w, 'yview', *args) - -class Tree(TixWidget): - """Tree - The tixTree widget can be used to display hierachical - data in a tree form. The user can adjust - the view of the tree by opening or closing parts of the tree.""" - - # FIXME: It should inherit -superclass tixScrolledWidget - def __init__(self, master=None, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixTree', - ['options'], cnf, kw) - self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') - self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') - self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') - - def autosetmode(self): - '''This command calls the setmode method for all the entries in this - Tree widget: if an entry has no child entries, its mode is set to - none. Otherwise, if the entry has any hidden child entries, its mode is - set to open; otherwise its mode is set to close.''' - self.tk.call(self._w, 'autosetmode') - - def close(self, entrypath): - '''Close the entry given by entryPath if its mode is close.''' - self.tk.call(self._w, 'close', entrypath) - - def getmode(self, entrypath): - '''Returns the current mode of the entry given by entryPath.''' - return self.tk.call(self._w, 'getmode', entrypath) - - def open(self, entrypath): - '''Open the entry given by entryPath if its mode is open.''' - self.tk.call(self._w, 'open', entrypath) - - def setmode(self, entrypath, mode='none'): - '''This command is used to indicate whether the entry given by - entryPath has children entries and whether the children are visible. mode - must be one of open, close or none. If mode is set to open, a (+) - indicator is drawn next the the entry. If mode is set to close, a (-) - indicator is drawn next the the entry. If mode is set to none, no - indicators will be drawn for this entry. The default mode is none. The - open mode indicates the entry has hidden children and this entry can be - opened by the user. The close mode indicates that all the children of the - entry are now visible and the entry can be closed by the user.''' - self.tk.call(self._w, 'setmode', entrypath, mode) - - -# Could try subclassing Tree for CheckList - would need another arg to init -class CheckList(TixWidget): - """The CheckList widget - displays a list of items to be selected by the user. CheckList acts - similarly to the Tk checkbutton or radiobutton widgets, except it is - capable of handling many more items than checkbuttons or radiobuttons. - """ - # FIXME: It should inherit -superclass tixTree - def __init__(self, master=None, cnf={}, **kw): - TixWidget.__init__(self, master, 'tixCheckList', - ['options'], cnf, kw) - self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') - self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') - self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') - - def autosetmode(self): - '''This command calls the setmode method for all the entries in this - Tree widget: if an entry has no child entries, its mode is set to - none. Otherwise, if the entry has any hidden child entries, its mode is - set to open; otherwise its mode is set to close.''' - self.tk.call(self._w, 'autosetmode') - - def close(self, entrypath): - '''Close the entry given by entryPath if its mode is close.''' - self.tk.call(self._w, 'close', entrypath) - - def getmode(self, entrypath): - '''Returns the current mode of the entry given by entryPath.''' - return self.tk.call(self._w, 'getmode', entrypath) - - def open(self, entrypath): - '''Open the entry given by entryPath if its mode is open.''' - self.tk.call(self._w, 'open', entrypath) - - def getselection(self, mode='on'): - '''Returns a list of items whose status matches status. If status is - not specified, the list of items in the "on" status will be returned. - Mode can be on, off, default''' - c = self.tk.split(self.tk.call(self._w, 'getselection', mode)) - return self.tk.splitlist(c) - - def getstatus(self, entrypath): - '''Returns the current status of entryPath.''' - return self.tk.call(self._w, 'getstatus', entrypath) - - def setstatus(self, entrypath, mode='on'): - '''Sets the status of entryPath to be status. A bitmap will be - displayed next to the entry its status is on, off or default.''' - self.tk.call(self._w, 'setstatus', entrypath, mode) - - -########################################################################### -### The subclassing below is used to instantiate the subwidgets in each ### -### mega widget. This allows us to access their methods directly. ### -########################################################################### - -class _dummyButton(Button, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - -class _dummyCheckbutton(Checkbutton, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - -class _dummyEntry(Entry, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - -class _dummyFrame(Frame, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - -class _dummyLabel(Label, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - -class _dummyListbox(Listbox, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - -class _dummyMenu(Menu, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - -class _dummyMenubutton(Menubutton, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - -class _dummyScrollbar(Scrollbar, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - -class _dummyText(Text, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - -class _dummyScrolledListBox(ScrolledListBox, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - self.subwidget_list['listbox'] = _dummyListbox(self, 'listbox') - self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') - self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') - -class _dummyHList(HList, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - -class _dummyScrolledHList(ScrolledHList, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') - self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') - self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') - -class _dummyTList(TList, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - -class _dummyComboBox(ComboBox, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, ['fancy',destroy_physically]) - self.subwidget_list['label'] = _dummyLabel(self, 'label') - self.subwidget_list['entry'] = _dummyEntry(self, 'entry') - self.subwidget_list['arrow'] = _dummyButton(self, 'arrow') - - self.subwidget_list['slistbox'] = _dummyScrolledListBox(self, - 'slistbox') - try: - self.subwidget_list['tick'] = _dummyButton(self, 'tick') - #cross Button : present if created with the fancy option - self.subwidget_list['cross'] = _dummyButton(self, 'cross') - except TypeError: - # unavailable when -fancy not specified - pass - -class _dummyDirList(DirList, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - self.subwidget_list['hlist'] = _dummyHList(self, 'hlist') - self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb') - self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb') - -class _dummyDirSelectBox(DirSelectBox, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist') - self.subwidget_list['dircbx'] = _dummyFileComboBox(self, 'dircbx') - -class _dummyExFileSelectBox(ExFileSelectBox, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - self.subwidget_list['cancel'] = _dummyButton(self, 'cancel') - self.subwidget_list['ok'] = _dummyButton(self, 'ok') - self.subwidget_list['hidden'] = _dummyCheckbutton(self, 'hidden') - self.subwidget_list['types'] = _dummyComboBox(self, 'types') - self.subwidget_list['dir'] = _dummyComboBox(self, 'dir') - self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist') - self.subwidget_list['file'] = _dummyComboBox(self, 'file') - self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist') - -class _dummyFileSelectBox(FileSelectBox, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist') - self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist') - self.subwidget_list['filter'] = _dummyComboBox(self, 'filter') - self.subwidget_list['selection'] = _dummyComboBox(self, 'selection') - -class _dummyFileComboBox(ComboBox, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - self.subwidget_list['dircbx'] = _dummyComboBox(self, 'dircbx') - -class _dummyStdButtonBox(StdButtonBox, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - self.subwidget_list['ok'] = _dummyButton(self, 'ok') - self.subwidget_list['apply'] = _dummyButton(self, 'apply') - self.subwidget_list['cancel'] = _dummyButton(self, 'cancel') - self.subwidget_list['help'] = _dummyButton(self, 'help') - -class _dummyNoteBookFrame(NoteBookFrame, TixSubWidget): - def __init__(self, master, name, destroy_physically=0): - TixSubWidget.__init__(self, master, name, destroy_physically) - -class _dummyPanedWindow(PanedWindow, TixSubWidget): - def __init__(self, master, name, destroy_physically=1): - TixSubWidget.__init__(self, master, name, destroy_physically) - -######################## -### Utility Routines ### -######################## - -#mike Should tixDestroy be exposed as a wrapper? - but not for widgets. - -def OptionName(widget): - '''Returns the qualified path name for the widget. Normally used to set - default options for subwidgets. See tixwidgets.py''' - return widget.tk.call('tixOptionName', widget._w) - -# Called with a dictionary argument of the form -# {'*.c':'C source files', '*.txt':'Text Files', '*':'All files'} -# returns a string which can be used to configure the fsbox file types -# in an ExFileSelectBox. i.e., -# '{{*} {* - All files}} {{*.c} {*.c - C source files}} {{*.txt} {*.txt - Text Files}}' -def FileTypeList(dict): - s = '' - for type in dict.keys(): - s = s + '{{' + type + '} {' + type + ' - ' + dict[type] + '}} ' - return s - -# Still to be done: -# tixIconView -class CObjView(TixWidget): - """This file implements the Canvas Object View widget. This is a base - class of IconView. It implements automatic placement/adjustment of the - scrollbars according to the canvas objects inside the canvas subwidget. - The scrollbars are adjusted so that the canvas is just large enough - to see all the objects. - """ - # FIXME: It should inherit -superclass tixScrolledWidget - pass - - -class Grid(TixWidget): - '''The Tix Grid command creates a new window and makes it into a - tixGrid widget. Additional options, may be specified on the command - line or in the option database to configure aspects such as its cursor - and relief. - - A Grid widget displays its contents in a two dimensional grid of cells. - Each cell may contain one Tix display item, which may be in text, - graphics or other formats. See the DisplayStyle class for more information - about Tix display items. Individual cells, or groups of cells, can be - formatted with a wide range of attributes, such as its color, relief and - border. - - Subwidgets - None''' - # valid specific resources as of Tk 8.4 - # editdonecmd, editnotifycmd, floatingcols, floatingrows, formatcmd, - # highlightbackground, highlightcolor, leftmargin, itemtype, selectmode, - # selectunit, topmargin, - def __init__(self, master=None, cnf={}, **kw): - static= [] - self.cnf= cnf - TixWidget.__init__(self, master, 'tixGrid', static, cnf, kw) - - # valid options as of Tk 8.4 - # anchor, bdtype, cget, configure, delete, dragsite, dropsite, entrycget, edit - # entryconfigure, format, geometryinfo, info, index, move, nearest, selection - # set, size, unset, xview, yview - # def anchor option ?args ...? - def anchor_get(self): - "Get the (x,y) coordinate of the current anchor cell" - return self._getints(self.tk.call(self, 'anchor', 'get')) - - # def bdtype - # def delete dim from ?to? - def delete_row(self, from_, to=None): - """Delete rows between from_ and to inclusive. - If to is not provided, delete only row at from_""" - if to is None: - self.tk.call(self, 'delete', 'row', from_) - else: - self.tk.call(self, 'delete', 'row', from_, to) - def delete_column(self, from_, to=None): - """Delete columns between from_ and to inclusive. - If to is not provided, delete only column at from_""" - if to is None: - self.tk.call(self, 'delete', 'column', from_) - else: - self.tk.call(self, 'delete', 'column', from_, to) - # def edit apply - # def edit set x y - - def entrycget(self, x, y, option): - "Get the option value for cell at (x,y)" - return self.tk.call(self, 'entrycget', x, y, option) - - def entryconfigure(self, x, y, **kw): - return self.tk.call(self, 'entryconfigure', x, y, *self._options(None, kw)) - # def format - # def index - - def info_exists(self, x, y): - "Return True if display item exists at (x,y)" - return bool(int(self.tk.call(self, 'info', 'exists', x, y))) - - def info_bbox(self, x, y): - # This seems to always return '', at least for 'text' displayitems - return self.tk.call(self, 'info', 'bbox', x, y) - - def nearest(self, x, y): - "Return coordinate of cell nearest pixel coordinate (x,y)" - return self._getints(self.tk.call(self, 'nearest', x, y)) - - # def selection adjust - # def selection clear - # def selection includes - # def selection set - # def selection toggle - # def move dim from to offset - - def set(self, x, y, itemtype=None, **kw): - args= self._options(self.cnf, kw) - if itemtype is not None: - args= ('-itemtype', itemtype) + args - self.tk.call(self, 'set', x, y, *args) - - # def size dim index ?option value ...? - # def unset x y - - def xview(self): - return self._getdoubles(self.tk.call(self, 'xview')) - def xview_moveto(self, fraction): - self.tk.call(self,'xview', 'moveto', fraction) - def xview_scroll(self, count, what="units"): - "Scroll right (count>0) or left of units|pages" - self.tk.call(self, 'xview', 'scroll', count, what) - - def yview(self): - return self._getdoubles(self.tk.call(self, 'yview')) - def yview_moveto(self, fraction): - self.tk.call(self,'ysview', 'moveto', fraction) - def yview_scroll(self, count, what="units"): - "Scroll down (count>0) or up of units|pages" - self.tk.call(self, 'yview', 'scroll', count, what) - -class ScrolledGrid(Grid): - '''Scrolled Grid widgets''' - - # FIXME: It should inherit -superclass tixScrolledWidget - def __init__(self, master=None, cnf={}, **kw): - static= [] - self.cnf= cnf - TixWidget.__init__(self, master, 'tixScrolledGrid', static, cnf, kw) Index: Lib/lib-tk/Tkdnd.py =================================================================== --- Lib/lib-tk/Tkdnd.py (revision 63074) +++ Lib/lib-tk/Tkdnd.py (working copy) @@ -1,321 +0,0 @@ -"""Drag-and-drop support for Tkinter. - -This is very preliminary. I currently only support dnd *within* one -application, between different windows (or within the same window). - -I an trying to make this as generic as possible -- not dependent on -the use of a particular widget or icon type, etc. I also hope that -this will work with Pmw. - -To enable an object to be dragged, you must create an event binding -for it that starts the drag-and-drop process. Typically, you should -bind to a callback function that you write. The function -should call Tkdnd.dnd_start(source, event), where 'source' is the -object to be dragged, and 'event' is the event that invoked the call -(the argument to your callback function). Even though this is a class -instantiation, the returned instance should not be stored -- it will -be kept alive automatically for the duration of the drag-and-drop. - -When a drag-and-drop is already in process for the Tk interpreter, the -call is *ignored*; this normally averts starting multiple simultaneous -dnd processes, e.g. because different button callbacks all -dnd_start(). - -The object is *not* necessarily a widget -- it can be any -application-specific object that is meaningful to potential -drag-and-drop targets. - -Potential drag-and-drop targets are discovered as follows. Whenever -the mouse moves, and at the start and end of a drag-and-drop move, the -Tk widget directly under the mouse is inspected. This is the target -widget (not to be confused with the target object, yet to be -determined). If there is no target widget, there is no dnd target -object. If there is a target widget, and it has an attribute -dnd_accept, this should be a function (or any callable object). The -function is called as dnd_accept(source, event), where 'source' is the -object being dragged (the object passed to dnd_start() above), and -'event' is the most recent event object (generally a event; -it can also be or ). If the dnd_accept() -function returns something other than None, this is the new dnd target -object. If dnd_accept() returns None, or if the target widget has no -dnd_accept attribute, the target widget's parent is considered as the -target widget, and the search for a target object is repeated from -there. If necessary, the search is repeated all the way up to the -root widget. If none of the target widgets can produce a target -object, there is no target object (the target object is None). - -The target object thus produced, if any, is called the new target -object. It is compared with the old target object (or None, if there -was no old target widget). There are several cases ('source' is the -source object, and 'event' is the most recent event object): - -- Both the old and new target objects are None. Nothing happens. - -- The old and new target objects are the same object. Its method -dnd_motion(source, event) is called. - -- The old target object was None, and the new target object is not -None. The new target object's method dnd_enter(source, event) is -called. - -- The new target object is None, and the old target object is not -None. The old target object's method dnd_leave(source, event) is -called. - -- The old and new target objects differ and neither is None. The old -target object's method dnd_leave(source, event), and then the new -target object's method dnd_enter(source, event) is called. - -Once this is done, the new target object replaces the old one, and the -Tk mainloop proceeds. The return value of the methods mentioned above -is ignored; if they raise an exception, the normal exception handling -mechanisms take over. - -The drag-and-drop processes can end in two ways: a final target object -is selected, or no final target object is selected. When a final -target object is selected, it will always have been notified of the -potential drop by a call to its dnd_enter() method, as described -above, and possibly one or more calls to its dnd_motion() method; its -dnd_leave() method has not been called since the last call to -dnd_enter(). The target is notified of the drop by a call to its -method dnd_commit(source, event). - -If no final target object is selected, and there was an old target -object, its dnd_leave(source, event) method is called to complete the -dnd sequence. - -Finally, the source object is notified that the drag-and-drop process -is over, by a call to source.dnd_end(target, event), specifying either -the selected target object, or None if no target object was selected. -The source object can use this to implement the commit action; this is -sometimes simpler than to do it in the target's dnd_commit(). The -target's dnd_commit() method could then simply be aliased to -dnd_leave(). - -At any time during a dnd sequence, the application can cancel the -sequence by calling the cancel() method on the object returned by -dnd_start(). This will call dnd_leave() if a target is currently -active; it will never call dnd_commit(). - -""" - - -import Tkinter - - -# The factory function - -def dnd_start(source, event): - h = DndHandler(source, event) - if h.root: - return h - else: - return None - - -# The class that does the work - -class DndHandler: - - root = None - - def __init__(self, source, event): - if event.num > 5: - return - root = event.widget._root() - try: - root.__dnd - return # Don't start recursive dnd - except AttributeError: - root.__dnd = self - self.root = root - self.source = source - self.target = None - self.initial_button = button = event.num - self.initial_widget = widget = event.widget - self.release_pattern = "" % (button, button) - self.save_cursor = widget['cursor'] or "" - widget.bind(self.release_pattern, self.on_release) - widget.bind("", self.on_motion) - widget['cursor'] = "hand2" - - def __del__(self): - root = self.root - self.root = None - if root: - try: - del root.__dnd - except AttributeError: - pass - - def on_motion(self, event): - x, y = event.x_root, event.y_root - target_widget = self.initial_widget.winfo_containing(x, y) - source = self.source - new_target = None - while target_widget: - try: - attr = target_widget.dnd_accept - except AttributeError: - pass - else: - new_target = attr(source, event) - if new_target: - break - target_widget = target_widget.master - old_target = self.target - if old_target is new_target: - if old_target: - old_target.dnd_motion(source, event) - else: - if old_target: - self.target = None - old_target.dnd_leave(source, event) - if new_target: - new_target.dnd_enter(source, event) - self.target = new_target - - def on_release(self, event): - self.finish(event, 1) - - def cancel(self, event=None): - self.finish(event, 0) - - def finish(self, event, commit=0): - target = self.target - source = self.source - widget = self.initial_widget - root = self.root - try: - del root.__dnd - self.initial_widget.unbind(self.release_pattern) - self.initial_widget.unbind("") - widget['cursor'] = self.save_cursor - self.target = self.source = self.initial_widget = self.root = None - if target: - if commit: - target.dnd_commit(source, event) - else: - target.dnd_leave(source, event) - finally: - source.dnd_end(target, event) - - - -# ---------------------------------------------------------------------- -# The rest is here for testing and demonstration purposes only! - -class Icon: - - def __init__(self, name): - self.name = name - self.canvas = self.label = self.id = None - - def attach(self, canvas, x=10, y=10): - if canvas is self.canvas: - self.canvas.coords(self.id, x, y) - return - if self.canvas: - self.detach() - if not canvas: - return - label = Tkinter.Label(canvas, text=self.name, - borderwidth=2, relief="raised") - id = canvas.create_window(x, y, window=label, anchor="nw") - self.canvas = canvas - self.label = label - self.id = id - label.bind("", self.press) - - def detach(self): - canvas = self.canvas - if not canvas: - return - id = self.id - label = self.label - self.canvas = self.label = self.id = None - canvas.delete(id) - label.destroy() - - def press(self, event): - if dnd_start(self, event): - # where the pointer is relative to the label widget: - self.x_off = event.x - self.y_off = event.y - # where the widget is relative to the canvas: - self.x_orig, self.y_orig = self.canvas.coords(self.id) - - def move(self, event): - x, y = self.where(self.canvas, event) - self.canvas.coords(self.id, x, y) - - def putback(self): - self.canvas.coords(self.id, self.x_orig, self.y_orig) - - def where(self, canvas, event): - # where the corner of the canvas is relative to the screen: - x_org = canvas.winfo_rootx() - y_org = canvas.winfo_rooty() - # where the pointer is relative to the canvas widget: - x = event.x_root - x_org - y = event.y_root - y_org - # compensate for initial pointer offset - return x - self.x_off, y - self.y_off - - def dnd_end(self, target, event): - pass - -class Tester: - - def __init__(self, root): - self.top = Tkinter.Toplevel(root) - self.canvas = Tkinter.Canvas(self.top, width=100, height=100) - self.canvas.pack(fill="both", expand=1) - self.canvas.dnd_accept = self.dnd_accept - - def dnd_accept(self, source, event): - return self - - def dnd_enter(self, source, event): - self.canvas.focus_set() # Show highlight border - x, y = source.where(self.canvas, event) - x1, y1, x2, y2 = source.canvas.bbox(source.id) - dx, dy = x2-x1, y2-y1 - self.dndid = self.canvas.create_rectangle(x, y, x+dx, y+dy) - self.dnd_motion(source, event) - - def dnd_motion(self, source, event): - x, y = source.where(self.canvas, event) - x1, y1, x2, y2 = self.canvas.bbox(self.dndid) - self.canvas.move(self.dndid, x-x1, y-y1) - - def dnd_leave(self, source, event): - self.top.focus_set() # Hide highlight border - self.canvas.delete(self.dndid) - self.dndid = None - - def dnd_commit(self, source, event): - self.dnd_leave(source, event) - x, y = source.where(self.canvas, event) - source.attach(self.canvas, x, y) - -def test(): - root = Tkinter.Tk() - root.geometry("+1+1") - Tkinter.Button(command=root.quit, text="Quit").pack() - t1 = Tester(root) - t1.top.geometry("+1+60") - t2 = Tester(root) - t2.top.geometry("+120+60") - t3 = Tester(root) - t3.top.geometry("+240+60") - i1 = Icon("ICON1") - i2 = Icon("ICON2") - i3 = Icon("ICON3") - i1.attach(t1.canvas) - i2.attach(t2.canvas) - i3.attach(t3.canvas) - root.mainloop() - -if __name__ == '__main__': - test() Index: Lib/lib-tk/tkFont.py =================================================================== --- Lib/lib-tk/tkFont.py (revision 63074) +++ Lib/lib-tk/tkFont.py (working copy) @@ -1,216 +0,0 @@ -# Tkinter font wrapper -# -# written by Fredrik Lundh, February 1998 -# -# FIXME: should add 'displayof' option where relevant (actual, families, -# measure, and metrics) -# - -__version__ = "0.9" - -import Tkinter - -# weight/slant -NORMAL = "normal" -ROMAN = "roman" -BOLD = "bold" -ITALIC = "italic" - -def nametofont(name): - """Given the name of a tk named font, returns a Font representation. - """ - return Font(name=name, exists=True) - -class Font: - - """Represents a named font. - - Constructor options are: - - font -- font specifier (name, system font, or (family, size, style)-tuple) - name -- name to use for this font configuration (defaults to a unique name) - exists -- does a named font by this name already exist? - Creates a new named font if False, points to the existing font if True. - Raises _tkinter.TclError if the assertion is false. - - the following are ignored if font is specified: - - family -- font 'family', e.g. Courier, Times, Helvetica - size -- font size in points - weight -- font thickness: NORMAL, BOLD - slant -- font slant: ROMAN, ITALIC - underline -- font underlining: false (0), true (1) - overstrike -- font strikeout: false (0), true (1) - - """ - - def _set(self, kw): - options = [] - for k, v in kw.items(): - options.append("-"+k) - options.append(str(v)) - return tuple(options) - - def _get(self, args): - options = [] - for k in args: - options.append("-"+k) - return tuple(options) - - def _mkdict(self, args): - options = {} - for i in range(0, len(args), 2): - options[args[i][1:]] = args[i+1] - return options - - def __init__(self, root=None, font=None, name=None, exists=False, **options): - if not root: - root = Tkinter._default_root - if font: - # get actual settings corresponding to the given font - font = root.tk.splitlist(root.tk.call("font", "actual", font)) - else: - font = self._set(options) - if not name: - name = "font" + str(id(self)) - self.name = name - - if exists: - self.delete_font = False - # confirm font exists - if self.name not in root.tk.call("font", "names"): - raise Tkinter._tkinter.TclError("named font %s does not already exist" % (self.name,)) - # if font config info supplied, apply it - if font: - root.tk.call("font", "configure", self.name, *font) - else: - # create new font (raises TclError if the font exists) - root.tk.call("font", "create", self.name, *font) - self.delete_font = True - # backlinks! - self._root = root - self._split = root.tk.splitlist - self._call = root.tk.call - - def __str__(self): - return self.name - - def __eq__(self, other): - return self.name == other.name and isinstance(other, Font) - - def __getitem__(self, key): - return self.cget(key) - - def __setitem__(self, key, value): - self.configure(**{key: value}) - - def __del__(self): - try: - if self.delete_font: - self._call("font", "delete", self.name) - except (KeyboardInterrupt, SystemExit): - raise - except Exception: - pass - - def copy(self): - "Return a distinct copy of the current font" - return Font(self._root, **self.actual()) - - def actual(self, option=None): - "Return actual font attributes" - if option: - return self._call("font", "actual", self.name, "-"+option) - else: - return self._mkdict( - self._split(self._call("font", "actual", self.name)) - ) - - def cget(self, option): - "Get font attribute" - return self._call("font", "config", self.name, "-"+option) - - def config(self, **options): - "Modify font attributes" - if options: - self._call("font", "config", self.name, - *self._set(options)) - else: - return self._mkdict( - self._split(self._call("font", "config", self.name)) - ) - - configure = config - - def measure(self, text): - "Return text width" - return int(self._call("font", "measure", self.name, text)) - - def metrics(self, *options): - """Return font metrics. - - For best performance, create a dummy widget - using this font before calling this method.""" - - if options: - return int( - self._call("font", "metrics", self.name, self._get(options)) - ) - else: - res = self._split(self._call("font", "metrics", self.name)) - options = {} - for i in range(0, len(res), 2): - options[res[i][1:]] = int(res[i+1]) - return options - -def families(root=None): - "Get font families (as a tuple)" - if not root: - root = Tkinter._default_root - return root.tk.splitlist(root.tk.call("font", "families")) - -def names(root=None): - "Get names of defined fonts (as a tuple)" - if not root: - root = Tkinter._default_root - return root.tk.splitlist(root.tk.call("font", "names")) - -# -------------------------------------------------------------------- -# test stuff - -if __name__ == "__main__": - - root = Tkinter.Tk() - - # create a font - f = Font(family="times", size=30, weight=NORMAL) - - print(f.actual()) - print(f.actual("family")) - print(f.actual("weight")) - - print(f.config()) - print(f.cget("family")) - print(f.cget("weight")) - - print(names()) - - print(f.measure("hello"), f.metrics("linespace")) - - print(f.metrics()) - - f = Font(font=("Courier", 20, "bold")) - print(f.measure("hello"), f.metrics("linespace")) - - w = Tkinter.Label(root, text="Hello, world", font=f) - w.pack() - - w = Tkinter.Button(root, text="Quit!", command=root.destroy) - w.pack() - - fb = Font(font=w["font"]).copy() - fb.config(weight=BOLD) - - w.config(font=fb) - - Tkinter.mainloop() Index: Lib/lib-tk/tkCommonDialog.py =================================================================== --- Lib/lib-tk/tkCommonDialog.py (revision 63074) +++ Lib/lib-tk/tkCommonDialog.py (working copy) @@ -1,60 +0,0 @@ -# base class for tk common dialogues -# -# this module provides a base class for accessing the common -# dialogues available in Tk 4.2 and newer. use tkFileDialog, -# tkColorChooser, and tkMessageBox to access the individual -# dialogs. -# -# written by Fredrik Lundh, May 1997 -# - -from Tkinter import * - -class Dialog: - - command = None - - def __init__(self, master=None, **options): - - # FIXME: should this be placed on the module level instead? - if TkVersion < 4.2: - raise TclError("this module requires Tk 4.2 or newer") - - self.master = master - self.options = options - if not master and options.get('parent'): - self.master = options['parent'] - - def _fixoptions(self): - pass # hook - - def _fixresult(self, widget, result): - return result # hook - - def show(self, **options): - - # update instance options - for k, v in options.items(): - self.options[k] = v - - self._fixoptions() - - # we need a dummy widget to properly process the options - # (at least as long as we use Tkinter 1.63) - w = Frame(self.master) - - try: - - s = w.tk.call(self.command, *w._options(self.options)) - - s = self._fixresult(w, s) - - finally: - - try: - # get rid of the widget - w.destroy() - except: - pass - - return s Index: Lib/lib-tk/tkSimpleDialog.py =================================================================== --- Lib/lib-tk/tkSimpleDialog.py (revision 63074) +++ Lib/lib-tk/tkSimpleDialog.py (working copy) @@ -1,319 +0,0 @@ -# -# An Introduction to Tkinter -# tkSimpleDialog.py -# -# Copyright (c) 1997 by Fredrik Lundh -# -# fredrik@pythonware.com -# http://www.pythonware.com -# - -# -------------------------------------------------------------------- -# dialog base class - -'''Dialog boxes - -This module handles dialog boxes. It contains the following -public symbols: - -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 -''' - -from Tkinter import * - -class Dialog(Toplevel): - - '''Class to open dialogs. - - This class is intended as a base class for custom dialogs - ''' - - def __init__(self, parent, title = None): - - '''Initialize a dialog. - - Arguments: - - parent -- a parent window (the application window) - - title -- the dialog title - ''' - Toplevel.__init__(self, parent) - - # If the master is not viewable, don't - # make the child transient, or else it - # would be opened withdrawn - if parent.winfo_viewable(): - self.transient(parent) - - if title: - self.title(title) - - self.parent = parent - - self.result = None - - body = Frame(self) - self.initial_focus = self.body(body) - body.pack(padx=5, pady=5) - - self.buttonbox() - - self.wait_visibility() # window needs to be visible for the grab - self.grab_set() - - if not self.initial_focus: - self.initial_focus = self - - self.protocol("WM_DELETE_WINDOW", self.cancel) - - if self.parent is not None: - self.geometry("+%d+%d" % (parent.winfo_rootx()+50, - parent.winfo_rooty()+50)) - - self.initial_focus.focus_set() - - self.wait_window(self) - - def destroy(self): - '''Destroy the window''' - self.initial_focus = None - Toplevel.destroy(self) - - # - # construction hooks - - def body(self, master): - '''create dialog body. - - return widget that should have initial focus. - This method should be overridden, and is called - by the __init__ method. - ''' - pass - - def buttonbox(self): - '''add standard button box. - - override if you do not want the standard buttons - ''' - - 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("", self.ok) - self.bind("", self.cancel) - - box.pack() - - # - # standard button semantics - - def ok(self, event=None): - - if not self.validate(): - self.initial_focus.focus_set() # put focus back - return - - self.withdraw() - self.update_idletasks() - - try: - self.apply() - finally: - self.cancel() - - def cancel(self, event=None): - - # put focus back to the parent window - if self.parent is not None: - self.parent.focus_set() - self.destroy() - - # - # command hooks - - def validate(self): - '''validate the data - - This method is called automatically to validate the data before the - dialog is destroyed. By default, it always validates OK. - ''' - - return 1 # override - - def apply(self): - '''process the data - - This method is called automatically to process the data, *after* - the dialog is destroyed. By default, it does nothing. - ''' - - pass # override - - -# -------------------------------------------------------------------- -# convenience dialogues - -class _QueryDialog(Dialog): - - def __init__(self, title, prompt, - initialvalue=None, - minvalue = None, maxvalue = None, - parent = None): - - if not parent: - import Tkinter - parent = Tkinter._default_root - - 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: - self.entry.insert(0, self.initialvalue) - self.entry.select_range(0, END) - - return self.entry - - def validate(self): - - import tkMessageBox - - try: - result = self.getresult() - except ValueError: - tkMessageBox.showwarning( - "Illegal value", - self.errormessage + "\nPlease try again", - parent = self - ) - return 0 - - if self.minvalue is not None and result < self.minvalue: - tkMessageBox.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: - tkMessageBox.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 int(self.entry.get()) - -def askinteger(title, prompt, **kw): - '''get an integer from the user - - Arguments: - - title -- the dialog title - prompt -- the label text - **kw -- see SimpleDialog class - - Return value is an integer - ''' - d = _QueryInteger(title, prompt, **kw) - return d.result - -class _QueryFloat(_QueryDialog): - errormessage = "Not a floating point value." - def getresult(self): - return float(self.entry.get()) - -def askfloat(title, prompt, **kw): - '''get a float from the user - - Arguments: - - title -- the dialog title - prompt -- the label text - **kw -- see SimpleDialog class - - Return value is a float - ''' - 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): - '''get a string from the user - - Arguments: - - title -- the dialog title - prompt -- the label text - **kw -- see SimpleDialog class - - Return value is a string - ''' - d = _QueryString(title, prompt, **kw) - return d.result - -if __name__ == "__main__": - - root = Tk() - root.update() - - 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")) Index: Lib/lib-tk/SimpleDialog.py =================================================================== --- Lib/lib-tk/SimpleDialog.py (revision 63074) +++ Lib/lib-tk/SimpleDialog.py (working copy) @@ -1,112 +0,0 @@ -"""A simple but flexible modal dialog box.""" - - -from Tkinter import * - - -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) - 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('', 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._set_transient(master) - - def _set_transient(self, master, relx=0.5, rely=0.3): - widget = self.root - widget.withdraw() # Remain invisible while we figure out the geometry - widget.transient(master) - widget.update_idletasks() # Actualize geometry information - if master.winfo_ismapped(): - m_width = master.winfo_width() - m_height = master.winfo_height() - m_x = master.winfo_rootx() - m_y = master.winfo_rooty() - else: - m_width = master.winfo_screenwidth() - m_height = master.winfo_screenheight() - m_x = m_y = 0 - w_width = widget.winfo_reqwidth() - w_height = widget.winfo_reqheight() - x = m_x + (m_width - w_width) * relx - y = m_y + (m_height - w_height) * rely - if x+w_width > master.winfo_screenwidth(): - x = master.winfo_screenwidth() - w_width - elif x < 0: - x = 0 - if y+w_height > master.winfo_screenheight(): - y = master.winfo_screenheight() - w_height - elif y < 0: - y = 0 - widget.geometry("+%d+%d" % (x, y)) - widget.deiconify() # Become visible at the desired location - - 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() - - -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()) - t = Button(root, text='Test', command=doit) - t.pack() - q = Button(root, text='Quit', command=t.quit) - q.pack() - t.mainloop() - - test() Index: Lib/lib-tk/Tkconstants.py =================================================================== --- Lib/lib-tk/Tkconstants.py (revision 63074) +++ Lib/lib-tk/Tkconstants.py (working copy) @@ -1,110 +0,0 @@ -# Symbolic constants for Tk - -# Booleans -NO=FALSE=OFF=0 -YES=TRUE=ON=1 - -# -anchor and -sticky -N='n' -S='s' -W='w' -E='e' -NW='nw' -SW='sw' -NE='ne' -SE='se' -NS='ns' -EW='ew' -NSEW='nsew' -CENTER='center' - -# -fill -NONE='none' -X='x' -Y='y' -BOTH='both' - -# -side -LEFT='left' -TOP='top' -RIGHT='right' -BOTTOM='bottom' - -# -relief -RAISED='raised' -SUNKEN='sunken' -FLAT='flat' -RIDGE='ridge' -GROOVE='groove' -SOLID = 'solid' - -# -orient -HORIZONTAL='horizontal' -VERTICAL='vertical' - -# -tabs -NUMERIC='numeric' - -# -wrap -CHAR='char' -WORD='word' - -# -align -BASELINE='baseline' - -# -bordermode -INSIDE='inside' -OUTSIDE='outside' - -# Special tags, marks and insert positions -SEL='sel' -SEL_FIRST='sel.first' -SEL_LAST='sel.last' -END='end' -INSERT='insert' -CURRENT='current' -ANCHOR='anchor' -ALL='all' # e.g. Canvas.delete(ALL) - -# Text widget and button states -NORMAL='normal' -DISABLED='disabled' -ACTIVE='active' -# Canvas state -HIDDEN='hidden' - -# Menu item types -CASCADE='cascade' -CHECKBUTTON='checkbutton' -COMMAND='command' -RADIOBUTTON='radiobutton' -SEPARATOR='separator' - -# Selection modes for list boxes -SINGLE='single' -BROWSE='browse' -MULTIPLE='multiple' -EXTENDED='extended' - -# Activestyle for list boxes -# NONE='none' is also valid -DOTBOX='dotbox' -UNDERLINE='underline' - -# Various canvas styles -PIESLICE='pieslice' -CHORD='chord' -ARC='arc' -FIRST='first' -LAST='last' -BUTT='butt' -PROJECTING='projecting' -ROUND='round' -BEVEL='bevel' -MITER='miter' - -# Arguments to xview/yview -MOVETO='moveto' -SCROLL='scroll' -UNITS='units' -PAGES='pages' Index: Lib/lib-tk/ScrolledText.py =================================================================== --- Lib/lib-tk/ScrolledText.py (revision 63074) +++ Lib/lib-tk/ScrolledText.py (working copy) @@ -1,43 +0,0 @@ -# A ScrolledText widget feels like a text widget but also has a -# vertical scroll bar on its right. (Later, options may be added to -# add a horizontal bar as well, to make the bars disappear -# automatically when not needed, to move them to the other side of the -# window, etc.) -# -# Configuration options are passed to the Text widget. -# A Frame widget is inserted between the master and the text, to hold -# the Scrollbar widget. -# Most methods calls are inherited from the Text widget; Pack methods -# are redirected to the Frame widget however. - -from Tkinter import * -from Tkinter import _cnfmerge - -class ScrolledText(Text): - def __init__(self, master=None, cnf=None, **kw): - if cnf is None: - cnf = {} - if kw: - cnf = _cnfmerge((cnf, kw)) - fcnf = {} - for k in cnf.keys(): - if isinstance(k, type) or k == 'name': - fcnf[k] = cnf[k] - del cnf[k] - self.frame = Frame(master, **fcnf) - self.vbar = Scrollbar(self.frame, name='vbar') - self.vbar.pack(side=RIGHT, fill=Y) - cnf['name'] = 'text' - Text.__init__(self, self.frame, **cnf) - self.pack(side=LEFT, fill=BOTH, expand=1) - self['yscrollcommand'] = self.vbar.set - self.vbar['command'] = self.yview - - # Copy geometry methods of self.frame -- hack! - methods = Pack.__dict__.keys() - methods = methods + Grid.__dict__.keys() - methods = methods + Place.__dict__.keys() - - for m in methods: - if m[0] != '_' and m != 'config' and m != 'configure': - setattr(self, m, getattr(self.frame, m)) Index: Lib/lib-tk/turtle.py =================================================================== --- Lib/lib-tk/turtle.py (revision 63074) +++ Lib/lib-tk/turtle.py (working copy) @@ -1,956 +0,0 @@ -# LogoMation-like turtle graphics - -""" -Turtle graphics is a popular way for introducing programming to -kids. It was part of the original Logo programming language developed -by Wally Feurzeig and Seymour Papert in 1966. - -Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it -the command turtle.forward(15), and it moves (on-screen!) 15 pixels in -the direction it is facing, drawing a line as it moves. Give it the -command turtle.left(25), and it rotates in-place 25 degrees clockwise. - -By combining together these and similar commands, intricate shapes and -pictures can easily be drawn. -""" - -from math import * # Also for export -from time import sleep -import Tkinter - -speeds = ['fastest', 'fast', 'normal', 'slow', 'slowest'] - -class Error(Exception): - pass - -class RawPen: - - def __init__(self, canvas): - self._canvas = canvas - self._items = [] - self._tracing = 1 - self._arrow = 0 - self._delay = 10 # default delay for drawing - self._angle = 0.0 - self.degrees() - self.reset() - - def degrees(self, fullcircle=360.0): - """ Set angle measurement units to degrees. - - Example: - >>> turtle.degrees() - """ - # Don't try to change _angle if it is 0, because - # _fullcircle might not be set, yet - if self._angle: - self._angle = (self._angle / self._fullcircle) * fullcircle - self._fullcircle = fullcircle - self._invradian = pi / (fullcircle * 0.5) - - def radians(self): - """ Set the angle measurement units to radians. - - Example: - >>> turtle.radians() - """ - self.degrees(2.0*pi) - - def reset(self): - """ Clear the screen, re-center the pen, and set variables to - the default values. - - Example: - >>> turtle.position() - [0.0, -22.0] - >>> turtle.heading() - 100.0 - >>> turtle.reset() - >>> turtle.position() - [0.0, 0.0] - >>> turtle.heading() - 0.0 - """ - canvas = self._canvas - self._canvas.update() - width = canvas.winfo_width() - height = canvas.winfo_height() - if width <= 1: - width = canvas['width'] - if height <= 1: - height = canvas['height'] - self._origin = float(width)/2.0, float(height)/2.0 - self._position = self._origin - self._angle = 0.0 - self._drawing = 1 - self._width = 1 - self._color = "black" - self._filling = 0 - self._path = [] - self.clear() - canvas._root().tkraise() - - def clear(self): - """ Clear the screen. The turtle does not move. - - Example: - >>> turtle.clear() - """ - self.fill(0) - canvas = self._canvas - items = self._items - self._items = [] - for item in items: - canvas.delete(item) - self._delete_turtle() - self._draw_turtle() - - def tracer(self, flag): - """ Set tracing on if flag is True, and off if it is False. - Tracing means line are drawn more slowly, with an - animation of an arrow along the line. - - Example: - >>> turtle.tracer(False) # turns off Tracer - """ - self._tracing = flag - if not self._tracing: - self._delete_turtle() - self._draw_turtle() - - def forward(self, distance): - """ Go forward distance steps. - - Example: - >>> turtle.position() - [0.0, 0.0] - >>> turtle.forward(25) - >>> turtle.position() - [25.0, 0.0] - >>> turtle.forward(-75) - >>> turtle.position() - [-50.0, 0.0] - """ - x0, y0 = start = self._position - x1 = x0 + distance * cos(self._angle*self._invradian) - y1 = y0 - distance * sin(self._angle*self._invradian) - self._goto(x1, y1) - - def backward(self, distance): - """ Go backwards distance steps. - - The turtle's heading does not change. - - Example: - >>> turtle.position() - [0.0, 0.0] - >>> turtle.backward(30) - >>> turtle.position() - [-30.0, 0.0] - """ - self.forward(-distance) - - def left(self, angle): - """ Turn left angle units (units are by default degrees, - but can be set via the degrees() and radians() functions.) - - When viewed from above, the turning happens in-place around - its front tip. - - Example: - >>> turtle.heading() - 22 - >>> turtle.left(45) - >>> turtle.heading() - 67.0 - """ - self._angle = (self._angle + angle) % self._fullcircle - self._draw_turtle() - - def right(self, angle): - """ Turn right angle units (units are by default degrees, - but can be set via the degrees() and radians() functions.) - - When viewed from above, the turning happens in-place around - its front tip. - - Example: - >>> turtle.heading() - 22 - >>> turtle.right(45) - >>> turtle.heading() - 337.0 - """ - self.left(-angle) - - def up(self): - """ Pull the pen up -- no drawing when moving. - - Example: - >>> turtle.up() - """ - self._drawing = 0 - - def down(self): - """ Put the pen down -- draw when moving. - - Example: - >>> turtle.down() - """ - self._drawing = 1 - - def width(self, width): - """ Set the line to thickness to width. - - Example: - >>> turtle.width(10) - """ - self._width = float(width) - - def color(self, *args): - """ Set the pen color. - - Three input formats are allowed: - - color(s) - s is a Tk specification string, such as "red" or "yellow" - - color((r, g, b)) - *a tuple* of r, g, and b, which represent, an RGB color, - and each of r, g, and b are in the range [0..1] - - color(r, g, b) - r, g, and b represent an RGB color, and each of r, g, and b - are in the range [0..1] - - Example: - - >>> turtle.color('brown') - >>> tup = (0.2, 0.8, 0.55) - >>> turtle.color(tup) - >>> turtle.color(0, .5, 0) - """ - if not args: - raise Error("no color arguments") - if len(args) == 1: - color = args[0] - if type(color) == type(""): - # Test the color first - try: - id = self._canvas.create_line(0, 0, 0, 0, fill=color) - except Tkinter.TclError: - raise Error("bad color string: %r" % (color,)) - self._set_color(color) - return - try: - r, g, b = color - except: - raise Error("bad color sequence: %r" % (color,)) - else: - try: - r, g, b = args - except: - raise Error("bad color arguments: %r" % (args,)) - assert 0 <= r <= 1 - assert 0 <= g <= 1 - assert 0 <= b <= 1 - x = 255.0 - y = 0.5 - self._set_color("#%02x%02x%02x" % (int(r*x+y), int(g*x+y), int(b*x+y))) - - def _set_color(self,color): - self._color = color - self._draw_turtle() - - def write(self, text, move=False): - """ Write text at the current pen position. - - If move is true, the pen is moved to the bottom-right corner - of the text. By default, move is False. - - Example: - >>> turtle.write('The race is on!') - >>> turtle.write('Home = (0, 0)', True) - """ - x, y = self._position - x = x-1 # correction -- calibrated for Windows - item = self._canvas.create_text(x, y, - text=str(text), anchor="sw", - fill=self._color) - self._items.append(item) - if move: - x0, y0, x1, y1 = self._canvas.bbox(item) - self._goto(x1, y1) - self._draw_turtle() - - def fill(self, flag): - """ Call fill(1) before drawing the shape you - want to fill, and fill(0) when done. - - Example: - >>> turtle.fill(1) - >>> turtle.forward(100) - >>> turtle.left(90) - >>> turtle.forward(100) - >>> turtle.left(90) - >>> turtle.forward(100) - >>> turtle.left(90) - >>> turtle.forward(100) - >>> turtle.fill(0) - """ - if self._filling: - path = tuple(self._path) - smooth = self._filling < 0 - if len(path) > 2: - item = self._canvas._create('polygon', path, - {'fill': self._color, - 'smooth': smooth}) - self._items.append(item) - self._path = [] - self._filling = flag - if flag: - self._path.append(self._position) - - def begin_fill(self): - """ Called just before drawing a shape to be filled. - Must eventually be followed by a corresponding end_fill() call. - Otherwise it will be ignored. - - Example: - >>> turtle.begin_fill() - >>> turtle.forward(100) - >>> turtle.left(90) - >>> turtle.forward(100) - >>> turtle.left(90) - >>> turtle.forward(100) - >>> turtle.left(90) - >>> turtle.forward(100) - >>> turtle.end_fill() - """ - self._path = [self._position] - self._filling = 1 - - def end_fill(self): - """ Called after drawing a shape to be filled. - - Example: - >>> turtle.begin_fill() - >>> turtle.forward(100) - >>> turtle.left(90) - >>> turtle.forward(100) - >>> turtle.left(90) - >>> turtle.forward(100) - >>> turtle.left(90) - >>> turtle.forward(100) - >>> turtle.end_fill() - """ - self.fill(0) - - def circle(self, radius, extent = None): - """ Draw a circle with given radius. - The center is radius units left of the turtle; extent - determines which part of the circle is drawn. If not given, - the entire circle is drawn. - - If extent is not a full circle, one endpoint of the arc is the - current pen position. The arc is drawn in a counter clockwise - direction if radius is positive, otherwise in a clockwise - direction. In the process, the direction of the turtle is - changed by the amount of the extent. - - >>> turtle.circle(50) - >>> turtle.circle(120, 180) # half a circle - """ - if extent is None: - extent = self._fullcircle - frac = abs(extent)/self._fullcircle - steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac) - w = 1.0 * extent / steps - w2 = 0.5 * w - l = 2.0 * radius * sin(w2*self._invradian) - if radius < 0: - l, w, w2 = -l, -w, -w2 - self.left(w2) - for i in range(steps): - self.forward(l) - self.left(w) - self.right(w2) - - def heading(self): - """ Return the turtle's current heading. - - Example: - >>> turtle.heading() - 67.0 - """ - return self._angle - - def setheading(self, angle): - """ Set the turtle facing the given angle. - - Here are some common directions in degrees: - - 0 - east - 90 - north - 180 - west - 270 - south - - Example: - >>> turtle.setheading(90) - >>> turtle.heading() - 90 - >>> turtle.setheading(128) - >>> turtle.heading() - 128 - """ - self._angle = angle - self._draw_turtle() - - def window_width(self): - """ Returns the width of the turtle window. - - Example: - >>> turtle.window_width() - 640 - """ - width = self._canvas.winfo_width() - if width <= 1: # the window isn't managed by a geometry manager - width = self._canvas['width'] - return width - - def window_height(self): - """ Return the height of the turtle window. - - Example: - >>> turtle.window_height() - 768 - """ - height = self._canvas.winfo_height() - if height <= 1: # the window isn't managed by a geometry manager - height = self._canvas['height'] - return height - - def position(self): - """ Return the current (x, y) location of the turtle. - - Example: - >>> turtle.position() - [0.0, 240.0] - """ - x0, y0 = self._origin - x1, y1 = self._position - return [x1-x0, -y1+y0] - - def setx(self, xpos): - """ Set the turtle's x coordinate to be xpos. - - Example: - >>> turtle.position() - [10.0, 240.0] - >>> turtle.setx(10) - >>> turtle.position() - [10.0, 240.0] - """ - x0, y0 = self._origin - x1, y1 = self._position - self._goto(x0+xpos, y1) - - def sety(self, ypos): - """ Set the turtle's y coordinate to be ypos. - - Example: - >>> turtle.position() - [0.0, 0.0] - >>> turtle.sety(-22) - >>> turtle.position() - [0.0, -22.0] - """ - x0, y0 = self._origin - x1, y1 = self._position - self._goto(x1, y0-ypos) - - def towards(self, *args): - """Returs the angle, which corresponds to the line - from turtle-position to point (x,y). - - Argument can be two coordinates or one pair of coordinates - or a RawPen/Pen instance. - - Example: - >>> turtle.position() - [10.0, 10.0] - >>> turtle.towards(0,0) - 225.0 - """ - if len(args) == 2: - x, y = args - else: - arg = args[0] - if isinstance(arg, RawPen): - x, y = arg.position() - else: - x, y = arg - x0, y0 = self.position() - dx = x - x0 - dy = y - y0 - return (atan2(dy,dx) / self._invradian) % self._fullcircle - - def goto(self, *args): - """ Go to the given point. - - If the pen is down, then a line will be drawn. The turtle's - orientation does not change. - - Two input formats are accepted: - - goto(x, y) - go to point (x, y) - - goto((x, y)) - go to point (x, y) - - Example: - >>> turtle.position() - [0.0, 0.0] - >>> turtle.goto(50, -45) - >>> turtle.position() - [50.0, -45.0] - """ - if len(args) == 1: - try: - x, y = args[0] - except: - raise Error("bad point argument: %r" % (args[0],)) - else: - try: - x, y = args - except: - raise Error("bad coordinates: %r" % (args[0],)) - x0, y0 = self._origin - self._goto(x0+x, y0-y) - - def _goto(self, x1, y1): - x0, y0 = self._position - self._position = (float(x1), float(y1)) - if self._filling: - self._path.append(self._position) - if self._drawing: - if self._tracing: - dx = float(x1 - x0) - dy = float(y1 - y0) - distance = hypot(dx, dy) - nhops = int(distance) - item = self._canvas.create_line(x0, y0, x0, y0, - width=self._width, - capstyle="round", - fill=self._color) - try: - for i in range(1, 1+nhops): - x, y = x0 + dx*i/nhops, y0 + dy*i/nhops - self._canvas.coords(item, x0, y0, x, y) - self._draw_turtle((x,y)) - self._canvas.update() - self._canvas.after(self._delay) - # in case nhops==0 - self._canvas.coords(item, x0, y0, x1, y1) - self._canvas.itemconfigure(item, arrow="none") - except Tkinter.TclError: - # Probably the window was closed! - return - else: - item = self._canvas.create_line(x0, y0, x1, y1, - width=self._width, - capstyle="round", - fill=self._color) - self._items.append(item) - self._draw_turtle() - - def speed(self, speed): - """ Set the turtle's speed. - - speed must one of these five strings: - - 'fastest' is a 0 ms delay - 'fast' is a 5 ms delay - 'normal' is a 10 ms delay - 'slow' is a 15 ms delay - 'slowest' is a 20 ms delay - - Example: - >>> turtle.speed('slow') - """ - try: - speed = speed.strip().lower() - self._delay = speeds.index(speed) * 5 - except: - raise ValueError("%r is not a valid speed. speed must be " - "one of %s" % (speed, speeds)) - - - def delay(self, delay): - """ Set the drawing delay in milliseconds. - - This is intended to allow finer control of the drawing speed - than the speed() method - - Example: - >>> turtle.delay(15) - """ - if int(delay) < 0: - raise ValueError("delay must be greater than or equal to 0") - self._delay = int(delay) - - def _draw_turtle(self, position=[]): - if not self._tracing: - self._canvas.update() - return - if position == []: - position = self._position - x,y = position - distance = 8 - dx = distance * cos(self._angle*self._invradian) - dy = distance * sin(self._angle*self._invradian) - self._delete_turtle() - self._arrow = self._canvas.create_line(x-dx,y+dy,x,y, - width=self._width, - arrow="last", - capstyle="round", - fill=self._color) - self._canvas.update() - - def _delete_turtle(self): - if self._arrow != 0: - self._canvas.delete(self._arrow) - self._arrow = 0 - - -_root = None -_canvas = None -_pen = None -_width = 0.50 # 50% of window width -_height = 0.75 # 75% of window height -_startx = None -_starty = None -_title = "Turtle Graphics" # default title - -class Pen(RawPen): - - def __init__(self): - global _root, _canvas - if _root is None: - _root = Tkinter.Tk() - _root.wm_protocol("WM_DELETE_WINDOW", self._destroy) - _root.title(_title) - - if _canvas is None: - # XXX Should have scroll bars - _canvas = Tkinter.Canvas(_root, background="white") - _canvas.pack(expand=1, fill="both") - - setup(width=_width, height= _height, startx=_startx, starty=_starty) - - RawPen.__init__(self, _canvas) - - def _destroy(self): - global _root, _canvas, _pen - root = self._canvas._root() - if root is _root: - _pen = None - _root = None - _canvas = None - root.destroy() - -def _getpen(): - global _pen - if not _pen: - _pen = Pen() - return _pen - -class Turtle(Pen): - pass - -"""For documentation of the following functions see - the RawPen methods with the same names -""" - -def degrees(): _getpen().degrees() -def radians(): _getpen().radians() -def reset(): _getpen().reset() -def clear(): _getpen().clear() -def tracer(flag): _getpen().tracer(flag) -def forward(distance): _getpen().forward(distance) -def backward(distance): _getpen().backward(distance) -def left(angle): _getpen().left(angle) -def right(angle): _getpen().right(angle) -def up(): _getpen().up() -def down(): _getpen().down() -def width(width): _getpen().width(width) -def color(*args): _getpen().color(*args) -def write(arg, move=0): _getpen().write(arg, move) -def fill(flag): _getpen().fill(flag) -def begin_fill(): _getpen().begin_fill() -def end_fill(): _getpen().end_fill() -def circle(radius, extent=None): _getpen().circle(radius, extent) -def goto(*args): _getpen().goto(*args) -def heading(): return _getpen().heading() -def setheading(angle): _getpen().setheading(angle) -def position(): return _getpen().position() -def window_width(): return _getpen().window_width() -def window_height(): return _getpen().window_height() -def setx(xpos): _getpen().setx(xpos) -def sety(ypos): _getpen().sety(ypos) -def towards(*args): return _getpen().towards(*args) - -def done(): _root.mainloop() -def delay(delay): return _getpen().delay(delay) -def speed(speed): return _getpen().speed(speed) - -for methodname in dir(RawPen): - """ copies RawPen docstrings to module functions of same name """ - if not methodname.startswith("_"): - eval(methodname).__doc__ = RawPen.__dict__[methodname].__doc__ - - -def setup(**geometry): - """ Sets the size and position of the main window. - - Keywords are width, height, startx and starty: - - width: either a size in pixels or a fraction of the screen. - Default is 50% of screen. - height: either the height in pixels or a fraction of the screen. - Default is 75% of screen. - - Setting either width or height to None before drawing will force - use of default geometry as in older versions of turtle.py - - startx: starting position in pixels from the left edge of the screen. - Default is to center window. Setting startx to None is the default - and centers window horizontally on screen. - - starty: starting position in pixels from the top edge of the screen. - Default is to center window. Setting starty to None is the default - and centers window vertically on screen. - - Examples: - >>> setup (width=200, height=200, startx=0, starty=0) - - sets window to 200x200 pixels, in upper left of screen - - >>> setup(width=.75, height=0.5, startx=None, starty=None) - - sets window to 75% of screen by 50% of screen and centers - - >>> setup(width=None) - - forces use of default geometry as in older versions of turtle.py - """ - - global _width, _height, _startx, _starty - - width = geometry.get('width',_width) - if width >= 0 or width is None: - _width = width - else: - raise ValueError("width can not be less than 0") - - height = geometry.get('height',_height) - if height >= 0 or height is None: - _height = height - else: - raise ValueError("height can not be less than 0") - - startx = geometry.get('startx', _startx) - if startx >= 0 or startx is None: - _startx = _startx - else: - raise ValueError("startx can not be less than 0") - - starty = geometry.get('starty', _starty) - if starty >= 0 or starty is None: - _starty = starty - else: - raise ValueError("startx can not be less than 0") - - - if _root and _width and _height: - if 0 < _width <= 1: - _width = _root.winfo_screenwidth() * +width - if 0 < _height <= 1: - _height = _root.winfo_screenheight() * _height - - # center window on screen - if _startx is None: - _startx = (_root.winfo_screenwidth() - _width) / 2 - - if _starty is None: - _starty = (_root.winfo_screenheight() - _height) / 2 - - _root.geometry("%dx%d+%d+%d" % (_width, _height, _startx, _starty)) - -def title(title): - """Set the window title. - - By default this is set to 'Turtle Graphics' - - Example: - >>> title("My Window") - """ - - global _title - _title = title - -def demo(): - reset() - tracer(1) - up() - backward(100) - down() - # draw 3 squares; the last filled - width(3) - for i in range(3): - if i == 2: - fill(1) - for j in range(4): - forward(20) - left(90) - if i == 2: - color("maroon") - fill(0) - up() - forward(30) - down() - width(1) - color("black") - # move out of the way - tracer(0) - up() - right(90) - forward(100) - right(90) - forward(100) - right(180) - down() - # some text - write("startstart", 1) - write("start", 1) - color("red") - # staircase - for i in range(5): - forward(20) - left(90) - forward(20) - right(90) - # filled staircase - fill(1) - for i in range(5): - forward(20) - left(90) - forward(20) - right(90) - fill(0) - tracer(1) - # more text - write("end") - -def demo2(): - # exercises some new and improved features - speed('fast') - width(3) - - # draw a segmented half-circle - setheading(towards(0,0)) - x,y = position() - r = (x**2+y**2)**.5/2.0 - right(90) - pendown = True - for i in range(18): - if pendown: - up() - pendown = False - else: - down() - pendown = True - circle(r,10) - sleep(2) - - reset() - left(90) - - # draw a series of triangles - l = 10 - color("green") - width(3) - left(180) - sp = 5 - for i in range(-2,16): - if i > 0: - color(1.0-0.05*i,0,0.05*i) - fill(1) - color("green") - for j in range(3): - forward(l) - left(120) - l += 10 - left(15) - if sp > 0: - sp = sp-1 - speed(speeds[sp]) - color(0.25,0,0.75) - fill(0) - - # draw and fill a concave shape - left(120) - up() - forward(70) - right(30) - down() - color("red") - speed("fastest") - fill(1) - for i in range(4): - circle(50,90) - right(90) - forward(30) - right(90) - color("yellow") - fill(0) - left(90) - up() - forward(30) - down(); - - color("red") - - # create a second turtle and make the original pursue and catch it - turtle=Turtle() - turtle.reset() - turtle.left(90) - turtle.speed('normal') - turtle.up() - turtle.goto(280,40) - turtle.left(24) - turtle.down() - turtle.speed('fast') - turtle.color("blue") - turtle.width(2) - speed('fastest') - - # turn default turtle towards new turtle object - setheading(towards(turtle)) - while ( abs(position()[0]-turtle.position()[0])>4 or - abs(position()[1]-turtle.position()[1])>4): - turtle.forward(3.5) - turtle.left(0.6) - # turn default turtle towards new turtle object - setheading(towards(turtle)) - forward(4) - write("CAUGHT! ", move=True) - - - -if __name__ == '__main__': - demo() - sleep(3) - demo2() - done() Index: Lib/lib-tk/Tkinter.py =================================================================== --- Lib/lib-tk/Tkinter.py (revision 63074) +++ Lib/lib-tk/Tkinter.py (working copy) @@ -1,3752 +0,0 @@ -"""Wrapper functions for Tcl/Tk. - -Tkinter provides classes which allow the display, positioning and -control of widgets. Toplevel widgets are Tk and Toplevel. Other -widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton, -Checkbutton, Scale, Listbox, Scrollbar, OptionMenu, Spinbox -LabelFrame and PanedWindow. - -Properties of the widgets are specified with keyword arguments. -Keyword arguments have the same name as the corresponding resource -under Tk. - -Widgets are positioned with one of the geometry managers Place, Pack -or Grid. These managers can be called with methods place, pack, grid -available in every Widget. - -Actions are bound to events by resources (e.g. keyword argument -command) or with the method bind. - -Example (Hello, World): -import Tkinter -from Tkconstants import * -tk = Tkinter.Tk() -frame = Tkinter.Frame(tk, relief=RIDGE, borderwidth=2) -frame.pack(fill=BOTH,expand=1) -label = Tkinter.Label(frame, text="Hello, World") -label.pack(fill=X, expand=1) -button = Tkinter.Button(frame,text="Exit",command=tk.destroy) -button.pack(side=BOTTOM) -tk.mainloop() -""" - -__version__ = "$Revision$" - -import sys -if sys.platform == "win32": - import FixTk # Attempt to configure Tcl/Tk without requiring PATH -import _tkinter # If this fails your Python may not be configured for Tk -tkinter = _tkinter # b/w compat for export -TclError = _tkinter.TclError -from Tkconstants import * -try: - import MacOS; _MacOS = MacOS; del MacOS -except ImportError: - _MacOS = None - -wantobjects = 1 - -TkVersion = float(_tkinter.TK_VERSION) -TclVersion = float(_tkinter.TCL_VERSION) - -READABLE = _tkinter.READABLE -WRITABLE = _tkinter.WRITABLE -EXCEPTION = _tkinter.EXCEPTION - -# These are not always defined, e.g. not on Win32 with Tk 8.0 :-( -try: _tkinter.createfilehandler -except AttributeError: _tkinter.createfilehandler = None -try: _tkinter.deletefilehandler -except AttributeError: _tkinter.deletefilehandler = None - - -def _flatten(seq): - """Internal function.""" - res = () - for item in seq: - if isinstance(item, (tuple, list)): - res = res + _flatten(item) - elif item is not None: - res = res + (item,) - return res - -try: _flatten = _tkinter._flatten -except AttributeError: pass - -def _cnfmerge(cnfs): - """Internal function.""" - if isinstance(cnfs, dict): - return cnfs - elif isinstance(cnfs, (type(None), str)): - return cnfs - else: - cnf = {} - for c in _flatten(cnfs): - try: - cnf.update(c) - except (AttributeError, TypeError) as msg: - print("_cnfmerge: fallback due to:", msg) - for k, v in c.items(): - cnf[k] = v - return cnf - -try: _cnfmerge = _tkinter._cnfmerge -except AttributeError: pass - -class Event: - """Container for the properties of an event. - - Instances of this type are generated if one of the following events occurs: - - KeyPress, KeyRelease - for keyboard events - ButtonPress, ButtonRelease, Motion, Enter, Leave, MouseWheel - for mouse events - Visibility, Unmap, Map, Expose, FocusIn, FocusOut, Circulate, - Colormap, Gravity, Reparent, Property, Destroy, Activate, - Deactivate - for window events. - - If a callback function for one of these events is registered - using bind, bind_all, bind_class, or tag_bind, the callback is - called with an Event as first argument. It will have the - following attributes (in braces are the event types for which - the attribute is valid): - - serial - serial number of event - num - mouse button pressed (ButtonPress, ButtonRelease) - focus - whether the window has the focus (Enter, Leave) - height - height of the exposed window (Configure, Expose) - width - width of the exposed window (Configure, Expose) - keycode - keycode of the pressed key (KeyPress, KeyRelease) - state - state of the event as a number (ButtonPress, ButtonRelease, - Enter, KeyPress, KeyRelease, - Leave, Motion) - state - state as a string (Visibility) - time - when the event occurred - x - x-position of the mouse - y - y-position of the mouse - x_root - x-position of the mouse on the screen - (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) - y_root - y-position of the mouse on the screen - (ButtonPress, ButtonRelease, KeyPress, KeyRelease, Motion) - char - pressed character (KeyPress, KeyRelease) - send_event - see X/Windows documentation - keysym - keysym of the event as a string (KeyPress, KeyRelease) - keysym_num - keysym of the event as a number (KeyPress, KeyRelease) - type - type of the event as a number - widget - widget in which the event occurred - delta - delta of wheel movement (MouseWheel) - """ - pass - -_support_default_root = 1 -_default_root = None - -def NoDefaultRoot(): - """Inhibit setting of default root window. - - Call this function to inhibit that the first instance of - Tk is used for windows without an explicit parent window. - """ - global _support_default_root - _support_default_root = 0 - global _default_root - _default_root = None - del _default_root - -def _tkerror(err): - """Internal function.""" - pass - -def _exit(code='0'): - """Internal function. Calling it will throw the exception SystemExit.""" - raise SystemExit(code) - -_varnum = 0 -class Variable: - """Class to define value holders for e.g. buttons. - - Subclasses StringVar, IntVar, DoubleVar, BooleanVar are specializations - that constrain the type of the value returned from get().""" - _default = "" - def __init__(self, master=None, value=None, name=None): - """Construct a variable - - MASTER can be given as master widget. - VALUE is an optional value (defaults to "") - NAME is an optional Tcl name (defaults to PY_VARnum). - - If NAME matches an existing variable and VALUE is omitted - then the existing value is retained. - """ - global _varnum - if not master: - master = _default_root - self._master = master - self._tk = master.tk - if name: - self._name = name - else: - self._name = 'PY_VAR' + repr(_varnum) - _varnum += 1 - if value is not None: - self.set(value) - elif not self._tk.call("info", "exists", self._name): - self.set(self._default) - def __del__(self): - """Unset the variable in Tcl.""" - self._tk.globalunsetvar(self._name) - def __str__(self): - """Return the name of the variable in Tcl.""" - return self._name - def set(self, value): - """Set the variable to VALUE.""" - return self._tk.globalsetvar(self._name, value) - def get(self): - """Return value of variable.""" - return self._tk.globalgetvar(self._name) - def trace_variable(self, mode, callback): - """Define a trace callback for the variable. - - MODE is one of "r", "w", "u" for read, write, undefine. - CALLBACK must be a function which is called when - the variable is read, written or undefined. - - Return the name of the callback. - """ - cbname = self._master._register(callback) - self._tk.call("trace", "variable", self._name, mode, cbname) - return cbname - trace = trace_variable - def trace_vdelete(self, mode, cbname): - """Delete the trace callback for a variable. - - MODE is one of "r", "w", "u" for read, write, undefine. - CBNAME is the name of the callback returned from trace_variable or trace. - """ - self._tk.call("trace", "vdelete", self._name, mode, cbname) - self._master.deletecommand(cbname) - def trace_vinfo(self): - """Return all trace callback information.""" - return map(self._tk.split, self._tk.splitlist( - self._tk.call("trace", "vinfo", self._name))) - def __eq__(self, other): - """Comparison for equality (==). - - Note: if the Variable's master matters to behavior - also compare self._master == other._master - """ - return self.__class__.__name__ == other.__class__.__name__ \ - and self._name == other._name - -class StringVar(Variable): - """Value holder for strings variables.""" - _default = "" - def __init__(self, master=None, value=None, name=None): - """Construct a string variable. - - MASTER can be given as master widget. - VALUE is an optional value (defaults to "") - NAME is an optional Tcl name (defaults to PY_VARnum). - - If NAME matches an existing variable and VALUE is omitted - then the existing value is retained. - """ - Variable.__init__(self, master, value, name) - - def get(self): - """Return value of variable as string.""" - value = self._tk.globalgetvar(self._name) - if isinstance(value, str): - return value - return str(value) - -class IntVar(Variable): - """Value holder for integer variables.""" - _default = 0 - def __init__(self, master=None, value=None, name=None): - """Construct an integer variable. - - MASTER can be given as master widget. - VALUE is an optional value (defaults to 0) - NAME is an optional Tcl name (defaults to PY_VARnum). - - If NAME matches an existing variable and VALUE is omitted - then the existing value is retained. - """ - Variable.__init__(self, master, value, name) - - def set(self, value): - """Set the variable to value, converting booleans to integers.""" - if isinstance(value, bool): - value = int(value) - return Variable.set(self, value) - - def get(self): - """Return the value of the variable as an integer.""" - return getint(self._tk.globalgetvar(self._name)) - -class DoubleVar(Variable): - """Value holder for float variables.""" - _default = 0.0 - def __init__(self, master=None, value=None, name=None): - """Construct a float variable. - - MASTER can be given as master widget. - VALUE is an optional value (defaults to 0.0) - NAME is an optional Tcl name (defaults to PY_VARnum). - - If NAME matches an existing variable and VALUE is omitted - then the existing value is retained. - """ - Variable.__init__(self, master, value, name) - - def get(self): - """Return the value of the variable as a float.""" - return getdouble(self._tk.globalgetvar(self._name)) - -class BooleanVar(Variable): - """Value holder for boolean variables.""" - _default = False - def __init__(self, master=None, value=None, name=None): - """Construct a boolean variable. - - MASTER can be given as master widget. - VALUE is an optional value (defaults to False) - NAME is an optional Tcl name (defaults to PY_VARnum). - - If NAME matches an existing variable and VALUE is omitted - then the existing value is retained. - """ - Variable.__init__(self, master, value, name) - - def get(self): - """Return the value of the variable as a bool.""" - return self._tk.getboolean(self._tk.globalgetvar(self._name)) - -def mainloop(n=0): - """Run the main loop of Tcl.""" - _default_root.tk.mainloop(n) - -getint = int - -getdouble = float - -def getboolean(s): - """Convert true and false to integer values 1 and 0.""" - return _default_root.tk.getboolean(s) - -# Methods defined on both toplevel and interior widgets -class Misc: - """Internal class. - - Base class which defines methods common for interior widgets.""" - - # XXX font command? - _tclCommands = None - def destroy(self): - """Internal function. - - Delete all Tcl commands created for - this widget in the Tcl interpreter.""" - if self._tclCommands is not None: - for name in self._tclCommands: - #print '- Tkinter: deleted command', name - self.tk.deletecommand(name) - self._tclCommands = None - def deletecommand(self, name): - """Internal function. - - Delete the Tcl command provided in NAME.""" - #print '- Tkinter: deleted command', name - self.tk.deletecommand(name) - try: - self._tclCommands.remove(name) - except ValueError: - pass - def tk_strictMotif(self, boolean=None): - """Set Tcl internal variable, whether the look and feel - should adhere to Motif. - - A parameter of 1 means adhere to Motif (e.g. no color - change if mouse passes over slider). - Returns the set value.""" - return self.tk.getboolean(self.tk.call( - 'set', 'tk_strictMotif', boolean)) - def tk_bisque(self): - """Change the color scheme to light brown as used in Tk 3.6 and before.""" - self.tk.call('tk_bisque') - def tk_setPalette(self, *args, **kw): - """Set a new color scheme for all widget elements. - - A single color as argument will cause that all colors of Tk - widget elements are derived from this. - Alternatively several keyword parameters and its associated - colors can be given. The following keywords are valid: - activeBackground, foreground, selectColor, - activeForeground, highlightBackground, selectBackground, - background, highlightColor, selectForeground, - disabledForeground, insertBackground, troughColor.""" - self.tk.call(('tk_setPalette',) - + _flatten(args) + _flatten(kw.items())) - def tk_menuBar(self, *args): - """Do not use. Needed in Tk 3.6 and earlier.""" - pass # obsolete since Tk 4.0 - def wait_variable(self, name='PY_VAR'): - """Wait until the variable is modified. - - A parameter of type IntVar, StringVar, DoubleVar or - BooleanVar must be given.""" - self.tk.call('tkwait', 'variable', name) - waitvar = wait_variable # XXX b/w compat - def wait_window(self, window=None): - """Wait until a WIDGET is destroyed. - - If no parameter is given self is used.""" - if window is None: - window = self - self.tk.call('tkwait', 'window', window._w) - def wait_visibility(self, window=None): - """Wait until the visibility of a WIDGET changes - (e.g. it appears). - - If no parameter is given self is used.""" - if window is None: - window = self - self.tk.call('tkwait', 'visibility', window._w) - def setvar(self, name='PY_VAR', value='1'): - """Set Tcl variable NAME to VALUE.""" - self.tk.setvar(name, value) - def getvar(self, name='PY_VAR'): - """Return value of Tcl variable NAME.""" - return self.tk.getvar(name) - getint = int - getdouble = float - def getboolean(self, s): - """Return a boolean value for Tcl boolean values true and false given as parameter.""" - return self.tk.getboolean(s) - def focus_set(self): - """Direct input focus to this widget. - - If the application currently does not have the focus - this widget will get the focus if the application gets - the focus through the window manager.""" - self.tk.call('focus', self._w) - focus = focus_set # XXX b/w compat? - def focus_force(self): - """Direct input focus to this widget even if the - application does not have the focus. Use with - caution!""" - self.tk.call('focus', '-force', self._w) - def focus_get(self): - """Return the widget which has currently the focus in the - application. - - Use focus_displayof to allow working with several - displays. Return None if application does not have - the focus.""" - name = self.tk.call('focus') - if name == 'none' or not name: return None - return self._nametowidget(name) - def focus_displayof(self): - """Return the widget which has currently the focus on the - display where this widget is located. - - Return None if the application does not have the focus.""" - name = self.tk.call('focus', '-displayof', self._w) - if name == 'none' or not name: return None - return self._nametowidget(name) - def focus_lastfor(self): - """Return the widget which would have the focus if top level - for this widget gets the focus from the window manager.""" - name = self.tk.call('focus', '-lastfor', self._w) - if name == 'none' or not name: return None - return self._nametowidget(name) - def tk_focusFollowsMouse(self): - """The widget under mouse will get automatically focus. Can not - be disabled easily.""" - self.tk.call('tk_focusFollowsMouse') - def tk_focusNext(self): - """Return the next widget in the focus order which follows - widget which has currently the focus. - - The focus order first goes to the next child, then to - the children of the child recursively and then to the - next sibling which is higher in the stacking order. A - widget is omitted if it has the takefocus resource set - to 0.""" - name = self.tk.call('tk_focusNext', self._w) - if not name: return None - return self._nametowidget(name) - def tk_focusPrev(self): - """Return previous widget in the focus order. See tk_focusNext for details.""" - name = self.tk.call('tk_focusPrev', self._w) - if not name: return None - return self._nametowidget(name) - def after(self, ms, func=None, *args): - """Call function once after given time. - - MS specifies the time in milliseconds. FUNC gives the - function which shall be called. Additional parameters - are given as parameters to the function call. Return - identifier to cancel scheduling with after_cancel.""" - if not func: - # I'd rather use time.sleep(ms*0.001) - self.tk.call('after', ms) - else: - def callit(): - try: - func(*args) - finally: - try: - self.deletecommand(name) - except TclError: - pass - name = self._register(callit) - return self.tk.call('after', ms, name) - def after_idle(self, func, *args): - """Call FUNC once if the Tcl main loop has no event to - process. - - Return an identifier to cancel the scheduling with - after_cancel.""" - return self.after('idle', func, *args) - def after_cancel(self, id): - """Cancel scheduling of function identified with ID. - - Identifier returned by after or after_idle must be - given as first parameter.""" - try: - data = self.tk.call('after', 'info', id) - # In Tk 8.3, splitlist returns: (script, type) - # In Tk 8.4, splitlist may return (script, type) or (script,) - script = self.tk.splitlist(data)[0] - self.deletecommand(script) - except TclError: - pass - self.tk.call('after', 'cancel', id) - def bell(self, displayof=0): - """Ring a display's bell.""" - self.tk.call(('bell',) + self._displayof(displayof)) - - # Clipboard handling: - def clipboard_get(self, **kw): - """Retrieve data from the clipboard on window's display. - - The window keyword defaults to the root window of the Tkinter - application. - - The type keyword specifies the form in which the data is - to be returned and should be an atom name such as STRING - or FILE_NAME. Type defaults to STRING. - - This command is equivalent to: - - selection_get(CLIPBOARD) - """ - return self.tk.call(('clipboard', 'get') + self._options(kw)) - - def clipboard_clear(self, **kw): - """Clear the data in the Tk clipboard. - - A widget specified for the optional displayof keyword - argument specifies the target display.""" - if 'displayof' not in kw: kw['displayof'] = self._w - self.tk.call(('clipboard', 'clear') + self._options(kw)) - def clipboard_append(self, string, **kw): - """Append STRING to the Tk clipboard. - - A widget specified at the optional displayof keyword - argument specifies the target display. The clipboard - can be retrieved with selection_get.""" - if 'displayof' not in kw: kw['displayof'] = self._w - self.tk.call(('clipboard', 'append') + self._options(kw) - + ('--', string)) - # XXX grab current w/o window argument - def grab_current(self): - """Return widget which has currently the grab in this application - or None.""" - name = self.tk.call('grab', 'current', self._w) - if not name: return None - return self._nametowidget(name) - def grab_release(self): - """Release grab for this widget if currently set.""" - self.tk.call('grab', 'release', self._w) - def grab_set(self): - """Set grab for this widget. - - A grab directs all events to this and descendant - widgets in the application.""" - self.tk.call('grab', 'set', self._w) - def grab_set_global(self): - """Set global grab for this widget. - - A global grab directs all events to this and - descendant widgets on the display. Use with caution - - other applications do not get events anymore.""" - self.tk.call('grab', 'set', '-global', self._w) - def grab_status(self): - """Return None, "local" or "global" if this widget has - no, a local or a global grab.""" - status = self.tk.call('grab', 'status', self._w) - if status == 'none': status = None - return status - def lower(self, belowThis=None): - """Lower this widget in the stacking order.""" - self.tk.call('lower', self._w, belowThis) - def option_add(self, pattern, value, priority = None): - """Set a VALUE (second parameter) for an option - PATTERN (first parameter). - - An optional third parameter gives the numeric priority - (defaults to 80).""" - self.tk.call('option', 'add', pattern, value, priority) - def option_clear(self): - """Clear the option database. - - It will be reloaded if option_add is called.""" - self.tk.call('option', 'clear') - def option_get(self, name, className): - """Return the value for an option NAME for this widget - with CLASSNAME. - - Values with higher priority override lower values.""" - return self.tk.call('option', 'get', self._w, name, className) - def option_readfile(self, fileName, priority = None): - """Read file FILENAME into the option database. - - An optional second parameter gives the numeric - priority.""" - self.tk.call('option', 'readfile', fileName, priority) - def selection_clear(self, **kw): - """Clear the current X selection.""" - if 'displayof' not in kw: kw['displayof'] = self._w - self.tk.call(('selection', 'clear') + self._options(kw)) - def selection_get(self, **kw): - """Return the contents of the current X selection. - - A keyword parameter selection specifies the name of - the selection and defaults to PRIMARY. A keyword - parameter displayof specifies a widget on the display - to use.""" - if 'displayof' not in kw: kw['displayof'] = self._w - return self.tk.call(('selection', 'get') + self._options(kw)) - def selection_handle(self, command, **kw): - """Specify a function COMMAND to call if the X - selection owned by this widget is queried by another - application. - - This function must return the contents of the - selection. The function will be called with the - arguments OFFSET and LENGTH which allows the chunking - of very long selections. The following keyword - parameters can be provided: - selection - name of the selection (default PRIMARY), - type - type of the selection (e.g. STRING, FILE_NAME).""" - name = self._register(command) - self.tk.call(('selection', 'handle') + self._options(kw) - + (self._w, name)) - def selection_own(self, **kw): - """Become owner of X selection. - - A keyword parameter selection specifies the name of - the selection (default PRIMARY).""" - self.tk.call(('selection', 'own') + - self._options(kw) + (self._w,)) - def selection_own_get(self, **kw): - """Return owner of X selection. - - The following keyword parameter can - be provided: - selection - name of the selection (default PRIMARY), - type - type of the selection (e.g. STRING, FILE_NAME).""" - if 'displayof' not in kw: kw['displayof'] = self._w - name = self.tk.call(('selection', 'own') + self._options(kw)) - if not name: return None - return self._nametowidget(name) - def send(self, interp, cmd, *args): - """Send Tcl command CMD to different interpreter INTERP to be executed.""" - return self.tk.call(('send', interp, cmd) + args) - def lower(self, belowThis=None): - """Lower this widget in the stacking order.""" - self.tk.call('lower', self._w, belowThis) - def tkraise(self, aboveThis=None): - """Raise this widget in the stacking order.""" - self.tk.call('raise', self._w, aboveThis) - lift = tkraise - def colormodel(self, value=None): - """Useless. Not implemented in Tk.""" - return self.tk.call('tk', 'colormodel', self._w, value) - def winfo_atom(self, name, displayof=0): - """Return integer which represents atom NAME.""" - args = ('winfo', 'atom') + self._displayof(displayof) + (name,) - return getint(self.tk.call(args)) - def winfo_atomname(self, id, displayof=0): - """Return name of atom with identifier ID.""" - args = ('winfo', 'atomname') \ - + self._displayof(displayof) + (id,) - return self.tk.call(args) - def winfo_cells(self): - """Return number of cells in the colormap for this widget.""" - return getint( - self.tk.call('winfo', 'cells', self._w)) - def winfo_children(self): - """Return a list of all widgets which are children of this widget.""" - result = [] - for child in self.tk.splitlist( - self.tk.call('winfo', 'children', self._w)): - try: - # Tcl sometimes returns extra windows, e.g. for - # menus; those need to be skipped - result.append(self._nametowidget(child)) - except KeyError: - pass - return result - - def winfo_class(self): - """Return window class name of this widget.""" - return self.tk.call('winfo', 'class', self._w) - def winfo_colormapfull(self): - """Return true if at the last color request the colormap was full.""" - return self.tk.getboolean( - self.tk.call('winfo', 'colormapfull', self._w)) - def winfo_containing(self, rootX, rootY, displayof=0): - """Return the widget which is at the root coordinates ROOTX, ROOTY.""" - args = ('winfo', 'containing') \ - + self._displayof(displayof) + (rootX, rootY) - name = self.tk.call(args) - if not name: return None - return self._nametowidget(name) - def winfo_depth(self): - """Return the number of bits per pixel.""" - return getint(self.tk.call('winfo', 'depth', self._w)) - def winfo_exists(self): - """Return true if this widget exists.""" - return getint( - self.tk.call('winfo', 'exists', self._w)) - def winfo_fpixels(self, number): - """Return the number of pixels for the given distance NUMBER - (e.g. "3c") as float.""" - return getdouble(self.tk.call( - 'winfo', 'fpixels', self._w, number)) - def winfo_geometry(self): - """Return geometry string for this widget in the form "widthxheight+X+Y".""" - return self.tk.call('winfo', 'geometry', self._w) - def winfo_height(self): - """Return height of this widget.""" - return getint( - self.tk.call('winfo', 'height', self._w)) - def winfo_id(self): - """Return identifier ID for this widget.""" - return self.tk.getint( - self.tk.call('winfo', 'id', self._w)) - def winfo_interps(self, displayof=0): - """Return the name of all Tcl interpreters for this display.""" - args = ('winfo', 'interps') + self._displayof(displayof) - return self.tk.splitlist(self.tk.call(args)) - def winfo_ismapped(self): - """Return true if this widget is mapped.""" - return getint( - self.tk.call('winfo', 'ismapped', self._w)) - def winfo_manager(self): - """Return the window mananger name for this widget.""" - return self.tk.call('winfo', 'manager', self._w) - def winfo_name(self): - """Return the name of this widget.""" - return self.tk.call('winfo', 'name', self._w) - def winfo_parent(self): - """Return the name of the parent of this widget.""" - return self.tk.call('winfo', 'parent', self._w) - def winfo_pathname(self, id, displayof=0): - """Return the pathname of the widget given by ID.""" - args = ('winfo', 'pathname') \ - + self._displayof(displayof) + (id,) - return self.tk.call(args) - def winfo_pixels(self, number): - """Rounded integer value of winfo_fpixels.""" - return getint( - self.tk.call('winfo', 'pixels', self._w, number)) - def winfo_pointerx(self): - """Return the x coordinate of the pointer on the root window.""" - return getint( - self.tk.call('winfo', 'pointerx', self._w)) - def winfo_pointerxy(self): - """Return a tuple of x and y coordinates of the pointer on the root window.""" - return self._getints( - self.tk.call('winfo', 'pointerxy', self._w)) - def winfo_pointery(self): - """Return the y coordinate of the pointer on the root window.""" - return getint( - self.tk.call('winfo', 'pointery', self._w)) - def winfo_reqheight(self): - """Return requested height of this widget.""" - return getint( - self.tk.call('winfo', 'reqheight', self._w)) - def winfo_reqwidth(self): - """Return requested width of this widget.""" - return getint( - self.tk.call('winfo', 'reqwidth', self._w)) - def winfo_rgb(self, color): - """Return tuple of decimal values for red, green, blue for - COLOR in this widget.""" - return self._getints( - self.tk.call('winfo', 'rgb', self._w, color)) - def winfo_rootx(self): - """Return x coordinate of upper left corner of this widget on the - root window.""" - return getint( - self.tk.call('winfo', 'rootx', self._w)) - def winfo_rooty(self): - """Return y coordinate of upper left corner of this widget on the - root window.""" - return getint( - self.tk.call('winfo', 'rooty', self._w)) - def winfo_screen(self): - """Return the screen name of this widget.""" - return self.tk.call('winfo', 'screen', self._w) - def winfo_screencells(self): - """Return the number of the cells in the colormap of the screen - of this widget.""" - return getint( - self.tk.call('winfo', 'screencells', self._w)) - def winfo_screendepth(self): - """Return the number of bits per pixel of the root window of the - screen of this widget.""" - return getint( - self.tk.call('winfo', 'screendepth', self._w)) - def winfo_screenheight(self): - """Return the number of pixels of the height of the screen of this widget - in pixel.""" - return getint( - self.tk.call('winfo', 'screenheight', self._w)) - def winfo_screenmmheight(self): - """Return the number of pixels of the height of the screen of - this widget in mm.""" - return getint( - self.tk.call('winfo', 'screenmmheight', self._w)) - def winfo_screenmmwidth(self): - """Return the number of pixels of the width of the screen of - this widget in mm.""" - return getint( - self.tk.call('winfo', 'screenmmwidth', self._w)) - def winfo_screenvisual(self): - """Return one of the strings directcolor, grayscale, pseudocolor, - staticcolor, staticgray, or truecolor for the default - colormodel of this screen.""" - return self.tk.call('winfo', 'screenvisual', self._w) - def winfo_screenwidth(self): - """Return the number of pixels of the width of the screen of - this widget in pixel.""" - return getint( - self.tk.call('winfo', 'screenwidth', self._w)) - def winfo_server(self): - """Return information of the X-Server of the screen of this widget in - the form "XmajorRminor vendor vendorVersion".""" - return self.tk.call('winfo', 'server', self._w) - def winfo_toplevel(self): - """Return the toplevel widget of this widget.""" - return self._nametowidget(self.tk.call( - 'winfo', 'toplevel', self._w)) - def winfo_viewable(self): - """Return true if the widget and all its higher ancestors are mapped.""" - return getint( - self.tk.call('winfo', 'viewable', self._w)) - def winfo_visual(self): - """Return one of the strings directcolor, grayscale, pseudocolor, - staticcolor, staticgray, or truecolor for the - colormodel of this widget.""" - return self.tk.call('winfo', 'visual', self._w) - def winfo_visualid(self): - """Return the X identifier for the visual for this widget.""" - return self.tk.call('winfo', 'visualid', self._w) - def winfo_visualsavailable(self, includeids=0): - """Return a list of all visuals available for the screen - of this widget. - - Each item in the list consists of a visual name (see winfo_visual), a - depth and if INCLUDEIDS=1 is given also the X identifier.""" - data = self.tk.split( - self.tk.call('winfo', 'visualsavailable', self._w, - includeids and 'includeids' or None)) - if isinstance(data, str): - data = [self.tk.split(data)] - return map(self.__winfo_parseitem, data) - def __winfo_parseitem(self, t): - """Internal function.""" - return t[:1] + tuple(map(self.__winfo_getint, t[1:])) - def __winfo_getint(self, x): - """Internal function.""" - return int(x, 0) - def winfo_vrootheight(self): - """Return the height of the virtual root window associated with this - widget in pixels. If there is no virtual root window return the - height of the screen.""" - return getint( - self.tk.call('winfo', 'vrootheight', self._w)) - def winfo_vrootwidth(self): - """Return the width of the virtual root window associated with this - widget in pixel. If there is no virtual root window return the - width of the screen.""" - return getint( - self.tk.call('winfo', 'vrootwidth', self._w)) - def winfo_vrootx(self): - """Return the x offset of the virtual root relative to the root - window of the screen of this widget.""" - return getint( - self.tk.call('winfo', 'vrootx', self._w)) - def winfo_vrooty(self): - """Return the y offset of the virtual root relative to the root - window of the screen of this widget.""" - return getint( - self.tk.call('winfo', 'vrooty', self._w)) - def winfo_width(self): - """Return the width of this widget.""" - return getint( - self.tk.call('winfo', 'width', self._w)) - def winfo_x(self): - """Return the x coordinate of the upper left corner of this widget - in the parent.""" - return getint( - self.tk.call('winfo', 'x', self._w)) - def winfo_y(self): - """Return the y coordinate of the upper left corner of this widget - in the parent.""" - return getint( - self.tk.call('winfo', 'y', self._w)) - def update(self): - """Enter event loop until all pending events have been processed by Tcl.""" - self.tk.call('update') - def update_idletasks(self): - """Enter event loop until all idle callbacks have been called. This - will update the display of windows but not process events caused by - the user.""" - self.tk.call('update', 'idletasks') - def bindtags(self, tagList=None): - """Set or get the list of bindtags for this widget. - - With no argument return the list of all bindtags associated with - this widget. With a list of strings as argument the bindtags are - set to this list. The bindtags determine in which order events are - processed (see bind).""" - if tagList is None: - return self.tk.splitlist( - self.tk.call('bindtags', self._w)) - else: - self.tk.call('bindtags', self._w, tagList) - def _bind(self, what, sequence, func, add, needcleanup=1): - """Internal function.""" - if isinstance(func, str): - self.tk.call(what + (sequence, func)) - elif func: - funcid = self._register(func, self._substitute, - needcleanup) - cmd = ('%sif {"[%s %s]" == "break"} break\n' - % - (add and '+' or '', - funcid, self._subst_format_str)) - self.tk.call(what + (sequence, cmd)) - return funcid - elif sequence: - return self.tk.call(what + (sequence,)) - else: - return self.tk.splitlist(self.tk.call(what)) - def bind(self, sequence=None, func=None, add=None): - """Bind to this widget at event SEQUENCE a call to function FUNC. - - SEQUENCE is a string of concatenated event - patterns. An event pattern is of the form - where MODIFIER is one - of Control, Mod2, M2, Shift, Mod3, M3, Lock, Mod4, M4, - Button1, B1, Mod5, M5 Button2, B2, Meta, M, Button3, - B3, Alt, Button4, B4, Double, Button5, B5 Triple, - Mod1, M1. TYPE is one of Activate, Enter, Map, - ButtonPress, Button, Expose, Motion, ButtonRelease - FocusIn, MouseWheel, Circulate, FocusOut, Property, - Colormap, Gravity Reparent, Configure, KeyPress, Key, - Unmap, Deactivate, KeyRelease Visibility, Destroy, - Leave and DETAIL is the button number for ButtonPress, - ButtonRelease and DETAIL is the Keysym for KeyPress and - KeyRelease. Examples are - for pressing Control and mouse button 1 or - for pressing A and the Alt key (KeyPress can be omitted). - An event pattern can also be a virtual event of the form - <> where AString can be arbitrary. This - event can be generated by event_generate. - If events are concatenated they must appear shortly - after each other. - - FUNC will be called if the event sequence occurs with an - instance of Event as argument. If the return value of FUNC is - "break" no further bound function is invoked. - - An additional boolean parameter ADD specifies whether FUNC will - be called additionally to the other bound function or whether - it will replace the previous function. - - Bind will return an identifier to allow deletion of the bound function with - unbind without memory leak. - - If FUNC or SEQUENCE is omitted the bound function or list - of bound events are returned.""" - - return self._bind(('bind', self._w), sequence, func, add) - def unbind(self, sequence, funcid=None): - """Unbind for this widget for event SEQUENCE the - function identified with FUNCID.""" - self.tk.call('bind', self._w, sequence, '') - if funcid: - self.deletecommand(funcid) - def bind_all(self, sequence=None, func=None, add=None): - """Bind to all widgets at an event SEQUENCE a call to function FUNC. - An additional boolean parameter ADD specifies whether FUNC will - be called additionally to the other bound function or whether - it will replace the previous function. See bind for the return value.""" - return self._bind(('bind', 'all'), sequence, func, add, 0) - def unbind_all(self, sequence): - """Unbind for all widgets for event SEQUENCE all functions.""" - self.tk.call('bind', 'all' , sequence, '') - def bind_class(self, className, sequence=None, func=None, add=None): - - """Bind to widgets with bindtag CLASSNAME at event - SEQUENCE a call of function FUNC. An additional - boolean parameter ADD specifies whether FUNC will be - called additionally to the other bound function or - whether it will replace the previous function. See bind for - the return value.""" - - return self._bind(('bind', className), sequence, func, add, 0) - def unbind_class(self, className, sequence): - """Unbind for a all widgets with bindtag CLASSNAME for event SEQUENCE - all functions.""" - self.tk.call('bind', className , sequence, '') - def mainloop(self, n=0): - """Call the mainloop of Tk.""" - self.tk.mainloop(n) - def quit(self): - """Quit the Tcl interpreter. All widgets will be destroyed.""" - self.tk.quit() - def _getints(self, string): - """Internal function.""" - if string: - return tuple(map(getint, self.tk.splitlist(string))) - def _getdoubles(self, string): - """Internal function.""" - if string: - return tuple(map(getdouble, self.tk.splitlist(string))) - def _getboolean(self, string): - """Internal function.""" - if string: - return self.tk.getboolean(string) - def _displayof(self, displayof): - """Internal function.""" - if displayof: - return ('-displayof', displayof) - if displayof is None: - return ('-displayof', self._w) - return () - def _options(self, cnf, kw = None): - """Internal function.""" - if kw: - cnf = _cnfmerge((cnf, kw)) - else: - cnf = _cnfmerge(cnf) - res = () - for k, v in cnf.items(): - if v is not None: - if k[-1] == '_': k = k[:-1] - if hasattr(v, '__call__'): - v = self._register(v) - res = res + ('-'+k, v) - return res - def nametowidget(self, name): - """Return the Tkinter instance of a widget identified by - its Tcl name NAME.""" - w = self - if name[0] == '.': - w = w._root() - name = name[1:] - while name: - i = name.find('.') - if i >= 0: - name, tail = name[:i], name[i+1:] - else: - tail = '' - w = w.children[name] - name = tail - return w - _nametowidget = nametowidget - def _register(self, func, subst=None, needcleanup=1): - """Return a newly created Tcl function. If this - function is called, the Python function FUNC will - be executed. An optional function SUBST can - be given which will be executed before FUNC.""" - f = CallWrapper(func, subst, self).__call__ - name = repr(id(f)) - try: - func = func.__func__ - except AttributeError: - pass - try: - name = name + func.__name__ - except AttributeError: - pass - self.tk.createcommand(name, f) - if needcleanup: - if self._tclCommands is None: - self._tclCommands = [] - self._tclCommands.append(name) - #print '+ Tkinter created command', name - return name - register = _register - def _root(self): - """Internal function.""" - w = self - while w.master: w = w.master - return w - _subst_format = ('%#', '%b', '%f', '%h', '%k', - '%s', '%t', '%w', '%x', '%y', - '%A', '%E', '%K', '%N', '%W', '%T', '%X', '%Y', '%D') - _subst_format_str = " ".join(_subst_format) - def _substitute(self, *args): - """Internal function.""" - if len(args) != len(self._subst_format): return args - getboolean = self.tk.getboolean - - getint = int - def getint_event(s): - """Tk changed behavior in 8.4.2, returning "??" rather more often.""" - try: - return int(s) - except ValueError: - return s - - nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, W, T, X, Y, D = args - # Missing: (a, c, d, m, o, v, B, R) - e = Event() - # serial field: valid vor all events - # number of button: ButtonPress and ButtonRelease events only - # height field: Configure, ConfigureRequest, Create, - # ResizeRequest, and Expose events only - # keycode field: KeyPress and KeyRelease events only - # time field: "valid for events that contain a time field" - # width field: Configure, ConfigureRequest, Create, ResizeRequest, - # and Expose events only - # x field: "valid for events that contain a x field" - # y field: "valid for events that contain a y field" - # keysym as decimal: KeyPress and KeyRelease events only - # x_root, y_root fields: ButtonPress, ButtonRelease, KeyPress, - # KeyRelease,and Motion events - e.serial = getint(nsign) - e.num = getint_event(b) - try: e.focus = getboolean(f) - except TclError: pass - e.height = getint_event(h) - e.keycode = getint_event(k) - e.state = getint_event(s) - e.time = getint_event(t) - e.width = getint_event(w) - e.x = getint_event(x) - e.y = getint_event(y) - e.char = A - try: e.send_event = getboolean(E) - except TclError: pass - e.keysym = K - e.keysym_num = getint_event(N) - e.type = T - try: - e.widget = self._nametowidget(W) - except KeyError: - e.widget = W - e.x_root = getint_event(X) - e.y_root = getint_event(Y) - try: - e.delta = getint(D) - except ValueError: - e.delta = 0 - return (e,) - def _report_exception(self): - """Internal function.""" - import sys - exc, val, tb = sys.exc_info() - root = self._root() - root.report_callback_exception(exc, val, tb) - def _configure(self, cmd, cnf, kw): - """Internal function.""" - if kw: - cnf = _cnfmerge((cnf, kw)) - elif cnf: - cnf = _cnfmerge(cnf) - if cnf is None: - cnf = {} - for x in self.tk.split( - self.tk.call(_flatten((self._w, cmd)))): - cnf[x[0][1:]] = (x[0][1:],) + x[1:] - return cnf - if isinstance(cnf, str): - x = self.tk.split( - self.tk.call(_flatten((self._w, cmd, '-'+cnf)))) - return (x[0][1:],) + x[1:] - self.tk.call(_flatten((self._w, cmd)) + self._options(cnf)) - # These used to be defined in Widget: - def configure(self, cnf=None, **kw): - """Configure resources of a widget. - - The values for resources are specified as keyword - arguments. To get an overview about - the allowed keyword arguments call the method keys. - """ - return self._configure('configure', cnf, kw) - config = configure - def cget(self, key): - """Return the resource value for a KEY given as string.""" - return self.tk.call(self._w, 'cget', '-' + key) - __getitem__ = cget - def __setitem__(self, key, value): - self.configure({key: value}) - def keys(self): - """Return a list of all resource names of this widget.""" - return map(lambda x: x[0][1:], - self.tk.split(self.tk.call(self._w, 'configure'))) - def __str__(self): - """Return the window path name of this widget.""" - return self._w - # Pack methods that apply to the master - _noarg_ = ['_noarg_'] - def pack_propagate(self, flag=_noarg_): - """Set or get the status for propagation of geometry information. - - A boolean argument specifies whether the geometry information - of the slaves will determine the size of this widget. If no argument - is given the current setting will be returned. - """ - if flag is Misc._noarg_: - return self._getboolean(self.tk.call( - 'pack', 'propagate', self._w)) - else: - self.tk.call('pack', 'propagate', self._w, flag) - propagate = pack_propagate - def pack_slaves(self): - """Return a list of all slaves of this widget - in its packing order.""" - return map(self._nametowidget, - self.tk.splitlist( - self.tk.call('pack', 'slaves', self._w))) - slaves = pack_slaves - # Place method that applies to the master - def place_slaves(self): - """Return a list of all slaves of this widget - in its packing order.""" - return map(self._nametowidget, - self.tk.splitlist( - self.tk.call( - 'place', 'slaves', self._w))) - # Grid methods that apply to the master - def grid_bbox(self, column=None, row=None, col2=None, row2=None): - """Return a tuple of integer coordinates for the bounding - box of this widget controlled by the geometry manager grid. - - If COLUMN, ROW is given the bounding box applies from - the cell with row and column 0 to the specified - cell. If COL2 and ROW2 are given the bounding box - starts at that cell. - - The returned integers specify the offset of the upper left - corner in the master widget and the width and height. - """ - args = ('grid', 'bbox', self._w) - if column is not None and row is not None: - args = args + (column, row) - if col2 is not None and row2 is not None: - args = args + (col2, row2) - return self._getints(self.tk.call(*args)) or None - - bbox = grid_bbox - def _grid_configure(self, command, index, cnf, kw): - """Internal function.""" - if isinstance(cnf, str) and not kw: - if cnf[-1:] == '_': - cnf = cnf[:-1] - if cnf[:1] != '-': - cnf = '-'+cnf - options = (cnf,) - else: - options = self._options(cnf, kw) - if not options: - res = self.tk.call('grid', - command, self._w, index) - words = self.tk.splitlist(res) - dict = {} - for i in range(0, len(words), 2): - key = words[i][1:] - value = words[i+1] - if not value: - value = None - elif '.' in value: - value = getdouble(value) - else: - value = getint(value) - dict[key] = value - return dict - res = self.tk.call( - ('grid', command, self._w, index) - + options) - if len(options) == 1: - if not res: return None - # In Tk 7.5, -width can be a float - if '.' in res: return getdouble(res) - return getint(res) - def grid_columnconfigure(self, index, cnf={}, **kw): - """Configure column INDEX of a grid. - - Valid resources are minsize (minimum size of the column), - weight (how much does additional space propagate to this column) - and pad (how much space to let additionally).""" - return self._grid_configure('columnconfigure', index, cnf, kw) - columnconfigure = grid_columnconfigure - def grid_location(self, x, y): - """Return a tuple of column and row which identify the cell - at which the pixel at position X and Y inside the master - widget is located.""" - return self._getints( - self.tk.call( - 'grid', 'location', self._w, x, y)) or None - def grid_propagate(self, flag=_noarg_): - """Set or get the status for propagation of geometry information. - - A boolean argument specifies whether the geometry information - of the slaves will determine the size of this widget. If no argument - is given, the current setting will be returned. - """ - if flag is Misc._noarg_: - return self._getboolean(self.tk.call( - 'grid', 'propagate', self._w)) - else: - self.tk.call('grid', 'propagate', self._w, flag) - def grid_rowconfigure(self, index, cnf={}, **kw): - """Configure row INDEX of a grid. - - Valid resources are minsize (minimum size of the row), - weight (how much does additional space propagate to this row) - and pad (how much space to let additionally).""" - return self._grid_configure('rowconfigure', index, cnf, kw) - rowconfigure = grid_rowconfigure - def grid_size(self): - """Return a tuple of the number of column and rows in the grid.""" - return self._getints( - self.tk.call('grid', 'size', self._w)) or None - size = grid_size - def grid_slaves(self, row=None, column=None): - """Return a list of all slaves of this widget - in its packing order.""" - args = () - if row is not None: - args = args + ('-row', row) - if column is not None: - args = args + ('-column', column) - return map(self._nametowidget, - self.tk.splitlist(self.tk.call( - ('grid', 'slaves', self._w) + args))) - - # Support for the "event" command, new in Tk 4.2. - # By Case Roole. - - def event_add(self, virtual, *sequences): - """Bind a virtual event VIRTUAL (of the form <>) - to an event SEQUENCE such that the virtual event is triggered - whenever SEQUENCE occurs.""" - args = ('event', 'add', virtual) + sequences - self.tk.call(args) - - def event_delete(self, virtual, *sequences): - """Unbind a virtual event VIRTUAL from SEQUENCE.""" - args = ('event', 'delete', virtual) + sequences - self.tk.call(args) - - def event_generate(self, sequence, **kw): - """Generate an event SEQUENCE. Additional - keyword arguments specify parameter of the event - (e.g. x, y, rootx, rooty).""" - args = ('event', 'generate', self._w, sequence) - for k, v in kw.items(): - args = args + ('-%s' % k, str(v)) - self.tk.call(args) - - def event_info(self, virtual=None): - """Return a list of all virtual events or the information - about the SEQUENCE bound to the virtual event VIRTUAL.""" - return self.tk.splitlist( - self.tk.call('event', 'info', virtual)) - - # Image related commands - - def image_names(self): - """Return a list of all existing image names.""" - return self.tk.call('image', 'names') - - def image_types(self): - """Return a list of all available image types (e.g. phote bitmap).""" - return self.tk.call('image', 'types') - - -class CallWrapper: - """Internal class. Stores function to call when some user - defined Tcl function is called e.g. after an event occurred.""" - def __init__(self, func, subst, widget): - """Store FUNC, SUBST and WIDGET as members.""" - self.func = func - self.subst = subst - self.widget = widget - def __call__(self, *args): - """Apply first function SUBST to arguments, than FUNC.""" - try: - if self.subst: - args = self.subst(*args) - return self.func(*args) - except SystemExit as msg: - raise SystemExit(msg) - except: - self.widget._report_exception() - - -class Wm: - """Provides functions for the communication with the window manager.""" - - def wm_aspect(self, - minNumer=None, minDenom=None, - maxNumer=None, maxDenom=None): - """Instruct the window manager to set the aspect ratio (width/height) - of this widget to be between MINNUMER/MINDENOM and MAXNUMER/MAXDENOM. Return a tuple - of the actual values if no argument is given.""" - return self._getints( - self.tk.call('wm', 'aspect', self._w, - minNumer, minDenom, - maxNumer, maxDenom)) - aspect = wm_aspect - - def wm_attributes(self, *args): - """This subcommand returns or sets platform specific attributes - - The first form returns a list of the platform specific flags and - their values. The second form returns the value for the specific - option. The third form sets one or more of the values. The values - are as follows: - - On Windows, -disabled gets or sets whether the window is in a - disabled state. -toolwindow gets or sets the style of the window - to toolwindow (as defined in the MSDN). -topmost gets or sets - whether this is a topmost window (displays above all other - windows). - - On Macintosh, XXXXX - - On Unix, there are currently no special attribute values. - """ - args = ('wm', 'attributes', self._w) + args - return self.tk.call(args) - attributes=wm_attributes - - def wm_client(self, name=None): - """Store NAME in WM_CLIENT_MACHINE property of this widget. Return - current value.""" - return self.tk.call('wm', 'client', self._w, name) - client = wm_client - def wm_colormapwindows(self, *wlist): - """Store list of window names (WLIST) into WM_COLORMAPWINDOWS property - of this widget. This list contains windows whose colormaps differ from their - parents. Return current list of widgets if WLIST is empty.""" - if len(wlist) > 1: - wlist = (wlist,) # Tk needs a list of windows here - args = ('wm', 'colormapwindows', self._w) + wlist - return map(self._nametowidget, self.tk.call(args)) - colormapwindows = wm_colormapwindows - def wm_command(self, value=None): - """Store VALUE in WM_COMMAND property. It is the command - which shall be used to invoke the application. Return current - command if VALUE is None.""" - return self.tk.call('wm', 'command', self._w, value) - command = wm_command - def wm_deiconify(self): - """Deiconify this widget. If it was never mapped it will not be mapped. - On Windows it will raise this widget and give it the focus.""" - return self.tk.call('wm', 'deiconify', self._w) - deiconify = wm_deiconify - def wm_focusmodel(self, model=None): - """Set focus model to MODEL. "active" means that this widget will claim - the focus itself, "passive" means that the window manager shall give - the focus. Return current focus model if MODEL is None.""" - return self.tk.call('wm', 'focusmodel', self._w, model) - focusmodel = wm_focusmodel - def wm_frame(self): - """Return identifier for decorative frame of this widget if present.""" - return self.tk.call('wm', 'frame', self._w) - frame = wm_frame - def wm_geometry(self, newGeometry=None): - """Set geometry to NEWGEOMETRY of the form =widthxheight+x+y. Return - current value if None is given.""" - return self.tk.call('wm', 'geometry', self._w, newGeometry) - geometry = wm_geometry - def wm_grid(self, - baseWidth=None, baseHeight=None, - widthInc=None, heightInc=None): - """Instruct the window manager that this widget shall only be - resized on grid boundaries. WIDTHINC and HEIGHTINC are the width and - height of a grid unit in pixels. BASEWIDTH and BASEHEIGHT are the - number of grid units requested in Tk_GeometryRequest.""" - return self._getints(self.tk.call( - 'wm', 'grid', self._w, - baseWidth, baseHeight, widthInc, heightInc)) - grid = wm_grid - def wm_group(self, pathName=None): - """Set the group leader widgets for related widgets to PATHNAME. Return - the group leader of this widget if None is given.""" - return self.tk.call('wm', 'group', self._w, pathName) - group = wm_group - def wm_iconbitmap(self, bitmap=None, default=None): - """Set bitmap for the iconified widget to BITMAP. Return - the bitmap if None is given. - - Under Windows, the DEFAULT parameter can be used to set the icon - for the widget and any descendents that don't have an icon set - explicitly. DEFAULT can be the relative path to a .ico file - (example: root.iconbitmap(default='myicon.ico') ). See Tk - documentation for more information.""" - if default: - return self.tk.call('wm', 'iconbitmap', self._w, '-default', default) - else: - return self.tk.call('wm', 'iconbitmap', self._w, bitmap) - iconbitmap = wm_iconbitmap - def wm_iconify(self): - """Display widget as icon.""" - return self.tk.call('wm', 'iconify', self._w) - iconify = wm_iconify - def wm_iconmask(self, bitmap=None): - """Set mask for the icon bitmap of this widget. Return the - mask if None is given.""" - return self.tk.call('wm', 'iconmask', self._w, bitmap) - iconmask = wm_iconmask - def wm_iconname(self, newName=None): - """Set the name of the icon for this widget. Return the name if - None is given.""" - return self.tk.call('wm', 'iconname', self._w, newName) - iconname = wm_iconname - def wm_iconposition(self, x=None, y=None): - """Set the position of the icon of this widget to X and Y. Return - a tuple of the current values of X and X if None is given.""" - return self._getints(self.tk.call( - 'wm', 'iconposition', self._w, x, y)) - iconposition = wm_iconposition - def wm_iconwindow(self, pathName=None): - """Set widget PATHNAME to be displayed instead of icon. Return the current - value if None is given.""" - return self.tk.call('wm', 'iconwindow', self._w, pathName) - iconwindow = wm_iconwindow - def wm_maxsize(self, width=None, height=None): - """Set max WIDTH and HEIGHT for this widget. If the window is gridded - the values are given in grid units. Return the current values if None - is given.""" - return self._getints(self.tk.call( - 'wm', 'maxsize', self._w, width, height)) - maxsize = wm_maxsize - def wm_minsize(self, width=None, height=None): - """Set min WIDTH and HEIGHT for this widget. If the window is gridded - the values are given in grid units. Return the current values if None - is given.""" - return self._getints(self.tk.call( - 'wm', 'minsize', self._w, width, height)) - minsize = wm_minsize - def wm_overrideredirect(self, boolean=None): - """Instruct the window manager to ignore this widget - if BOOLEAN is given with 1. Return the current value if None - is given.""" - return self._getboolean(self.tk.call( - 'wm', 'overrideredirect', self._w, boolean)) - overrideredirect = wm_overrideredirect - def wm_positionfrom(self, who=None): - """Instruct the window manager that the position of this widget shall - be defined by the user if WHO is "user", and by its own policy if WHO is - "program".""" - return self.tk.call('wm', 'positionfrom', self._w, who) - positionfrom = wm_positionfrom - def wm_protocol(self, name=None, func=None): - """Bind function FUNC to command NAME for this widget. - Return the function bound to NAME if None is given. NAME could be - e.g. "WM_SAVE_YOURSELF" or "WM_DELETE_WINDOW".""" - if hasattr(func, '__call__'): - command = self._register(func) - else: - command = func - return self.tk.call( - 'wm', 'protocol', self._w, name, command) - protocol = wm_protocol - def wm_resizable(self, width=None, height=None): - """Instruct the window manager whether this width can be resized - in WIDTH or HEIGHT. Both values are boolean values.""" - return self.tk.call('wm', 'resizable', self._w, width, height) - resizable = wm_resizable - def wm_sizefrom(self, who=None): - """Instruct the window manager that the size of this widget shall - be defined by the user if WHO is "user", and by its own policy if WHO is - "program".""" - return self.tk.call('wm', 'sizefrom', self._w, who) - sizefrom = wm_sizefrom - def wm_state(self, newstate=None): - """Query or set the state of this widget as one of normal, icon, - iconic (see wm_iconwindow), withdrawn, or zoomed (Windows only).""" - return self.tk.call('wm', 'state', self._w, newstate) - state = wm_state - def wm_title(self, string=None): - """Set the title of this widget.""" - return self.tk.call('wm', 'title', self._w, string) - title = wm_title - def wm_transient(self, master=None): - """Instruct the window manager that this widget is transient - with regard to widget MASTER.""" - return self.tk.call('wm', 'transient', self._w, master) - transient = wm_transient - def wm_withdraw(self): - """Withdraw this widget from the screen such that it is unmapped - and forgotten by the window manager. Re-draw it with wm_deiconify.""" - return self.tk.call('wm', 'withdraw', self._w) - withdraw = wm_withdraw - - -class Tk(Misc, Wm): - """Toplevel widget of Tk which represents mostly the main window - of an appliation. It has an associated Tcl interpreter.""" - _w = '.' - def __init__(self, screenName=None, baseName=None, className='Tk', - useTk=1, sync=0, use=None): - """Return a new Toplevel widget on screen SCREENNAME. A new Tcl interpreter will - be created. BASENAME will be used for the identification of the profile file (see - readprofile). - It is constructed from sys.argv[0] without extensions if None is given. CLASSNAME - is the name of the widget class.""" - self.master = None - self.children = {} - self._tkloaded = 0 - # to avoid recursions in the getattr code in case of failure, we - # ensure that self.tk is always _something_. - self.tk = None - if baseName is None: - import sys, os - baseName = os.path.basename(sys.argv[0]) - baseName, ext = os.path.splitext(baseName) - if ext not in ('.py', '.pyc', '.pyo'): - baseName = baseName + ext - interactive = 0 - self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use) - if useTk: - self._loadtk() - self.readprofile(baseName, className) - def loadtk(self): - if not self._tkloaded: - self.tk.loadtk() - self._loadtk() - def _loadtk(self): - self._tkloaded = 1 - global _default_root - if _MacOS and hasattr(_MacOS, 'SchedParams'): - # Disable event scanning except for Command-Period - _MacOS.SchedParams(1, 0) - # Work around nasty MacTk bug - # XXX Is this one still needed? - self.update() - # Version sanity checks - tk_version = self.tk.getvar('tk_version') - if tk_version != _tkinter.TK_VERSION: - raise RuntimeError("tk.h version (%s) doesn't match libtk.a version (%s)" - % (_tkinter.TK_VERSION, tk_version)) - # Under unknown circumstances, tcl_version gets coerced to float - tcl_version = str(self.tk.getvar('tcl_version')) - if tcl_version != _tkinter.TCL_VERSION: - raise RuntimeError("tcl.h version (%s) doesn't match libtcl.a version (%s)" \ - % (_tkinter.TCL_VERSION, tcl_version)) - if TkVersion < 4.0: - raise RuntimeError("Tk 4.0 or higher is required; found Tk %s" - % str(TkVersion)) - # Create and register the tkerror and exit commands - # We need to inline parts of _register here, _ register - # would register differently-named commands. - if self._tclCommands is None: - self._tclCommands = [] - self.tk.createcommand('tkerror', _tkerror) - self.tk.createcommand('exit', _exit) - self._tclCommands.append('tkerror') - self._tclCommands.append('exit') - if _support_default_root and not _default_root: - _default_root = self - self.protocol("WM_DELETE_WINDOW", self.destroy) - def destroy(self): - """Destroy this and all descendants widgets. This will - end the application of this Tcl interpreter.""" - for c in list(self.children.values()): c.destroy() - self.tk.call('destroy', self._w) - Misc.destroy(self) - global _default_root - if _support_default_root and _default_root is self: - _default_root = None - def readprofile(self, baseName, className): - """Internal function. It reads BASENAME.tcl and CLASSNAME.tcl into - the Tcl Interpreter and calls exec on the contents of BASENAME.py and - CLASSNAME.py if such a file exists in the home directory.""" - import os - if 'HOME' in os.environ: home = os.environ['HOME'] - else: home = os.curdir - class_tcl = os.path.join(home, '.%s.tcl' % className) - class_py = os.path.join(home, '.%s.py' % className) - base_tcl = os.path.join(home, '.%s.tcl' % baseName) - base_py = os.path.join(home, '.%s.py' % baseName) - dir = {'self': self} - exec('from Tkinter import *', dir) - if os.path.isfile(class_tcl): - self.tk.call('source', class_tcl) - if os.path.isfile(class_py): - exec(open(class_py).read(), dir) - if os.path.isfile(base_tcl): - self.tk.call('source', base_tcl) - if os.path.isfile(base_py): - exec(open(base_py).read(), dir) - def report_callback_exception(self, exc, val, tb): - """Internal function. It reports exception on sys.stderr.""" - import traceback, sys - sys.stderr.write("Exception in Tkinter callback\n") - sys.last_type = exc - sys.last_value = val - sys.last_traceback = tb - traceback.print_exception(exc, val, tb) - def __getattr__(self, attr): - "Delegate attribute access to the interpreter object" - return getattr(self.tk, attr) - -# Ideally, the classes Pack, Place and Grid disappear, the -# pack/place/grid methods are defined on the Widget class, and -# everybody uses w.pack_whatever(...) instead of Pack.whatever(w, -# ...), with pack(), place() and grid() being short for -# pack_configure(), place_configure() and grid_columnconfigure(), and -# forget() being short for pack_forget(). As a practical matter, I'm -# afraid that there is too much code out there that may be using the -# Pack, Place or Grid class, so I leave them intact -- but only as -# backwards compatibility features. Also note that those methods that -# take a master as argument (e.g. pack_propagate) have been moved to -# the Misc class (which now incorporates all methods common between -# toplevel and interior widgets). Again, for compatibility, these are -# copied into the Pack, Place or Grid class. - - -def Tcl(screenName=None, baseName=None, className='Tk', useTk=0): - return Tk(screenName, baseName, className, useTk) - -class Pack: - """Geometry manager Pack. - - Base class to use the methods pack_* in every widget.""" - def pack_configure(self, cnf={}, **kw): - """Pack a widget in the parent widget. Use as options: - after=widget - pack it after you have packed widget - anchor=NSEW (or subset) - position widget according to - given direction - before=widget - pack it before you will pack widget - expand=bool - expand widget if parent size grows - fill=NONE or X or Y or BOTH - fill widget if widget grows - in=master - use master to contain this widget - ipadx=amount - add internal padding in x direction - ipady=amount - add internal padding in y direction - padx=amount - add padding in x direction - pady=amount - add padding in y direction - side=TOP or BOTTOM or LEFT or RIGHT - where to add this widget. - """ - self.tk.call( - ('pack', 'configure', self._w) - + self._options(cnf, kw)) - pack = configure = config = pack_configure - def pack_forget(self): - """Unmap this widget and do not use it for the packing order.""" - self.tk.call('pack', 'forget', self._w) - forget = pack_forget - def pack_info(self): - """Return information about the packing options - for this widget.""" - words = self.tk.splitlist( - self.tk.call('pack', 'info', self._w)) - dict = {} - for i in range(0, len(words), 2): - key = words[i][1:] - value = words[i+1] - if value[:1] == '.': - value = self._nametowidget(value) - dict[key] = value - return dict - info = pack_info - propagate = pack_propagate = Misc.pack_propagate - slaves = pack_slaves = Misc.pack_slaves - -class Place: - """Geometry manager Place. - - Base class to use the methods place_* in every widget.""" - def place_configure(self, cnf={}, **kw): - """Place a widget in the parent widget. Use as options: - in=master - master relative to which the widget is placed. - x=amount - locate anchor of this widget at position x of master - y=amount - locate anchor of this widget at position y of master - relx=amount - locate anchor of this widget between 0.0 and 1.0 - relative to width of master (1.0 is right edge) - rely=amount - locate anchor of this widget between 0.0 and 1.0 - relative to height of master (1.0 is bottom edge) - anchor=NSEW (or subset) - position anchor according to given direction - width=amount - width of this widget in pixel - height=amount - height of this widget in pixel - relwidth=amount - width of this widget between 0.0 and 1.0 - relative to width of master (1.0 is the same width - as the master) - relheight=amount - height of this widget between 0.0 and 1.0 - relative to height of master (1.0 is the same - height as the master) - bordermode="inside" or "outside" - whether to take border width of master widget - into account - """ - for k in ['in_']: - if k in kw: - kw[k[:-1]] = kw[k] - del kw[k] - self.tk.call( - ('place', 'configure', self._w) - + self._options(cnf, kw)) - place = configure = config = place_configure - def place_forget(self): - """Unmap this widget.""" - self.tk.call('place', 'forget', self._w) - forget = place_forget - def place_info(self): - """Return information about the placing options - for this widget.""" - words = self.tk.splitlist( - self.tk.call('place', 'info', self._w)) - dict = {} - for i in range(0, len(words), 2): - key = words[i][1:] - value = words[i+1] - if value[:1] == '.': - value = self._nametowidget(value) - dict[key] = value - return dict - info = place_info - slaves = place_slaves = Misc.place_slaves - -class Grid: - """Geometry manager Grid. - - Base class to use the methods grid_* in every widget.""" - # Thanks to Masazumi Yoshikawa (yosikawa@isi.edu) - def grid_configure(self, cnf={}, **kw): - """Position a widget in the parent widget in a grid. Use as options: - column=number - use cell identified with given column (starting with 0) - columnspan=number - this widget will span several columns - in=master - use master to contain this widget - ipadx=amount - add internal padding in x direction - ipady=amount - add internal padding in y direction - padx=amount - add padding in x direction - pady=amount - add padding in y direction - row=number - use cell identified with given row (starting with 0) - rowspan=number - this widget will span several rows - sticky=NSEW - if cell is larger on which sides will this - widget stick to the cell boundary - """ - self.tk.call( - ('grid', 'configure', self._w) - + self._options(cnf, kw)) - grid = configure = config = grid_configure - bbox = grid_bbox = Misc.grid_bbox - columnconfigure = grid_columnconfigure = Misc.grid_columnconfigure - def grid_forget(self): - """Unmap this widget.""" - self.tk.call('grid', 'forget', self._w) - forget = grid_forget - def grid_remove(self): - """Unmap this widget but remember the grid options.""" - self.tk.call('grid', 'remove', self._w) - def grid_info(self): - """Return information about the options - for positioning this widget in a grid.""" - words = self.tk.splitlist( - self.tk.call('grid', 'info', self._w)) - dict = {} - for i in range(0, len(words), 2): - key = words[i][1:] - value = words[i+1] - if value[:1] == '.': - value = self._nametowidget(value) - dict[key] = value - return dict - info = grid_info - location = grid_location = Misc.grid_location - propagate = grid_propagate = Misc.grid_propagate - rowconfigure = grid_rowconfigure = Misc.grid_rowconfigure - size = grid_size = Misc.grid_size - slaves = grid_slaves = Misc.grid_slaves - -class BaseWidget(Misc): - """Internal class.""" - def _setup(self, master, cnf): - """Internal function. Sets up information about children.""" - if _support_default_root: - global _default_root - if not master: - if not _default_root: - _default_root = Tk() - master = _default_root - self.master = master - self.tk = master.tk - name = None - if 'name' in cnf: - name = cnf['name'] - del cnf['name'] - if not name: - name = repr(id(self)) - self._name = name - if master._w=='.': - self._w = '.' + name - else: - self._w = master._w + '.' + name - self.children = {} - if self._name in self.master.children: - self.master.children[self._name].destroy() - self.master.children[self._name] = self - def __init__(self, master, widgetName, cnf={}, kw={}, extra=()): - """Construct a widget with the parent widget MASTER, a name WIDGETNAME - and appropriate options.""" - if kw: - cnf = _cnfmerge((cnf, kw)) - self.widgetName = widgetName - BaseWidget._setup(self, master, cnf) - classes = [] - for k in cnf.keys(): - if isinstance(k, type): - classes.append((k, cnf[k])) - del cnf[k] - self.tk.call( - (widgetName, self._w) + extra + self._options(cnf)) - for k, v in classes: - k.configure(self, v) - def destroy(self): - """Destroy this and all descendants widgets.""" - for c in list(self.children.values()): c.destroy() - self.tk.call('destroy', self._w) - if self._name in self.master.children: - del self.master.children[self._name] - Misc.destroy(self) - def _do(self, name, args=()): - # XXX Obsolete -- better use self.tk.call directly! - return self.tk.call((self._w, name) + args) - -class Widget(BaseWidget, Pack, Place, Grid): - """Internal class. - - Base class for a widget which can be positioned with the geometry managers - Pack, Place or Grid.""" - pass - -class Toplevel(BaseWidget, Wm): - """Toplevel widget, e.g. for dialogs.""" - def __init__(self, master=None, cnf={}, **kw): - """Construct a toplevel widget with the parent MASTER. - - Valid resource names: background, bd, bg, borderwidth, class, - colormap, container, cursor, height, highlightbackground, - highlightcolor, highlightthickness, menu, relief, screen, takefocus, - use, visual, width.""" - if kw: - cnf = _cnfmerge((cnf, kw)) - extra = () - for wmkey in ['screen', 'class_', 'class', 'visual', - 'colormap']: - if wmkey in cnf: - val = cnf[wmkey] - # TBD: a hack needed because some keys - # are not valid as keyword arguments - if wmkey[-1] == '_': opt = '-'+wmkey[:-1] - else: opt = '-'+wmkey - extra = extra + (opt, val) - del cnf[wmkey] - BaseWidget.__init__(self, master, 'toplevel', cnf, {}, extra) - root = self._root() - self.iconname(root.iconname()) - self.title(root.title()) - self.protocol("WM_DELETE_WINDOW", self.destroy) - -class Button(Widget): - """Button widget.""" - def __init__(self, master=None, cnf={}, **kw): - """Construct a button widget with the parent MASTER. - - STANDARD OPTIONS - - activebackground, activeforeground, anchor, - background, bitmap, borderwidth, cursor, - disabledforeground, font, foreground - highlightbackground, highlightcolor, - highlightthickness, image, justify, - padx, pady, relief, repeatdelay, - repeatinterval, takefocus, text, - textvariable, underline, wraplength - - WIDGET-SPECIFIC OPTIONS - - command, compound, default, height, - overrelief, state, width - """ - Widget.__init__(self, master, 'button', cnf, kw) - - def tkButtonEnter(self, *dummy): - self.tk.call('tkButtonEnter', self._w) - - def tkButtonLeave(self, *dummy): - self.tk.call('tkButtonLeave', self._w) - - def tkButtonDown(self, *dummy): - self.tk.call('tkButtonDown', self._w) - - def tkButtonUp(self, *dummy): - self.tk.call('tkButtonUp', self._w) - - def tkButtonInvoke(self, *dummy): - self.tk.call('tkButtonInvoke', self._w) - - def flash(self): - """Flash the button. - - This is accomplished by redisplaying - the button several times, alternating between active and - normal colors. At the end of the flash the button is left - in the same normal/active state as when the command was - invoked. This command is ignored if the button's state is - disabled. - """ - self.tk.call(self._w, 'flash') - - def invoke(self): - """Invoke the command associated with the button. - - The return value is the return value from the command, - or an empty string if there is no command associated with - the button. This command is ignored if the button's state - is disabled. - """ - return self.tk.call(self._w, 'invoke') - -# Indices: -# XXX I don't like these -- take them away -def AtEnd(): - return 'end' -def AtInsert(*args): - s = 'insert' - for a in args: - if a: s = s + (' ' + a) - return s -def AtSelFirst(): - return 'sel.first' -def AtSelLast(): - return 'sel.last' -def At(x, y=None): - if y is None: - return '@%r' % (x,) - else: - return '@%r,%r' % (x, y) - -class Canvas(Widget): - """Canvas widget to display graphical elements like lines or text.""" - def __init__(self, master=None, cnf={}, **kw): - """Construct a canvas widget with the parent MASTER. - - Valid resource names: background, bd, bg, borderwidth, closeenough, - confine, cursor, height, highlightbackground, highlightcolor, - highlightthickness, insertbackground, insertborderwidth, - insertofftime, insertontime, insertwidth, offset, relief, - scrollregion, selectbackground, selectborderwidth, selectforeground, - state, takefocus, width, xscrollcommand, xscrollincrement, - yscrollcommand, yscrollincrement.""" - Widget.__init__(self, master, 'canvas', cnf, kw) - def addtag(self, *args): - """Internal function.""" - self.tk.call((self._w, 'addtag') + args) - def addtag_above(self, newtag, tagOrId): - """Add tag NEWTAG to all items above TAGORID.""" - self.addtag(newtag, 'above', tagOrId) - def addtag_all(self, newtag): - """Add tag NEWTAG to all items.""" - self.addtag(newtag, 'all') - def addtag_below(self, newtag, tagOrId): - """Add tag NEWTAG to all items below TAGORID.""" - self.addtag(newtag, 'below', tagOrId) - def addtag_closest(self, newtag, x, y, halo=None, start=None): - """Add tag NEWTAG to item which is closest to pixel at X, Y. - If several match take the top-most. - All items closer than HALO are considered overlapping (all are - closests). If START is specified the next below this tag is taken.""" - self.addtag(newtag, 'closest', x, y, halo, start) - def addtag_enclosed(self, newtag, x1, y1, x2, y2): - """Add tag NEWTAG to all items in the rectangle defined - by X1,Y1,X2,Y2.""" - self.addtag(newtag, 'enclosed', x1, y1, x2, y2) - def addtag_overlapping(self, newtag, x1, y1, x2, y2): - """Add tag NEWTAG to all items which overlap the rectangle - defined by X1,Y1,X2,Y2.""" - self.addtag(newtag, 'overlapping', x1, y1, x2, y2) - def addtag_withtag(self, newtag, tagOrId): - """Add tag NEWTAG to all items with TAGORID.""" - self.addtag(newtag, 'withtag', tagOrId) - def bbox(self, *args): - """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle - which encloses all items with tags specified as arguments.""" - return self._getints( - self.tk.call((self._w, 'bbox') + args)) or None - def tag_unbind(self, tagOrId, sequence, funcid=None): - """Unbind for all items with TAGORID for event SEQUENCE the - function identified with FUNCID.""" - self.tk.call(self._w, 'bind', tagOrId, sequence, '') - if funcid: - self.deletecommand(funcid) - def tag_bind(self, tagOrId, sequence=None, func=None, add=None): - """Bind to all items with TAGORID at event SEQUENCE a call to function FUNC. - - An additional boolean parameter ADD specifies whether FUNC will be - called additionally to the other bound function or whether it will - replace the previous function. See bind for the return value.""" - return self._bind((self._w, 'bind', tagOrId), - sequence, func, add) - def canvasx(self, screenx, gridspacing=None): - """Return the canvas x coordinate of pixel position SCREENX rounded - to nearest multiple of GRIDSPACING units.""" - return getdouble(self.tk.call( - self._w, 'canvasx', screenx, gridspacing)) - def canvasy(self, screeny, gridspacing=None): - """Return the canvas y coordinate of pixel position SCREENY rounded - to nearest multiple of GRIDSPACING units.""" - return getdouble(self.tk.call( - self._w, 'canvasy', screeny, gridspacing)) - def coords(self, *args): - """Return a list of coordinates for the item given in ARGS.""" - # XXX Should use _flatten on args - return map(getdouble, - self.tk.splitlist( - self.tk.call((self._w, 'coords') + args))) - def _create(self, itemType, args, kw): # Args: (val, val, ..., cnf={}) - """Internal function.""" - args = _flatten(args) - cnf = args[-1] - if isinstance(cnf, (dict, tuple)): - args = args[:-1] - else: - cnf = {} - return getint(self.tk.call( - self._w, 'create', itemType, - *(args + self._options(cnf, kw)))) - def create_arc(self, *args, **kw): - """Create arc shaped region with coordinates x1,y1,x2,y2.""" - return self._create('arc', args, kw) - def create_bitmap(self, *args, **kw): - """Create bitmap with coordinates x1,y1.""" - return self._create('bitmap', args, kw) - def create_image(self, *args, **kw): - """Create image item with coordinates x1,y1.""" - return self._create('image', args, kw) - def create_line(self, *args, **kw): - """Create line with coordinates x1,y1,...,xn,yn.""" - return self._create('line', args, kw) - def create_oval(self, *args, **kw): - """Create oval with coordinates x1,y1,x2,y2.""" - return self._create('oval', args, kw) - def create_polygon(self, *args, **kw): - """Create polygon with coordinates x1,y1,...,xn,yn.""" - return self._create('polygon', args, kw) - def create_rectangle(self, *args, **kw): - """Create rectangle with coordinates x1,y1,x2,y2.""" - return self._create('rectangle', args, kw) - def create_text(self, *args, **kw): - """Create text with coordinates x1,y1.""" - return self._create('text', args, kw) - def create_window(self, *args, **kw): - """Create window with coordinates x1,y1,x2,y2.""" - return self._create('window', args, kw) - def dchars(self, *args): - """Delete characters of text items identified by tag or id in ARGS (possibly - several times) from FIRST to LAST character (including).""" - self.tk.call((self._w, 'dchars') + args) - def delete(self, *args): - """Delete items identified by all tag or ids contained in ARGS.""" - self.tk.call((self._w, 'delete') + args) - def dtag(self, *args): - """Delete tag or id given as last arguments in ARGS from items - identified by first argument in ARGS.""" - self.tk.call((self._w, 'dtag') + args) - def find(self, *args): - """Internal function.""" - return self._getints( - self.tk.call((self._w, 'find') + args)) or () - def find_above(self, tagOrId): - """Return items above TAGORID.""" - return self.find('above', tagOrId) - def find_all(self): - """Return all items.""" - return self.find('all') - def find_below(self, tagOrId): - """Return all items below TAGORID.""" - return self.find('below', tagOrId) - def find_closest(self, x, y, halo=None, start=None): - """Return item which is closest to pixel at X, Y. - If several match take the top-most. - All items closer than HALO are considered overlapping (all are - closests). If START is specified the next below this tag is taken.""" - return self.find('closest', x, y, halo, start) - def find_enclosed(self, x1, y1, x2, y2): - """Return all items in rectangle defined - by X1,Y1,X2,Y2.""" - return self.find('enclosed', x1, y1, x2, y2) - def find_overlapping(self, x1, y1, x2, y2): - """Return all items which overlap the rectangle - defined by X1,Y1,X2,Y2.""" - return self.find('overlapping', x1, y1, x2, y2) - def find_withtag(self, tagOrId): - """Return all items with TAGORID.""" - return self.find('withtag', tagOrId) - def focus(self, *args): - """Set focus to the first item specified in ARGS.""" - return self.tk.call((self._w, 'focus') + args) - def gettags(self, *args): - """Return tags associated with the first item specified in ARGS.""" - return self.tk.splitlist( - self.tk.call((self._w, 'gettags') + args)) - def icursor(self, *args): - """Set cursor at position POS in the item identified by TAGORID. - In ARGS TAGORID must be first.""" - self.tk.call((self._w, 'icursor') + args) - def index(self, *args): - """Return position of cursor as integer in item specified in ARGS.""" - return getint(self.tk.call((self._w, 'index') + args)) - def insert(self, *args): - """Insert TEXT in item TAGORID at position POS. ARGS must - be TAGORID POS TEXT.""" - self.tk.call((self._w, 'insert') + args) - def itemcget(self, tagOrId, option): - """Return the resource value for an OPTION for item TAGORID.""" - return self.tk.call( - (self._w, 'itemcget') + (tagOrId, '-'+option)) - def itemconfigure(self, tagOrId, cnf=None, **kw): - """Configure resources of an item TAGORID. - - The values for resources are specified as keyword - arguments. To get an overview about - the allowed keyword arguments call the method without arguments. - """ - return self._configure(('itemconfigure', tagOrId), cnf, kw) - itemconfig = itemconfigure - # lower, tkraise/lift hide Misc.lower, Misc.tkraise/lift, - # so the preferred name for them is tag_lower, tag_raise - # (similar to tag_bind, and similar to the Text widget); - # unfortunately can't delete the old ones yet (maybe in 1.6) - def tag_lower(self, *args): - """Lower an item TAGORID given in ARGS - (optional below another item).""" - self.tk.call((self._w, 'lower') + args) - lower = tag_lower - def move(self, *args): - """Move an item TAGORID given in ARGS.""" - self.tk.call((self._w, 'move') + args) - def postscript(self, cnf={}, **kw): - """Print the contents of the canvas to a postscript - file. Valid options: colormap, colormode, file, fontmap, - height, pageanchor, pageheight, pagewidth, pagex, pagey, - rotate, witdh, x, y.""" - return self.tk.call((self._w, 'postscript') + - self._options(cnf, kw)) - def tag_raise(self, *args): - """Raise an item TAGORID given in ARGS - (optional above another item).""" - self.tk.call((self._w, 'raise') + args) - lift = tkraise = tag_raise - def scale(self, *args): - """Scale item TAGORID with XORIGIN, YORIGIN, XSCALE, YSCALE.""" - self.tk.call((self._w, 'scale') + args) - def scan_mark(self, x, y): - """Remember the current X, Y coordinates.""" - self.tk.call(self._w, 'scan', 'mark', x, y) - def scan_dragto(self, x, y, gain=10): - """Adjust the view of the canvas to GAIN times the - difference between X and Y and the coordinates given in - scan_mark.""" - self.tk.call(self._w, 'scan', 'dragto', x, y, gain) - def select_adjust(self, tagOrId, index): - """Adjust the end of the selection near the cursor of an item TAGORID to index.""" - self.tk.call(self._w, 'select', 'adjust', tagOrId, index) - def select_clear(self): - """Clear the selection if it is in this widget.""" - self.tk.call(self._w, 'select', 'clear') - def select_from(self, tagOrId, index): - """Set the fixed end of a selection in item TAGORID to INDEX.""" - self.tk.call(self._w, 'select', 'from', tagOrId, index) - def select_item(self): - """Return the item which has the selection.""" - return self.tk.call(self._w, 'select', 'item') or None - def select_to(self, tagOrId, index): - """Set the variable end of a selection in item TAGORID to INDEX.""" - self.tk.call(self._w, 'select', 'to', tagOrId, index) - def type(self, tagOrId): - """Return the type of the item TAGORID.""" - return self.tk.call(self._w, 'type', tagOrId) or None - def xview(self, *args): - """Query and change horizontal position of the view.""" - if not args: - return self._getdoubles(self.tk.call(self._w, 'xview')) - self.tk.call((self._w, 'xview') + args) - def xview_moveto(self, fraction): - """Adjusts the view in the window so that FRACTION of the - total width of the canvas is off-screen to the left.""" - self.tk.call(self._w, 'xview', 'moveto', fraction) - def xview_scroll(self, number, what): - """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" - self.tk.call(self._w, 'xview', 'scroll', number, what) - def yview(self, *args): - """Query and change vertical position of the view.""" - if not args: - return self._getdoubles(self.tk.call(self._w, 'yview')) - self.tk.call((self._w, 'yview') + args) - def yview_moveto(self, fraction): - """Adjusts the view in the window so that FRACTION of the - total height of the canvas is off-screen to the top.""" - self.tk.call(self._w, 'yview', 'moveto', fraction) - def yview_scroll(self, number, what): - """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" - self.tk.call(self._w, 'yview', 'scroll', number, what) - -class Checkbutton(Widget): - """Checkbutton widget which is either in on- or off-state.""" - def __init__(self, master=None, cnf={}, **kw): - """Construct a checkbutton widget with the parent MASTER. - - Valid resource names: activebackground, activeforeground, anchor, - background, bd, bg, bitmap, borderwidth, command, cursor, - disabledforeground, fg, font, foreground, height, - highlightbackground, highlightcolor, highlightthickness, image, - indicatoron, justify, offvalue, onvalue, padx, pady, relief, - selectcolor, selectimage, state, takefocus, text, textvariable, - underline, variable, width, wraplength.""" - Widget.__init__(self, master, 'checkbutton', cnf, kw) - def deselect(self): - """Put the button in off-state.""" - self.tk.call(self._w, 'deselect') - def flash(self): - """Flash the button.""" - self.tk.call(self._w, 'flash') - def invoke(self): - """Toggle the button and invoke a command if given as resource.""" - return self.tk.call(self._w, 'invoke') - def select(self): - """Put the button in on-state.""" - self.tk.call(self._w, 'select') - def toggle(self): - """Toggle the button.""" - self.tk.call(self._w, 'toggle') - -class Entry(Widget): - """Entry widget which allows to display simple text.""" - def __init__(self, master=None, cnf={}, **kw): - """Construct an entry widget with the parent MASTER. - - Valid resource names: background, bd, bg, borderwidth, cursor, - exportselection, fg, font, foreground, highlightbackground, - highlightcolor, highlightthickness, insertbackground, - insertborderwidth, insertofftime, insertontime, insertwidth, - invalidcommand, invcmd, justify, relief, selectbackground, - selectborderwidth, selectforeground, show, state, takefocus, - textvariable, validate, validatecommand, vcmd, width, - xscrollcommand.""" - Widget.__init__(self, master, 'entry', cnf, kw) - def delete(self, first, last=None): - """Delete text from FIRST to LAST (not included).""" - self.tk.call(self._w, 'delete', first, last) - def get(self): - """Return the text.""" - return self.tk.call(self._w, 'get') - def icursor(self, index): - """Insert cursor at INDEX.""" - self.tk.call(self._w, 'icursor', index) - def index(self, index): - """Return position of cursor.""" - return getint(self.tk.call( - self._w, 'index', index)) - def insert(self, index, string): - """Insert STRING at INDEX.""" - self.tk.call(self._w, 'insert', index, string) - def scan_mark(self, x): - """Remember the current X, Y coordinates.""" - self.tk.call(self._w, 'scan', 'mark', x) - def scan_dragto(self, x): - """Adjust the view of the canvas to 10 times the - difference between X and Y and the coordinates given in - scan_mark.""" - self.tk.call(self._w, 'scan', 'dragto', x) - def selection_adjust(self, index): - """Adjust the end of the selection near the cursor to INDEX.""" - self.tk.call(self._w, 'selection', 'adjust', index) - select_adjust = selection_adjust - def selection_clear(self): - """Clear the selection if it is in this widget.""" - self.tk.call(self._w, 'selection', 'clear') - select_clear = selection_clear - def selection_from(self, index): - """Set the fixed end of a selection to INDEX.""" - self.tk.call(self._w, 'selection', 'from', index) - select_from = selection_from - def selection_present(self): - """Return whether the widget has the selection.""" - return self.tk.getboolean( - self.tk.call(self._w, 'selection', 'present')) - select_present = selection_present - def selection_range(self, start, end): - """Set the selection from START to END (not included).""" - self.tk.call(self._w, 'selection', 'range', start, end) - select_range = selection_range - def selection_to(self, index): - """Set the variable end of a selection to INDEX.""" - self.tk.call(self._w, 'selection', 'to', index) - select_to = selection_to - def xview(self, index): - """Query and change horizontal position of the view.""" - self.tk.call(self._w, 'xview', index) - def xview_moveto(self, fraction): - """Adjust the view in the window so that FRACTION of the - total width of the entry is off-screen to the left.""" - self.tk.call(self._w, 'xview', 'moveto', fraction) - def xview_scroll(self, number, what): - """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" - self.tk.call(self._w, 'xview', 'scroll', number, what) - -class Frame(Widget): - """Frame widget which may contain other widgets and can have a 3D border.""" - def __init__(self, master=None, cnf={}, **kw): - """Construct a frame widget with the parent MASTER. - - Valid resource names: background, bd, bg, borderwidth, class, - colormap, container, cursor, height, highlightbackground, - highlightcolor, highlightthickness, relief, takefocus, visual, width.""" - cnf = _cnfmerge((cnf, kw)) - extra = () - if 'class_' in cnf: - extra = ('-class', cnf['class_']) - del cnf['class_'] - elif 'class' in cnf: - extra = ('-class', cnf['class']) - del cnf['class'] - Widget.__init__(self, master, 'frame', cnf, {}, extra) - -class Label(Widget): - """Label widget which can display text and bitmaps.""" - def __init__(self, master=None, cnf={}, **kw): - """Construct a label widget with the parent MASTER. - - STANDARD OPTIONS - - activebackground, activeforeground, anchor, - background, bitmap, borderwidth, cursor, - disabledforeground, font, foreground, - highlightbackground, highlightcolor, - highlightthickness, image, justify, - padx, pady, relief, takefocus, text, - textvariable, underline, wraplength - - WIDGET-SPECIFIC OPTIONS - - height, state, width - - """ - Widget.__init__(self, master, 'label', cnf, kw) - -class Listbox(Widget): - """Listbox widget which can display a list of strings.""" - def __init__(self, master=None, cnf={}, **kw): - """Construct a listbox widget with the parent MASTER. - - Valid resource names: background, bd, bg, borderwidth, cursor, - exportselection, fg, font, foreground, height, highlightbackground, - highlightcolor, highlightthickness, relief, selectbackground, - selectborderwidth, selectforeground, selectmode, setgrid, takefocus, - width, xscrollcommand, yscrollcommand, listvariable.""" - Widget.__init__(self, master, 'listbox', cnf, kw) - def activate(self, index): - """Activate item identified by INDEX.""" - self.tk.call(self._w, 'activate', index) - def bbox(self, *args): - """Return a tuple of X1,Y1,X2,Y2 coordinates for a rectangle - which encloses the item identified by index in ARGS.""" - return self._getints( - self.tk.call((self._w, 'bbox') + args)) or None - def curselection(self): - """Return list of indices of currently selected item.""" - # XXX Ought to apply self._getints()... - return self.tk.splitlist(self.tk.call( - self._w, 'curselection')) - def delete(self, first, last=None): - """Delete items from FIRST to LAST (not included).""" - self.tk.call(self._w, 'delete', first, last) - def get(self, first, last=None): - """Get list of items from FIRST to LAST (not included).""" - if last: - return self.tk.splitlist(self.tk.call( - self._w, 'get', first, last)) - else: - return self.tk.call(self._w, 'get', first) - def index(self, index): - """Return index of item identified with INDEX.""" - i = self.tk.call(self._w, 'index', index) - if i == 'none': return None - return getint(i) - def insert(self, index, *elements): - """Insert ELEMENTS at INDEX.""" - self.tk.call((self._w, 'insert', index) + elements) - def nearest(self, y): - """Get index of item which is nearest to y coordinate Y.""" - return getint(self.tk.call( - self._w, 'nearest', y)) - def scan_mark(self, x, y): - """Remember the current X, Y coordinates.""" - self.tk.call(self._w, 'scan', 'mark', x, y) - def scan_dragto(self, x, y): - """Adjust the view of the listbox to 10 times the - difference between X and Y and the coordinates given in - scan_mark.""" - self.tk.call(self._w, 'scan', 'dragto', x, y) - def see(self, index): - """Scroll such that INDEX is visible.""" - self.tk.call(self._w, 'see', index) - def selection_anchor(self, index): - """Set the fixed end oft the selection to INDEX.""" - self.tk.call(self._w, 'selection', 'anchor', index) - select_anchor = selection_anchor - def selection_clear(self, first, last=None): - """Clear the selection from FIRST to LAST (not included).""" - self.tk.call(self._w, - 'selection', 'clear', first, last) - select_clear = selection_clear - def selection_includes(self, index): - """Return 1 if INDEX is part of the selection.""" - return self.tk.getboolean(self.tk.call( - self._w, 'selection', 'includes', index)) - select_includes = selection_includes - def selection_set(self, first, last=None): - """Set the selection from FIRST to LAST (not included) without - changing the currently selected elements.""" - self.tk.call(self._w, 'selection', 'set', first, last) - select_set = selection_set - def size(self): - """Return the number of elements in the listbox.""" - return getint(self.tk.call(self._w, 'size')) - def xview(self, *what): - """Query and change horizontal position of the view.""" - if not what: - return self._getdoubles(self.tk.call(self._w, 'xview')) - self.tk.call((self._w, 'xview') + what) - def xview_moveto(self, fraction): - """Adjust the view in the window so that FRACTION of the - total width of the entry is off-screen to the left.""" - self.tk.call(self._w, 'xview', 'moveto', fraction) - def xview_scroll(self, number, what): - """Shift the x-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" - self.tk.call(self._w, 'xview', 'scroll', number, what) - def yview(self, *what): - """Query and change vertical position of the view.""" - if not what: - return self._getdoubles(self.tk.call(self._w, 'yview')) - self.tk.call((self._w, 'yview') + what) - def yview_moveto(self, fraction): - """Adjust the view in the window so that FRACTION of the - total width of the entry is off-screen to the top.""" - self.tk.call(self._w, 'yview', 'moveto', fraction) - def yview_scroll(self, number, what): - """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" - self.tk.call(self._w, 'yview', 'scroll', number, what) - def itemcget(self, index, option): - """Return the resource value for an ITEM and an OPTION.""" - return self.tk.call( - (self._w, 'itemcget') + (index, '-'+option)) - def itemconfigure(self, index, cnf=None, **kw): - """Configure resources of an ITEM. - - The values for resources are specified as keyword arguments. - To get an overview about the allowed keyword arguments - call the method without arguments. - Valid resource names: background, bg, foreground, fg, - selectbackground, selectforeground.""" - return self._configure(('itemconfigure', index), cnf, kw) - itemconfig = itemconfigure - -class Menu(Widget): - """Menu widget which allows to display menu bars, pull-down menus and pop-up menus.""" - def __init__(self, master=None, cnf={}, **kw): - """Construct menu widget with the parent MASTER. - - Valid resource names: activebackground, activeborderwidth, - activeforeground, background, bd, bg, borderwidth, cursor, - disabledforeground, fg, font, foreground, postcommand, relief, - selectcolor, takefocus, tearoff, tearoffcommand, title, type.""" - Widget.__init__(self, master, 'menu', cnf, kw) - def tk_bindForTraversal(self): - pass # obsolete since Tk 4.0 - def tk_mbPost(self): - self.tk.call('tk_mbPost', self._w) - def tk_mbUnpost(self): - self.tk.call('tk_mbUnpost') - def tk_traverseToMenu(self, char): - self.tk.call('tk_traverseToMenu', self._w, char) - def tk_traverseWithinMenu(self, char): - self.tk.call('tk_traverseWithinMenu', self._w, char) - def tk_getMenuButtons(self): - return self.tk.call('tk_getMenuButtons', self._w) - def tk_nextMenu(self, count): - self.tk.call('tk_nextMenu', count) - def tk_nextMenuEntry(self, count): - self.tk.call('tk_nextMenuEntry', count) - def tk_invokeMenu(self): - self.tk.call('tk_invokeMenu', self._w) - def tk_firstMenu(self): - self.tk.call('tk_firstMenu', self._w) - def tk_mbButtonDown(self): - self.tk.call('tk_mbButtonDown', self._w) - def tk_popup(self, x, y, entry=""): - """Post the menu at position X,Y with entry ENTRY.""" - self.tk.call('tk_popup', self._w, x, y, entry) - def activate(self, index): - """Activate entry at INDEX.""" - self.tk.call(self._w, 'activate', index) - def add(self, itemType, cnf={}, **kw): - """Internal function.""" - self.tk.call((self._w, 'add', itemType) + - self._options(cnf, kw)) - def add_cascade(self, cnf={}, **kw): - """Add hierarchical menu item.""" - self.add('cascade', cnf or kw) - def add_checkbutton(self, cnf={}, **kw): - """Add checkbutton menu item.""" - self.add('checkbutton', cnf or kw) - def add_command(self, cnf={}, **kw): - """Add command menu item.""" - self.add('command', cnf or kw) - def add_radiobutton(self, cnf={}, **kw): - """Addd radio menu item.""" - self.add('radiobutton', cnf or kw) - def add_separator(self, cnf={}, **kw): - """Add separator.""" - self.add('separator', cnf or kw) - def insert(self, index, itemType, cnf={}, **kw): - """Internal function.""" - self.tk.call((self._w, 'insert', index, itemType) + - self._options(cnf, kw)) - def insert_cascade(self, index, cnf={}, **kw): - """Add hierarchical menu item at INDEX.""" - self.insert(index, 'cascade', cnf or kw) - def insert_checkbutton(self, index, cnf={}, **kw): - """Add checkbutton menu item at INDEX.""" - self.insert(index, 'checkbutton', cnf or kw) - def insert_command(self, index, cnf={}, **kw): - """Add command menu item at INDEX.""" - self.insert(index, 'command', cnf or kw) - def insert_radiobutton(self, index, cnf={}, **kw): - """Addd radio menu item at INDEX.""" - self.insert(index, 'radiobutton', cnf or kw) - def insert_separator(self, index, cnf={}, **kw): - """Add separator at INDEX.""" - self.insert(index, 'separator', cnf or kw) - def delete(self, index1, index2=None): - """Delete menu items between INDEX1 and INDEX2 (not included).""" - self.tk.call(self._w, 'delete', index1, index2) - def entrycget(self, index, option): - """Return the resource value of an menu item for OPTION at INDEX.""" - return self.tk.call(self._w, 'entrycget', index, '-' + option) - def entryconfigure(self, index, cnf=None, **kw): - """Configure a menu item at INDEX.""" - return self._configure(('entryconfigure', index), cnf, kw) - entryconfig = entryconfigure - def index(self, index): - """Return the index of a menu item identified by INDEX.""" - i = self.tk.call(self._w, 'index', index) - if i == 'none': return None - return getint(i) - def invoke(self, index): - """Invoke a menu item identified by INDEX and execute - the associated command.""" - return self.tk.call(self._w, 'invoke', index) - def post(self, x, y): - """Display a menu at position X,Y.""" - self.tk.call(self._w, 'post', x, y) - def type(self, index): - """Return the type of the menu item at INDEX.""" - return self.tk.call(self._w, 'type', index) - def unpost(self): - """Unmap a menu.""" - self.tk.call(self._w, 'unpost') - def yposition(self, index): - """Return the y-position of the topmost pixel of the menu item at INDEX.""" - return getint(self.tk.call( - self._w, 'yposition', index)) - -class Menubutton(Widget): - """Menubutton widget, obsolete since Tk8.0.""" - def __init__(self, master=None, cnf={}, **kw): - Widget.__init__(self, master, 'menubutton', cnf, kw) - -class Message(Widget): - """Message widget to display multiline text. Obsolete since Label does it too.""" - def __init__(self, master=None, cnf={}, **kw): - Widget.__init__(self, master, 'message', cnf, kw) - -class Radiobutton(Widget): - """Radiobutton widget which shows only one of several buttons in on-state.""" - def __init__(self, master=None, cnf={}, **kw): - """Construct a radiobutton widget with the parent MASTER. - - Valid resource names: activebackground, activeforeground, anchor, - background, bd, bg, bitmap, borderwidth, command, cursor, - disabledforeground, fg, font, foreground, height, - highlightbackground, highlightcolor, highlightthickness, image, - indicatoron, justify, padx, pady, relief, selectcolor, selectimage, - state, takefocus, text, textvariable, underline, value, variable, - width, wraplength.""" - Widget.__init__(self, master, 'radiobutton', cnf, kw) - def deselect(self): - """Put the button in off-state.""" - - self.tk.call(self._w, 'deselect') - def flash(self): - """Flash the button.""" - self.tk.call(self._w, 'flash') - def invoke(self): - """Toggle the button and invoke a command if given as resource.""" - return self.tk.call(self._w, 'invoke') - def select(self): - """Put the button in on-state.""" - self.tk.call(self._w, 'select') - -class Scale(Widget): - """Scale widget which can display a numerical scale.""" - def __init__(self, master=None, cnf={}, **kw): - """Construct a scale widget with the parent MASTER. - - Valid resource names: activebackground, background, bigincrement, bd, - bg, borderwidth, command, cursor, digits, fg, font, foreground, from, - highlightbackground, highlightcolor, highlightthickness, label, - length, orient, relief, repeatdelay, repeatinterval, resolution, - showvalue, sliderlength, sliderrelief, state, takefocus, - tickinterval, to, troughcolor, variable, width.""" - Widget.__init__(self, master, 'scale', cnf, kw) - def get(self): - """Get the current value as integer or float.""" - value = self.tk.call(self._w, 'get') - try: - return getint(value) - except ValueError: - return getdouble(value) - def set(self, value): - """Set the value to VALUE.""" - self.tk.call(self._w, 'set', value) - def coords(self, value=None): - """Return a tuple (X,Y) of the point along the centerline of the - trough that corresponds to VALUE or the current value if None is - given.""" - - return self._getints(self.tk.call(self._w, 'coords', value)) - def identify(self, x, y): - """Return where the point X,Y lies. Valid return values are "slider", - "though1" and "though2".""" - return self.tk.call(self._w, 'identify', x, y) - -class Scrollbar(Widget): - """Scrollbar widget which displays a slider at a certain position.""" - def __init__(self, master=None, cnf={}, **kw): - """Construct a scrollbar widget with the parent MASTER. - - Valid resource names: activebackground, activerelief, - background, bd, bg, borderwidth, command, cursor, - elementborderwidth, highlightbackground, - highlightcolor, highlightthickness, jump, orient, - relief, repeatdelay, repeatinterval, takefocus, - troughcolor, width.""" - Widget.__init__(self, master, 'scrollbar', cnf, kw) - def activate(self, index): - """Display the element at INDEX with activebackground and activerelief. - INDEX can be "arrow1","slider" or "arrow2".""" - self.tk.call(self._w, 'activate', index) - def delta(self, deltax, deltay): - """Return the fractional change of the scrollbar setting if it - would be moved by DELTAX or DELTAY pixels.""" - return getdouble( - self.tk.call(self._w, 'delta', deltax, deltay)) - def fraction(self, x, y): - """Return the fractional value which corresponds to a slider - position of X,Y.""" - return getdouble(self.tk.call(self._w, 'fraction', x, y)) - def identify(self, x, y): - """Return the element under position X,Y as one of - "arrow1","slider","arrow2" or "".""" - return self.tk.call(self._w, 'identify', x, y) - def get(self): - """Return the current fractional values (upper and lower end) - of the slider position.""" - return self._getdoubles(self.tk.call(self._w, 'get')) - def set(self, *args): - """Set the fractional values of the slider position (upper and - lower ends as value between 0 and 1).""" - self.tk.call((self._w, 'set') + args) - - - -class Text(Widget): - """Text widget which can display text in various forms.""" - def __init__(self, master=None, cnf={}, **kw): - """Construct a text widget with the parent MASTER. - - STANDARD OPTIONS - - background, borderwidth, cursor, - exportselection, font, foreground, - highlightbackground, highlightcolor, - highlightthickness, insertbackground, - insertborderwidth, insertofftime, - insertontime, insertwidth, padx, pady, - relief, selectbackground, - selectborderwidth, selectforeground, - setgrid, takefocus, - xscrollcommand, yscrollcommand, - - WIDGET-SPECIFIC OPTIONS - - autoseparators, height, maxundo, - spacing1, spacing2, spacing3, - state, tabs, undo, width, wrap, - - """ - Widget.__init__(self, master, 'text', cnf, kw) - def bbox(self, *args): - """Return a tuple of (x,y,width,height) which gives the bounding - box of the visible part of the character at the index in ARGS.""" - return self._getints( - self.tk.call((self._w, 'bbox') + args)) or None - def tk_textSelectTo(self, index): - self.tk.call('tk_textSelectTo', self._w, index) - def tk_textBackspace(self): - self.tk.call('tk_textBackspace', self._w) - def tk_textIndexCloser(self, a, b, c): - self.tk.call('tk_textIndexCloser', self._w, a, b, c) - def tk_textResetAnchor(self, index): - self.tk.call('tk_textResetAnchor', self._w, index) - def compare(self, index1, op, index2): - """Return whether between index INDEX1 and index INDEX2 the - relation OP is satisfied. OP is one of <, <=, ==, >=, >, or !=.""" - return self.tk.getboolean(self.tk.call( - self._w, 'compare', index1, op, index2)) - def debug(self, boolean=None): - """Turn on the internal consistency checks of the B-Tree inside the text - widget according to BOOLEAN.""" - return self.tk.getboolean(self.tk.call( - self._w, 'debug', boolean)) - def delete(self, index1, index2=None): - """Delete the characters between INDEX1 and INDEX2 (not included).""" - self.tk.call(self._w, 'delete', index1, index2) - def dlineinfo(self, index): - """Return tuple (x,y,width,height,baseline) giving the bounding box - and baseline position of the visible part of the line containing - the character at INDEX.""" - return self._getints(self.tk.call(self._w, 'dlineinfo', index)) - def dump(self, index1, index2=None, command=None, **kw): - """Return the contents of the widget between index1 and index2. - - The type of contents returned in filtered based on the keyword - parameters; if 'all', 'image', 'mark', 'tag', 'text', or 'window' are - given and true, then the corresponding items are returned. The result - is a list of triples of the form (key, value, index). If none of the - keywords are true then 'all' is used by default. - - If the 'command' argument is given, it is called once for each element - of the list of triples, with the values of each triple serving as the - arguments to the function. In this case the list is not returned.""" - args = [] - func_name = None - result = None - if not command: - # Never call the dump command without the -command flag, since the - # output could involve Tcl quoting and would be a pain to parse - # right. Instead just set the command to build a list of triples - # as if we had done the parsing. - result = [] - def append_triple(key, value, index, result=result): - result.append((key, value, index)) - command = append_triple - try: - if not isinstance(command, str): - func_name = command = self._register(command) - args += ["-command", command] - for key in kw: - if kw[key]: args.append("-" + key) - args.append(index1) - if index2: - args.append(index2) - self.tk.call(self._w, "dump", *args) - return result - finally: - if func_name: - self.deletecommand(func_name) - - ## new in tk8.4 - def edit(self, *args): - """Internal method - - This method controls the undo mechanism and - the modified flag. The exact behavior of the - command depends on the option argument that - follows the edit argument. The following forms - of the command are currently supported: - - edit_modified, edit_redo, edit_reset, edit_separator - and edit_undo - - """ - return self._getints( - self.tk.call((self._w, 'edit') + args)) or () - - def edit_modified(self, arg=None): - """Get or Set the modified flag - - If arg is not specified, returns the modified - flag of the widget. The insert, delete, edit undo and - edit redo commands or the user can set or clear the - modified flag. If boolean is specified, sets the - modified flag of the widget to arg. - """ - return self.edit("modified", arg) - - def edit_redo(self): - """Redo the last undone edit - - When the undo option is true, reapplies the last - undone edits provided no other edits were done since - then. Generates an error when the redo stack is empty. - Does nothing when the undo option is false. - """ - return self.edit("redo") - - def edit_reset(self): - """Clears the undo and redo stacks - """ - return self.edit("reset") - - def edit_separator(self): - """Inserts a separator (boundary) on the undo stack. - - Does nothing when the undo option is false - """ - return self.edit("separator") - - def edit_undo(self): - """Undoes the last edit action - - If the undo option is true. An edit action is defined - as all the insert and delete commands that are recorded - on the undo stack in between two separators. Generates - an error when the undo stack is empty. Does nothing - when the undo option is false - """ - return self.edit("undo") - - def get(self, index1, index2=None): - """Return the text from INDEX1 to INDEX2 (not included).""" - return self.tk.call(self._w, 'get', index1, index2) - # (Image commands are new in 8.0) - def image_cget(self, index, option): - """Return the value of OPTION of an embedded image at INDEX.""" - if option[:1] != "-": - option = "-" + option - if option[-1:] == "_": - option = option[:-1] - return self.tk.call(self._w, "image", "cget", index, option) - def image_configure(self, index, cnf=None, **kw): - """Configure an embedded image at INDEX.""" - return self._configure(('image', 'configure', index), cnf, kw) - def image_create(self, index, cnf={}, **kw): - """Create an embedded image at INDEX.""" - return self.tk.call( - self._w, "image", "create", index, - *self._options(cnf, kw)) - def image_names(self): - """Return all names of embedded images in this widget.""" - return self.tk.call(self._w, "image", "names") - def index(self, index): - """Return the index in the form line.char for INDEX.""" - return str(self.tk.call(self._w, 'index', index)) - def insert(self, index, chars, *args): - """Insert CHARS before the characters at INDEX. An additional - tag can be given in ARGS. Additional CHARS and tags can follow in ARGS.""" - self.tk.call((self._w, 'insert', index, chars) + args) - def mark_gravity(self, markName, direction=None): - """Change the gravity of a mark MARKNAME to DIRECTION (LEFT or RIGHT). - Return the current value if None is given for DIRECTION.""" - return self.tk.call( - (self._w, 'mark', 'gravity', markName, direction)) - def mark_names(self): - """Return all mark names.""" - return self.tk.splitlist(self.tk.call( - self._w, 'mark', 'names')) - def mark_set(self, markName, index): - """Set mark MARKNAME before the character at INDEX.""" - self.tk.call(self._w, 'mark', 'set', markName, index) - def mark_unset(self, *markNames): - """Delete all marks in MARKNAMES.""" - self.tk.call((self._w, 'mark', 'unset') + markNames) - def mark_next(self, index): - """Return the name of the next mark after INDEX.""" - return self.tk.call(self._w, 'mark', 'next', index) or None - def mark_previous(self, index): - """Return the name of the previous mark before INDEX.""" - return self.tk.call(self._w, 'mark', 'previous', index) or None - def scan_mark(self, x, y): - """Remember the current X, Y coordinates.""" - self.tk.call(self._w, 'scan', 'mark', x, y) - def scan_dragto(self, x, y): - """Adjust the view of the text to 10 times the - difference between X and Y and the coordinates given in - scan_mark.""" - self.tk.call(self._w, 'scan', 'dragto', x, y) - def search(self, pattern, index, stopindex=None, - forwards=None, backwards=None, exact=None, - regexp=None, nocase=None, count=None, elide=None): - """Search PATTERN beginning from INDEX until STOPINDEX. - Return the index of the first character of a match or an empty string.""" - args = [self._w, 'search'] - if forwards: args.append('-forwards') - if backwards: args.append('-backwards') - if exact: args.append('-exact') - if regexp: args.append('-regexp') - if nocase: args.append('-nocase') - if elide: args.append('-elide') - if count: args.append('-count'); args.append(count) - if pattern[0] == '-': args.append('--') - args.append(pattern) - args.append(index) - if stopindex: args.append(stopindex) - return self.tk.call(tuple(args)) - def see(self, index): - """Scroll such that the character at INDEX is visible.""" - self.tk.call(self._w, 'see', index) - def tag_add(self, tagName, index1, *args): - """Add tag TAGNAME to all characters between INDEX1 and index2 in ARGS. - Additional pairs of indices may follow in ARGS.""" - self.tk.call( - (self._w, 'tag', 'add', tagName, index1) + args) - def tag_unbind(self, tagName, sequence, funcid=None): - """Unbind for all characters with TAGNAME for event SEQUENCE the - function identified with FUNCID.""" - self.tk.call(self._w, 'tag', 'bind', tagName, sequence, '') - if funcid: - self.deletecommand(funcid) - def tag_bind(self, tagName, sequence, func, add=None): - """Bind to all characters with TAGNAME at event SEQUENCE a call to function FUNC. - - An additional boolean parameter ADD specifies whether FUNC will be - called additionally to the other bound function or whether it will - replace the previous function. See bind for the return value.""" - return self._bind((self._w, 'tag', 'bind', tagName), - sequence, func, add) - def tag_cget(self, tagName, option): - """Return the value of OPTION for tag TAGNAME.""" - if option[:1] != '-': - option = '-' + option - if option[-1:] == '_': - option = option[:-1] - return self.tk.call(self._w, 'tag', 'cget', tagName, option) - def tag_configure(self, tagName, cnf=None, **kw): - """Configure a tag TAGNAME.""" - return self._configure(('tag', 'configure', tagName), cnf, kw) - tag_config = tag_configure - def tag_delete(self, *tagNames): - """Delete all tags in TAGNAMES.""" - self.tk.call((self._w, 'tag', 'delete') + tagNames) - def tag_lower(self, tagName, belowThis=None): - """Change the priority of tag TAGNAME such that it is lower - than the priority of BELOWTHIS.""" - self.tk.call(self._w, 'tag', 'lower', tagName, belowThis) - def tag_names(self, index=None): - """Return a list of all tag names.""" - return self.tk.splitlist( - self.tk.call(self._w, 'tag', 'names', index)) - def tag_nextrange(self, tagName, index1, index2=None): - """Return a list of start and end index for the first sequence of - characters between INDEX1 and INDEX2 which all have tag TAGNAME. - The text is searched forward from INDEX1.""" - return self.tk.splitlist(self.tk.call( - self._w, 'tag', 'nextrange', tagName, index1, index2)) - def tag_prevrange(self, tagName, index1, index2=None): - """Return a list of start and end index for the first sequence of - characters between INDEX1 and INDEX2 which all have tag TAGNAME. - The text is searched backwards from INDEX1.""" - return self.tk.splitlist(self.tk.call( - self._w, 'tag', 'prevrange', tagName, index1, index2)) - def tag_raise(self, tagName, aboveThis=None): - """Change the priority of tag TAGNAME such that it is higher - than the priority of ABOVETHIS.""" - self.tk.call( - self._w, 'tag', 'raise', tagName, aboveThis) - def tag_ranges(self, tagName): - """Return a list of ranges of text which have tag TAGNAME.""" - return self.tk.splitlist(self.tk.call( - self._w, 'tag', 'ranges', tagName)) - def tag_remove(self, tagName, index1, index2=None): - """Remove tag TAGNAME from all characters between INDEX1 and INDEX2.""" - self.tk.call( - self._w, 'tag', 'remove', tagName, index1, index2) - def window_cget(self, index, option): - """Return the value of OPTION of an embedded window at INDEX.""" - if option[:1] != '-': - option = '-' + option - if option[-1:] == '_': - option = option[:-1] - return self.tk.call(self._w, 'window', 'cget', index, option) - def window_configure(self, index, cnf=None, **kw): - """Configure an embedded window at INDEX.""" - return self._configure(('window', 'configure', index), cnf, kw) - window_config = window_configure - def window_create(self, index, cnf={}, **kw): - """Create a window at INDEX.""" - self.tk.call( - (self._w, 'window', 'create', index) - + self._options(cnf, kw)) - def window_names(self): - """Return all names of embedded windows in this widget.""" - return self.tk.splitlist( - self.tk.call(self._w, 'window', 'names')) - def xview(self, *what): - """Query and change horizontal position of the view.""" - if not what: - return self._getdoubles(self.tk.call(self._w, 'xview')) - self.tk.call((self._w, 'xview') + what) - def xview_moveto(self, fraction): - """Adjusts the view in the window so that FRACTION of the - total width of the canvas is off-screen to the left.""" - self.tk.call(self._w, 'xview', 'moveto', fraction) - def xview_scroll(self, number, what): - """Shift the x-view according to NUMBER which is measured - in "units" or "pages" (WHAT).""" - self.tk.call(self._w, 'xview', 'scroll', number, what) - def yview(self, *what): - """Query and change vertical position of the view.""" - if not what: - return self._getdoubles(self.tk.call(self._w, 'yview')) - self.tk.call((self._w, 'yview') + what) - def yview_moveto(self, fraction): - """Adjusts the view in the window so that FRACTION of the - total height of the canvas is off-screen to the top.""" - self.tk.call(self._w, 'yview', 'moveto', fraction) - def yview_scroll(self, number, what): - """Shift the y-view according to NUMBER which is measured - in "units" or "pages" (WHAT).""" - self.tk.call(self._w, 'yview', 'scroll', number, what) - def yview_pickplace(self, *what): - """Obsolete function, use see.""" - self.tk.call((self._w, 'yview', '-pickplace') + what) - - -class _setit: - """Internal class. It wraps the command in the widget OptionMenu.""" - def __init__(self, var, value, callback=None): - self.__value = value - self.__var = var - self.__callback = callback - def __call__(self, *args): - self.__var.set(self.__value) - if self.__callback: - self.__callback(self.__value, *args) - -class OptionMenu(Menubutton): - """OptionMenu which allows the user to select a value from a menu.""" - def __init__(self, master, variable, value, *values, **kwargs): - """Construct an optionmenu widget with the parent MASTER, with - the resource textvariable set to VARIABLE, the initially selected - value VALUE, the other menu values VALUES and an additional - keyword argument command.""" - kw = {"borderwidth": 2, "textvariable": variable, - "indicatoron": 1, "relief": RAISED, "anchor": "c", - "highlightthickness": 2} - Widget.__init__(self, master, "menubutton", kw) - self.widgetName = 'tk_optionMenu' - menu = self.__menu = Menu(self, name="menu", tearoff=0) - self.menuname = menu._w - # 'command' is the only supported keyword - callback = kwargs.get('command') - if 'command' in kwargs: - del kwargs['command'] - if kwargs: - raise TclError('unknown option -'+kwargs.keys()[0]) - menu.add_command(label=value, - command=_setit(variable, value, callback)) - for v in values: - menu.add_command(label=v, - command=_setit(variable, v, callback)) - self["menu"] = menu - - def __getitem__(self, name): - if name == 'menu': - return self.__menu - return Widget.__getitem__(self, name) - - def destroy(self): - """Destroy this widget and the associated menu.""" - Menubutton.destroy(self) - self.__menu = None - -class Image: - """Base class for images.""" - _last_id = 0 - def __init__(self, imgtype, name=None, cnf={}, master=None, **kw): - self.name = None - if not master: - master = _default_root - if not master: - raise RuntimeError('Too early to create image') - self.tk = master.tk - if not name: - Image._last_id += 1 - name = "pyimage%r" % (Image._last_id,) # tk itself would use image - # The following is needed for systems where id(x) - # can return a negative number, such as Linux/m68k: - if name[0] == '-': name = '_' + name[1:] - if kw and cnf: cnf = _cnfmerge((cnf, kw)) - elif kw: cnf = kw - options = () - for k, v in cnf.items(): - if hasattr(v, '__call__'): - v = self._register(v) - options = options + ('-'+k, v) - self.tk.call(('image', 'create', imgtype, name,) + options) - self.name = name - def __str__(self): return self.name - def __del__(self): - if self.name: - try: - self.tk.call('image', 'delete', self.name) - except TclError: - # May happen if the root was destroyed - pass - def __setitem__(self, key, value): - self.tk.call(self.name, 'configure', '-'+key, value) - def __getitem__(self, key): - return self.tk.call(self.name, 'configure', '-'+key) - def configure(self, **kw): - """Configure the image.""" - res = () - for k, v in _cnfmerge(kw).items(): - if v is not None: - if k[-1] == '_': k = k[:-1] - if hasattr(v, '__call__'): - v = self._register(v) - res = res + ('-'+k, v) - self.tk.call((self.name, 'config') + res) - config = configure - def height(self): - """Return the height of the image.""" - return getint( - self.tk.call('image', 'height', self.name)) - def type(self): - """Return the type of the imgage, e.g. "photo" or "bitmap".""" - return self.tk.call('image', 'type', self.name) - def width(self): - """Return the width of the image.""" - return getint( - self.tk.call('image', 'width', self.name)) - -class PhotoImage(Image): - """Widget which can display colored images in GIF, PPM/PGM format.""" - def __init__(self, name=None, cnf={}, master=None, **kw): - """Create an image with NAME. - - Valid resource names: data, format, file, gamma, height, palette, - width.""" - Image.__init__(self, 'photo', name, cnf, master, **kw) - def blank(self): - """Display a transparent image.""" - self.tk.call(self.name, 'blank') - def cget(self, option): - """Return the value of OPTION.""" - return self.tk.call(self.name, 'cget', '-' + option) - # XXX config - def __getitem__(self, key): - return self.tk.call(self.name, 'cget', '-' + key) - # XXX copy -from, -to, ...? - def copy(self): - """Return a new PhotoImage with the same image as this widget.""" - destImage = PhotoImage() - self.tk.call(destImage, 'copy', self.name) - return destImage - def zoom(self,x,y=''): - """Return a new PhotoImage with the same image as this widget - but zoom it with X and Y.""" - destImage = PhotoImage() - if y=='': y=x - self.tk.call(destImage, 'copy', self.name, '-zoom',x,y) - return destImage - def subsample(self,x,y=''): - """Return a new PhotoImage based on the same image as this widget - but use only every Xth or Yth pixel.""" - destImage = PhotoImage() - if y=='': y=x - self.tk.call(destImage, 'copy', self.name, '-subsample',x,y) - return destImage - def get(self, x, y): - """Return the color (red, green, blue) of the pixel at X,Y.""" - return self.tk.call(self.name, 'get', x, y) - def put(self, data, to=None): - """Put row formated colors to image starting from - position TO, e.g. image.put("{red green} {blue yellow}", to=(4,6))""" - args = (self.name, 'put', data) - if to: - if to[0] == '-to': - to = to[1:] - args = args + ('-to',) + tuple(to) - self.tk.call(args) - # XXX read - def write(self, filename, format=None, from_coords=None): - """Write image to file FILENAME in FORMAT starting from - position FROM_COORDS.""" - args = (self.name, 'write', filename) - if format: - args = args + ('-format', format) - if from_coords: - args = args + ('-from',) + tuple(from_coords) - self.tk.call(args) - -class BitmapImage(Image): - """Widget which can display a bitmap.""" - def __init__(self, name=None, cnf={}, master=None, **kw): - """Create a bitmap with NAME. - - Valid resource names: background, data, file, foreground, maskdata, maskfile.""" - Image.__init__(self, 'bitmap', name, cnf, master, **kw) - -def image_names(): return _default_root.tk.call('image', 'names') -def image_types(): return _default_root.tk.call('image', 'types') - - -class Spinbox(Widget): - """spinbox widget.""" - def __init__(self, master=None, cnf={}, **kw): - """Construct a spinbox widget with the parent MASTER. - - STANDARD OPTIONS - - activebackground, background, borderwidth, - cursor, exportselection, font, foreground, - highlightbackground, highlightcolor, - highlightthickness, insertbackground, - insertborderwidth, insertofftime, - insertontime, insertwidth, justify, relief, - repeatdelay, repeatinterval, - selectbackground, selectborderwidth - selectforeground, takefocus, textvariable - xscrollcommand. - - WIDGET-SPECIFIC OPTIONS - - buttonbackground, buttoncursor, - buttondownrelief, buttonuprelief, - command, disabledbackground, - disabledforeground, format, from, - invalidcommand, increment, - readonlybackground, state, to, - validate, validatecommand values, - width, wrap, - """ - Widget.__init__(self, master, 'spinbox', cnf, kw) - - def bbox(self, index): - """Return a tuple of X1,Y1,X2,Y2 coordinates for a - rectangle which encloses the character given by index. - - The first two elements of the list give the x and y - coordinates of the upper-left corner of the screen - area covered by the character (in pixels relative - to the widget) and the last two elements give the - width and height of the character, in pixels. The - bounding box may refer to a region outside the - visible area of the window. - """ - return self.tk.call(self._w, 'bbox', index) - - def delete(self, first, last=None): - """Delete one or more elements of the spinbox. - - First is the index of the first character to delete, - and last is the index of the character just after - the last one to delete. If last isn't specified it - defaults to first+1, i.e. a single character is - deleted. This command returns an empty string. - """ - return self.tk.call(self._w, 'delete', first, last) - - def get(self): - """Returns the spinbox's string""" - return self.tk.call(self._w, 'get') - - def icursor(self, index): - """Alter the position of the insertion cursor. - - The insertion cursor will be displayed just before - the character given by index. Returns an empty string - """ - return self.tk.call(self._w, 'icursor', index) - - def identify(self, x, y): - """Returns the name of the widget at position x, y - - Return value is one of: none, buttondown, buttonup, entry - """ - return self.tk.call(self._w, 'identify', x, y) - - def index(self, index): - """Returns the numerical index corresponding to index - """ - return self.tk.call(self._w, 'index', index) - - def insert(self, index, s): - """Insert string s at index - - Returns an empty string. - """ - return self.tk.call(self._w, 'insert', index, s) - - def invoke(self, element): - """Causes the specified element to be invoked - - The element could be buttondown or buttonup - triggering the action associated with it. - """ - return self.tk.call(self._w, 'invoke', element) - - def scan(self, *args): - """Internal function.""" - return self._getints( - self.tk.call((self._w, 'scan') + args)) or () - - def scan_mark(self, x): - """Records x and the current view in the spinbox window; - - used in conjunction with later scan dragto commands. - Typically this command is associated with a mouse button - press in the widget. It returns an empty string. - """ - return self.scan("mark", x) - - def scan_dragto(self, x): - """Compute the difference between the given x argument - and the x argument to the last scan mark command - - It then adjusts the view left or right by 10 times the - difference in x-coordinates. This command is typically - associated with mouse motion events in the widget, to - produce the effect of dragging the spinbox at high speed - through the window. The return value is an empty string. - """ - return self.scan("dragto", x) - - def selection(self, *args): - """Internal function.""" - return self._getints( - self.tk.call((self._w, 'selection') + args)) or () - - def selection_adjust(self, index): - """Locate the end of the selection nearest to the character - given by index, - - Then adjust that end of the selection to be at index - (i.e including but not going beyond index). The other - end of the selection is made the anchor point for future - select to commands. If the selection isn't currently in - the spinbox, then a new selection is created to include - the characters between index and the most recent selection - anchor point, inclusive. Returns an empty string. - """ - return self.selection("adjust", index) - - def selection_clear(self): - """Clear the selection - - If the selection isn't in this widget then the - command has no effect. Returns an empty string. - """ - return self.selection("clear") - - def selection_element(self, element=None): - """Sets or gets the currently selected element. - - If a spinbutton element is specified, it will be - displayed depressed - """ - return self.selection("element", element) - -########################################################################### - -class LabelFrame(Widget): - """labelframe widget.""" - def __init__(self, master=None, cnf={}, **kw): - """Construct a labelframe widget with the parent MASTER. - - STANDARD OPTIONS - - borderwidth, cursor, font, foreground, - highlightbackground, highlightcolor, - highlightthickness, padx, pady, relief, - takefocus, text - - WIDGET-SPECIFIC OPTIONS - - background, class, colormap, container, - height, labelanchor, labelwidget, - visual, width - """ - Widget.__init__(self, master, 'labelframe', cnf, kw) - -######################################################################## - -class PanedWindow(Widget): - """panedwindow widget.""" - def __init__(self, master=None, cnf={}, **kw): - """Construct a panedwindow widget with the parent MASTER. - - STANDARD OPTIONS - - background, borderwidth, cursor, height, - orient, relief, width - - WIDGET-SPECIFIC OPTIONS - - handlepad, handlesize, opaqueresize, - sashcursor, sashpad, sashrelief, - sashwidth, showhandle, - """ - Widget.__init__(self, master, 'panedwindow', cnf, kw) - - def add(self, child, **kw): - """Add a child widget to the panedwindow in a new pane. - - The child argument is the name of the child widget - followed by pairs of arguments that specify how to - manage the windows. Options may have any of the values - accepted by the configure subcommand. - """ - self.tk.call((self._w, 'add', child) + self._options(kw)) - - def remove(self, child): - """Remove the pane containing child from the panedwindow - - All geometry management options for child will be forgotten. - """ - self.tk.call(self._w, 'forget', child) - forget=remove - - def identify(self, x, y): - """Identify the panedwindow component at point x, y - - If the point is over a sash or a sash handle, the result - is a two element list containing the index of the sash or - handle, and a word indicating whether it is over a sash - or a handle, such as {0 sash} or {2 handle}. If the point - is over any other part of the panedwindow, the result is - an empty list. - """ - return self.tk.call(self._w, 'identify', x, y) - - def proxy(self, *args): - """Internal function.""" - return self._getints( - self.tk.call((self._w, 'proxy') + args)) or () - - def proxy_coord(self): - """Return the x and y pair of the most recent proxy location - """ - return self.proxy("coord") - - def proxy_forget(self): - """Remove the proxy from the display. - """ - return self.proxy("forget") - - def proxy_place(self, x, y): - """Place the proxy at the given x and y coordinates. - """ - return self.proxy("place", x, y) - - def sash(self, *args): - """Internal function.""" - return self._getints( - self.tk.call((self._w, 'sash') + args)) or () - - def sash_coord(self, index): - """Return the current x and y pair for the sash given by index. - - Index must be an integer between 0 and 1 less than the - number of panes in the panedwindow. The coordinates given are - those of the top left corner of the region containing the sash. - pathName sash dragto index x y This command computes the - difference between the given coordinates and the coordinates - given to the last sash coord command for the given sash. It then - moves that sash the computed difference. The return value is the - empty string. - """ - return self.sash("coord", index) - - def sash_mark(self, index): - """Records x and y for the sash given by index; - - Used in conjunction with later dragto commands to move the sash. - """ - return self.sash("mark", index) - - def sash_place(self, index, x, y): - """Place the sash given by index at the given coordinates - """ - return self.sash("place", index, x, y) - - def panecget(self, child, option): - """Query a management option for window. - - Option may be any value allowed by the paneconfigure subcommand - """ - return self.tk.call( - (self._w, 'panecget') + (child, '-'+option)) - - def paneconfigure(self, tagOrId, cnf=None, **kw): - """Query or modify the management options for window. - - If no option is specified, returns a list describing all - of the available options for pathName. If option is - specified with no value, then the command returns a list - describing the one named option (this list will be identical - to the corresponding sublist of the value returned if no - option is specified). If one or more option-value pairs are - specified, then the command modifies the given widget - option(s) to have the given value(s); in this case the - command returns an empty string. The following options - are supported: - - after window - Insert the window after the window specified. window - should be the name of a window already managed by pathName. - before window - Insert the window before the window specified. window - should be the name of a window already managed by pathName. - height size - Specify a height for the window. The height will be the - outer dimension of the window including its border, if - any. If size is an empty string, or if -height is not - specified, then the height requested internally by the - window will be used initially; the height may later be - adjusted by the movement of sashes in the panedwindow. - Size may be any value accepted by Tk_GetPixels. - minsize n - Specifies that the size of the window cannot be made - less than n. This constraint only affects the size of - the widget in the paned dimension -- the x dimension - for horizontal panedwindows, the y dimension for - vertical panedwindows. May be any value accepted by - Tk_GetPixels. - padx n - Specifies a non-negative value indicating how much - extra space to leave on each side of the window in - the X-direction. The value may have any of the forms - accepted by Tk_GetPixels. - pady n - Specifies a non-negative value indicating how much - extra space to leave on each side of the window in - the Y-direction. The value may have any of the forms - accepted by Tk_GetPixels. - sticky style - If a window's pane is larger than the requested - dimensions of the window, this option may be used - to position (or stretch) the window within its pane. - Style is a string that contains zero or more of the - characters n, s, e or w. The string can optionally - contains spaces or commas, but they are ignored. Each - letter refers to a side (north, south, east, or west) - that the window will "stick" to. If both n and s - (or e and w) are specified, the window will be - stretched to fill the entire height (or width) of - its cavity. - width size - Specify a width for the window. The width will be - the outer dimension of the window including its - border, if any. If size is an empty string, or - if -width is not specified, then the width requested - internally by the window will be used initially; the - width may later be adjusted by the movement of sashes - in the panedwindow. Size may be any value accepted by - Tk_GetPixels. - - """ - if cnf is None and not kw: - cnf = {} - for x in self.tk.split( - self.tk.call(self._w, - 'paneconfigure', tagOrId)): - cnf[x[0][1:]] = (x[0][1:],) + x[1:] - return cnf - if isinstance(cnf, str) and not kw: - x = self.tk.split(self.tk.call( - self._w, 'paneconfigure', tagOrId, '-'+cnf)) - return (x[0][1:],) + x[1:] - self.tk.call((self._w, 'paneconfigure', tagOrId) + - self._options(cnf, kw)) - paneconfig = paneconfigure - - def panes(self): - """Returns an ordered list of the child panes.""" - return self.tk.call(self._w, 'panes') - -###################################################################### -# Extensions: - -class Studbutton(Button): - def __init__(self, master=None, cnf={}, **kw): - Widget.__init__(self, master, 'studbutton', cnf, kw) - self.bind('', self.tkButtonEnter) - self.bind('', self.tkButtonLeave) - self.bind('<1>', self.tkButtonDown) - self.bind('', self.tkButtonUp) - -class Tributton(Button): - def __init__(self, master=None, cnf={}, **kw): - Widget.__init__(self, master, 'tributton', cnf, kw) - self.bind('', self.tkButtonEnter) - self.bind('', self.tkButtonLeave) - self.bind('<1>', self.tkButtonDown) - self.bind('', self.tkButtonUp) - self['fg'] = self['bg'] - self['activebackground'] = self['bg'] - -###################################################################### -# Test: - -def _test(): - root = Tk() - text = "This is Tcl/Tk version %s" % TclVersion - if TclVersion >= 8.1: - text += "\nThis should be a cedilla: \xe7" - label = Label(root, text=text) - label.pack() - test = Button(root, text="Click me!", - command=lambda root=root: root.test.configure( - text="[%s]" % root.test['text'])) - test.pack() - root.test = test - quit = Button(root, text="QUIT", command=root.destroy) - quit.pack() - # The following three commands are needed so the window pops - # up on top on Windows... - root.iconify() - root.update() - root.deiconify() - root.mainloop() - -if __name__ == '__main__': - _test() Index: Lib/lib-tk/FixTk.py =================================================================== --- Lib/lib-tk/FixTk.py (revision 63074) +++ Lib/lib-tk/FixTk.py (working copy) @@ -1,41 +0,0 @@ -import sys, os - -# Delay import _tkinter until we have set TCL_LIBRARY, -# so that Tcl_FindExecutable has a chance to locate its -# encoding directory. - -# Unfortunately, we cannot know the TCL_LIBRARY directory -# if we don't know the tcl version, which we cannot find out -# without import Tcl. Fortunately, Tcl will itself look in -# \..\tcl, so anything close to -# the real Tcl library will do. - -prefix = os.path.join(sys.prefix,"tcl") -if not os.path.exists(prefix): - # devdir/../tcltk/lib - prefix = os.path.join(sys.prefix, os.path.pardir, "tcltk", "lib") - prefix = os.path.abspath(prefix) -# if this does not exist, no further search is needed -if os.path.exists(prefix): - if "TCL_LIBRARY" not in os.environ: - for name in os.listdir(prefix): - if name.startswith("tcl"): - tcldir = os.path.join(prefix,name) - if os.path.isdir(tcldir): - os.environ["TCL_LIBRARY"] = tcldir - # Compute TK_LIBRARY, knowing that it has the same version - # as Tcl - import _tkinter - ver = str(_tkinter.TCL_VERSION) - if "TK_LIBRARY" not in os.environ: - v = os.path.join(prefix, 'tk'+ver) - if os.path.exists(os.path.join(v, "tclIndex")): - os.environ['TK_LIBRARY'] = v - # We don't know the Tix version, so we must search the entire - # directory - if "TIX_LIBRARY" not in os.environ: - for name in os.listdir(prefix): - if name.startswith("tix"): - tixdir = os.path.join(prefix,name) - if os.path.isdir(tixdir): - os.environ["TIX_LIBRARY"] = tixdir Index: Makefile.pre.in =================================================================== --- Makefile.pre.in (revision 63124) +++ Makefile.pre.in (working copy) @@ -808,7 +808,7 @@ plat-mac/lib-scriptpackages/SystemEvents \ plat-mac/lib-scriptpackages/Terminal PLATMACPATH=:plat-mac:plat-mac/lib-scriptpackages -LIBSUBDIRS= lib-tk site-packages test test/output test/data \ +LIBSUBDIRS= tkinter site-packages test test/output test/data \ test/decimaltestdata \ encodings \ email email/mime email/test email/test/data \ Index: Modules/Setup.dist =================================================================== --- Modules/Setup.dist (revision 63074) +++ Modules/Setup.dist (working copy) @@ -94,11 +94,7 @@ MACHDEPPATH=:plat-$(MACHDEP) EXTRAMACHDEPPATH= -# Path component for the Tkinter-related modules -# The TKPATH variable is always enabled, to save you the effort. -TKPATH=:lib-tk - -COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)$(MACHDEPPATH)$(EXTRAMACHDEPPATH)$(TKPATH) +COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)$(MACHDEPPATH)$(EXTRAMACHDEPPATH) PYTHONPATH=$(COREPYTHONPATH)