From 7fafbc95c0c963438197c9a43fe893c4ea6fe759 Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Thu, 30 Dec 2010 21:33:07 +0000 Subject: More cleanup: Move some demos into a dedicated Tools/demo dir, move 2to3 demo to Tools, and remove all the other Demo content. --- Demo/README | 62 -- Demo/classes/Complex.py | 304 ------- Demo/classes/Dates.py | 227 ----- Demo/classes/README | 11 - Demo/classes/Range.py | 93 --- Demo/classes/Rev.py | 93 --- Demo/classes/Vec.py | 68 -- Demo/classes/bitvec.py | 322 -------- Demo/curses/README | 25 - Demo/curses/life.py | 250 ------ Demo/curses/repeat.py | 80 -- Demo/distutils/test2to3/README | 3 - Demo/distutils/test2to3/maintest.py | 10 - Demo/distutils/test2to3/setup.py | 26 - Demo/distutils/test2to3/test/runtests.py | 19 - Demo/distutils/test2to3/test/test_foo.py | 8 - Demo/distutils/test2to3/test2to3/__init__.py | 1 - Demo/distutils/test2to3/test2to3/hello.py | 5 - Demo/embed/Makefile | 57 -- Demo/embed/README | 19 - Demo/embed/demo.c | 89 -- Demo/embed/importexc.c | 23 - Demo/embed/loop.c | 33 - Demo/newmetaclasses/Eiffel.py | 141 ---- Demo/newmetaclasses/Enum.py | 177 ---- Demo/scripts/README | 22 - Demo/scripts/beer.py | 20 - Demo/scripts/fact.py | 49 -- Demo/scripts/markov.py | 121 --- Demo/scripts/queens.py | 85 -- Demo/scripts/unbirthday.py | 106 --- Demo/sockets/README | 14 - Demo/sockets/broadcast.py | 15 - Demo/sockets/echosvr.py | 31 - Demo/sockets/finger.py | 58 -- Demo/sockets/ftp.py | 152 ---- Demo/sockets/gopher.py | 352 -------- Demo/sockets/mcast.py | 80 -- Demo/sockets/radio.py | 14 - Demo/sockets/rpython.py | 35 - Demo/sockets/rpythond.py | 52 -- Demo/sockets/telnet.py | 109 --- Demo/sockets/throughput.py | 93 --- Demo/sockets/udpecho.py | 64 -- Demo/sockets/unicast.py | 14 - Demo/sockets/unixclient.py | 12 - Demo/sockets/unixserver.py | 24 - Demo/tix/INSTALL.txt | 89 -- Demo/tix/README.txt | 19 - Demo/tix/bitmaps/about.xpm | 50 -- Demo/tix/bitmaps/bold.xbm | 6 - Demo/tix/bitmaps/capital.xbm | 6 - Demo/tix/bitmaps/centerj.xbm | 6 - Demo/tix/bitmaps/combobox.xbm | 14 - Demo/tix/bitmaps/combobox.xpm | 49 -- Demo/tix/bitmaps/combobox.xpm.1 | 47 -- Demo/tix/bitmaps/drivea.xbm | 14 - Demo/tix/bitmaps/drivea.xpm | 43 - Demo/tix/bitmaps/exit.xpm | 48 -- Demo/tix/bitmaps/filebox.xbm | 14 - Demo/tix/bitmaps/filebox.xpm | 49 -- Demo/tix/bitmaps/italic.xbm | 6 - Demo/tix/bitmaps/justify.xbm | 6 - Demo/tix/bitmaps/leftj.xbm | 6 - Demo/tix/bitmaps/netw.xbm | 14 - Demo/tix/bitmaps/netw.xpm | 45 - Demo/tix/bitmaps/optmenu.xpm | 48 -- Demo/tix/bitmaps/rightj.xbm | 6 - Demo/tix/bitmaps/select.xpm | 52 -- Demo/tix/bitmaps/tix.gif | Bin 11042 -> 0 bytes Demo/tix/bitmaps/underline.xbm | 6 - Demo/tix/grid.py | 28 - Demo/tix/samples/Balloon.py | 68 -- Demo/tix/samples/BtnBox.py | 44 - Demo/tix/samples/CmpImg.py | 196 ----- Demo/tix/samples/ComboBox.py | 102 --- Demo/tix/samples/Control.py | 122 --- Demo/tix/samples/DirList.py | 131 --- Demo/tix/samples/DirTree.py | 117 --- Demo/tix/samples/NoteBook.py | 119 --- Demo/tix/samples/OptMenu.py | 68 -- Demo/tix/samples/PanedWin.py | 98 --- Demo/tix/samples/PopMenu.py | 57 -- Demo/tix/samples/SHList1.py | 131 --- Demo/tix/samples/SHList2.py | 168 ---- Demo/tix/samples/Tree.py | 80 -- Demo/tix/tixwidgets.py | 1002 ----------------------- Demo/tkinter/README | 11 - Demo/tkinter/guido/attr_dialog.py | 460 ----------- Demo/tkinter/guido/brownian.py | 50 -- Demo/tkinter/guido/brownian2.py | 55 -- Demo/tkinter/guido/canvasevents.py | 264 ------ Demo/tkinter/guido/dialog.py | 108 --- Demo/tkinter/guido/electrons.py | 91 -- Demo/tkinter/guido/hanoi.py | 154 ---- Demo/tkinter/guido/hello.py | 17 - Demo/tkinter/guido/imagedraw.py | 23 - Demo/tkinter/guido/imageview.py | 12 - Demo/tkinter/guido/kill.py | 96 --- Demo/tkinter/guido/listtree.py | 34 - Demo/tkinter/guido/manpage.py | 215 ----- Demo/tkinter/guido/mbox.py | 286 ------- Demo/tkinter/guido/mimeviewer.py | 159 ---- Demo/tkinter/guido/newmenubardemo.py | 47 -- Demo/tkinter/guido/optionmenu.py | 27 - Demo/tkinter/guido/paint.py | 60 -- Demo/tkinter/guido/rmt.py | 159 ---- Demo/tkinter/guido/shell_window.py | 146 ---- Demo/tkinter/guido/solitaire.py | 626 -------------- Demo/tkinter/guido/sortvisu.py | 636 -------------- Demo/tkinter/guido/ss1.py | 842 ------------------- Demo/tkinter/guido/svkill.py | 124 --- Demo/tkinter/guido/switch.py | 55 -- Demo/tkinter/guido/tkman.py | 267 ------ Demo/tkinter/guido/wish.py | 34 - Demo/tkinter/matt/00-HELLO-WORLD.py | 27 - Demo/tkinter/matt/README | 30 - Demo/tkinter/matt/animation-simple.py | 35 - Demo/tkinter/matt/animation-w-velocity-ctrl.py | 44 - Demo/tkinter/matt/bind-w-mult-calls-p-type.py | 43 - Demo/tkinter/matt/canvas-demo-simple.py | 28 - Demo/tkinter/matt/canvas-gridding.py | 61 -- Demo/tkinter/matt/canvas-moving-or-creating.py | 62 -- Demo/tkinter/matt/canvas-moving-w-mouse.py | 55 -- Demo/tkinter/matt/canvas-mult-item-sel.py | 78 -- Demo/tkinter/matt/canvas-reading-tag-info.py | 49 -- Demo/tkinter/matt/canvas-w-widget-draw-el.py | 36 - Demo/tkinter/matt/canvas-with-scrollbars.py | 60 -- Demo/tkinter/matt/dialog-box.py | 64 -- Demo/tkinter/matt/entry-simple.py | 24 - Demo/tkinter/matt/entry-with-shared-variable.py | 45 - Demo/tkinter/matt/killing-window-w-wm.py | 42 - Demo/tkinter/matt/menu-all-types-of-entries.py | 244 ------ Demo/tkinter/matt/menu-simple.py | 112 --- Demo/tkinter/matt/not-what-you-might-think-1.py | 28 - Demo/tkinter/matt/not-what-you-might-think-2.py | 30 - Demo/tkinter/matt/packer-and-placer-together.py | 41 - Demo/tkinter/matt/packer-simple.py | 32 - Demo/tkinter/matt/placer-simple.py | 39 - Demo/tkinter/matt/pong-demo-1.py | 52 -- Demo/tkinter/matt/printing-coords-of-items.py | 61 -- Demo/tkinter/matt/radiobutton-simple.py | 62 -- Demo/tkinter/matt/rubber-band-box-demo-1.py | 58 -- Demo/tkinter/matt/rubber-line-demo-1.py | 51 -- Demo/tkinter/matt/slider-demo-1.py | 36 - Demo/tkinter/matt/subclass-existing-widgets.py | 28 - Demo/tkinter/matt/two-radio-groups.py | 110 --- Demo/tkinter/matt/window-creation-more.py | 35 - Demo/tkinter/matt/window-creation-simple.py | 31 - Demo/tkinter/matt/window-creation-w-location.py | 45 - Demo/tkinter/ttk/combo_themes.py | 46 -- Demo/tkinter/ttk/dirbrowser.py | 93 --- Demo/tkinter/ttk/img/close.gif | Bin 101 -> 0 bytes Demo/tkinter/ttk/img/close_active.gif | Bin 80 -> 0 bytes Demo/tkinter/ttk/img/close_pressed.gif | Bin 101 -> 0 bytes Demo/tkinter/ttk/listbox_scrollcmd.py | 37 - Demo/tkinter/ttk/mac_searchentry.py | 78 -- Demo/tkinter/ttk/notebook_closebtn.py | 78 -- Demo/tkinter/ttk/plastik_theme.py | 268 ------ Demo/tkinter/ttk/roundframe.py | 111 --- Demo/tkinter/ttk/theme_selector.py | 61 -- Demo/tkinter/ttk/treeview_multicolumn.py | 107 --- Demo/tkinter/ttk/ttkcalendar.py | 231 ------ Demo/tkinter/ttk/widget_state.py | 83 -- Tools/demo/Eiffel.py | 141 ++++ Tools/demo/Vec.py | 68 ++ Tools/demo/beer.py | 20 + Tools/demo/hanoi.py | 154 ++++ Tools/demo/life.py | 250 ++++++ Tools/demo/markov.py | 121 +++ Tools/demo/mcast.py | 80 ++ Tools/demo/queens.py | 85 ++ Tools/demo/rpython.py | 36 + Tools/demo/rpythond.py | 55 ++ Tools/demo/sortvisu.py | 636 ++++++++++++++ Tools/demo/ss1.py | 842 +++++++++++++++++++ Tools/test2to3/README | 3 + Tools/test2to3/maintest.py | 10 + Tools/test2to3/setup.py | 26 + Tools/test2to3/test/runtests.py | 19 + Tools/test2to3/test/test_foo.py | 8 + Tools/test2to3/test2to3/__init__.py | 1 + Tools/test2to3/test2to3/hello.py | 5 + 183 files changed, 2560 insertions(+), 14971 deletions(-) delete mode 100644 Demo/README delete mode 100644 Demo/classes/Complex.py delete mode 100644 Demo/classes/Dates.py delete mode 100644 Demo/classes/README delete mode 100644 Demo/classes/Range.py delete mode 100644 Demo/classes/Rev.py delete mode 100644 Demo/classes/Vec.py delete mode 100644 Demo/classes/bitvec.py delete mode 100644 Demo/curses/README delete mode 100755 Demo/curses/life.py delete mode 100755 Demo/curses/repeat.py delete mode 100644 Demo/distutils/test2to3/README delete mode 100644 Demo/distutils/test2to3/maintest.py delete mode 100644 Demo/distutils/test2to3/setup.py delete mode 100644 Demo/distutils/test2to3/test/runtests.py delete mode 100644 Demo/distutils/test2to3/test/test_foo.py delete mode 100644 Demo/distutils/test2to3/test2to3/__init__.py delete mode 100644 Demo/distutils/test2to3/test2to3/hello.py delete mode 100644 Demo/embed/Makefile delete mode 100644 Demo/embed/README delete mode 100644 Demo/embed/demo.c delete mode 100644 Demo/embed/importexc.c delete mode 100644 Demo/embed/loop.c delete mode 100644 Demo/newmetaclasses/Eiffel.py delete mode 100644 Demo/newmetaclasses/Enum.py delete mode 100644 Demo/scripts/README delete mode 100755 Demo/scripts/beer.py delete mode 100755 Demo/scripts/fact.py delete mode 100755 Demo/scripts/markov.py delete mode 100755 Demo/scripts/queens.py delete mode 100755 Demo/scripts/unbirthday.py delete mode 100644 Demo/sockets/README delete mode 100644 Demo/sockets/broadcast.py delete mode 100755 Demo/sockets/echosvr.py delete mode 100755 Demo/sockets/finger.py delete mode 100644 Demo/sockets/ftp.py delete mode 100755 Demo/sockets/gopher.py delete mode 100755 Demo/sockets/mcast.py delete mode 100644 Demo/sockets/radio.py delete mode 100755 Demo/sockets/rpython.py delete mode 100755 Demo/sockets/rpythond.py delete mode 100755 Demo/sockets/telnet.py delete mode 100755 Demo/sockets/throughput.py delete mode 100755 Demo/sockets/udpecho.py delete mode 100644 Demo/sockets/unicast.py delete mode 100644 Demo/sockets/unixclient.py delete mode 100644 Demo/sockets/unixserver.py delete mode 100644 Demo/tix/INSTALL.txt delete mode 100644 Demo/tix/README.txt delete mode 100755 Demo/tix/bitmaps/about.xpm delete mode 100755 Demo/tix/bitmaps/bold.xbm delete mode 100755 Demo/tix/bitmaps/capital.xbm delete mode 100755 Demo/tix/bitmaps/centerj.xbm delete mode 100755 Demo/tix/bitmaps/combobox.xbm delete mode 100755 Demo/tix/bitmaps/combobox.xpm delete mode 100755 Demo/tix/bitmaps/combobox.xpm.1 delete mode 100755 Demo/tix/bitmaps/drivea.xbm delete mode 100755 Demo/tix/bitmaps/drivea.xpm delete mode 100755 Demo/tix/bitmaps/exit.xpm delete mode 100755 Demo/tix/bitmaps/filebox.xbm delete mode 100755 Demo/tix/bitmaps/filebox.xpm delete mode 100755 Demo/tix/bitmaps/italic.xbm delete mode 100755 Demo/tix/bitmaps/justify.xbm delete mode 100755 Demo/tix/bitmaps/leftj.xbm delete mode 100755 Demo/tix/bitmaps/netw.xbm delete mode 100755 Demo/tix/bitmaps/netw.xpm delete mode 100755 Demo/tix/bitmaps/optmenu.xpm delete mode 100755 Demo/tix/bitmaps/rightj.xbm delete mode 100755 Demo/tix/bitmaps/select.xpm delete mode 100755 Demo/tix/bitmaps/tix.gif delete mode 100755 Demo/tix/bitmaps/underline.xbm delete mode 100644 Demo/tix/grid.py delete mode 100644 Demo/tix/samples/Balloon.py delete mode 100644 Demo/tix/samples/BtnBox.py delete mode 100644 Demo/tix/samples/CmpImg.py delete mode 100644 Demo/tix/samples/ComboBox.py delete mode 100644 Demo/tix/samples/Control.py delete mode 100644 Demo/tix/samples/DirList.py delete mode 100644 Demo/tix/samples/DirTree.py delete mode 100644 Demo/tix/samples/NoteBook.py delete mode 100644 Demo/tix/samples/OptMenu.py delete mode 100644 Demo/tix/samples/PanedWin.py delete mode 100644 Demo/tix/samples/PopMenu.py delete mode 100644 Demo/tix/samples/SHList1.py delete mode 100644 Demo/tix/samples/SHList2.py delete mode 100644 Demo/tix/samples/Tree.py delete mode 100644 Demo/tix/tixwidgets.py delete mode 100644 Demo/tkinter/README delete mode 100644 Demo/tkinter/guido/attr_dialog.py delete mode 100644 Demo/tkinter/guido/brownian.py delete mode 100644 Demo/tkinter/guido/brownian2.py delete mode 100644 Demo/tkinter/guido/canvasevents.py delete mode 100755 Demo/tkinter/guido/dialog.py delete mode 100755 Demo/tkinter/guido/electrons.py delete mode 100644 Demo/tkinter/guido/hanoi.py delete mode 100644 Demo/tkinter/guido/hello.py delete mode 100644 Demo/tkinter/guido/imagedraw.py delete mode 100644 Demo/tkinter/guido/imageview.py delete mode 100755 Demo/tkinter/guido/kill.py delete mode 100644 Demo/tkinter/guido/listtree.py delete mode 100644 Demo/tkinter/guido/manpage.py delete mode 100755 Demo/tkinter/guido/mbox.py delete mode 100755 Demo/tkinter/guido/mimeviewer.py delete mode 100644 Demo/tkinter/guido/newmenubardemo.py delete mode 100644 Demo/tkinter/guido/optionmenu.py delete mode 100644 Demo/tkinter/guido/paint.py delete mode 100755 Demo/tkinter/guido/rmt.py delete mode 100644 Demo/tkinter/guido/shell_window.py delete mode 100755 Demo/tkinter/guido/solitaire.py delete mode 100644 Demo/tkinter/guido/sortvisu.py delete mode 100644 Demo/tkinter/guido/ss1.py delete mode 100755 Demo/tkinter/guido/svkill.py delete mode 100644 Demo/tkinter/guido/switch.py delete mode 100755 Demo/tkinter/guido/tkman.py delete mode 100644 Demo/tkinter/guido/wish.py delete mode 100644 Demo/tkinter/matt/00-HELLO-WORLD.py delete mode 100644 Demo/tkinter/matt/README delete mode 100644 Demo/tkinter/matt/animation-simple.py delete mode 100644 Demo/tkinter/matt/animation-w-velocity-ctrl.py delete mode 100644 Demo/tkinter/matt/bind-w-mult-calls-p-type.py delete mode 100644 Demo/tkinter/matt/canvas-demo-simple.py delete mode 100644 Demo/tkinter/matt/canvas-gridding.py delete mode 100644 Demo/tkinter/matt/canvas-moving-or-creating.py delete mode 100644 Demo/tkinter/matt/canvas-moving-w-mouse.py delete mode 100644 Demo/tkinter/matt/canvas-mult-item-sel.py delete mode 100644 Demo/tkinter/matt/canvas-reading-tag-info.py delete mode 100644 Demo/tkinter/matt/canvas-w-widget-draw-el.py delete mode 100644 Demo/tkinter/matt/canvas-with-scrollbars.py delete mode 100644 Demo/tkinter/matt/dialog-box.py delete mode 100644 Demo/tkinter/matt/entry-simple.py delete mode 100644 Demo/tkinter/matt/entry-with-shared-variable.py delete mode 100644 Demo/tkinter/matt/killing-window-w-wm.py delete mode 100644 Demo/tkinter/matt/menu-all-types-of-entries.py delete mode 100644 Demo/tkinter/matt/menu-simple.py delete mode 100644 Demo/tkinter/matt/not-what-you-might-think-1.py delete mode 100644 Demo/tkinter/matt/not-what-you-might-think-2.py delete mode 100644 Demo/tkinter/matt/packer-and-placer-together.py delete mode 100644 Demo/tkinter/matt/packer-simple.py delete mode 100644 Demo/tkinter/matt/placer-simple.py delete mode 100644 Demo/tkinter/matt/pong-demo-1.py delete mode 100644 Demo/tkinter/matt/printing-coords-of-items.py delete mode 100644 Demo/tkinter/matt/radiobutton-simple.py delete mode 100644 Demo/tkinter/matt/rubber-band-box-demo-1.py delete mode 100644 Demo/tkinter/matt/rubber-line-demo-1.py delete mode 100644 Demo/tkinter/matt/slider-demo-1.py delete mode 100644 Demo/tkinter/matt/subclass-existing-widgets.py delete mode 100644 Demo/tkinter/matt/two-radio-groups.py delete mode 100644 Demo/tkinter/matt/window-creation-more.py delete mode 100644 Demo/tkinter/matt/window-creation-simple.py delete mode 100644 Demo/tkinter/matt/window-creation-w-location.py delete mode 100644 Demo/tkinter/ttk/combo_themes.py delete mode 100644 Demo/tkinter/ttk/dirbrowser.py delete mode 100644 Demo/tkinter/ttk/img/close.gif delete mode 100644 Demo/tkinter/ttk/img/close_active.gif delete mode 100644 Demo/tkinter/ttk/img/close_pressed.gif delete mode 100644 Demo/tkinter/ttk/listbox_scrollcmd.py delete mode 100644 Demo/tkinter/ttk/mac_searchentry.py delete mode 100644 Demo/tkinter/ttk/notebook_closebtn.py delete mode 100644 Demo/tkinter/ttk/plastik_theme.py delete mode 100644 Demo/tkinter/ttk/roundframe.py delete mode 100644 Demo/tkinter/ttk/theme_selector.py delete mode 100644 Demo/tkinter/ttk/treeview_multicolumn.py delete mode 100644 Demo/tkinter/ttk/ttkcalendar.py delete mode 100644 Demo/tkinter/ttk/widget_state.py create mode 100644 Tools/demo/Eiffel.py create mode 100644 Tools/demo/Vec.py create mode 100755 Tools/demo/beer.py create mode 100644 Tools/demo/hanoi.py create mode 100755 Tools/demo/life.py create mode 100755 Tools/demo/markov.py create mode 100755 Tools/demo/mcast.py create mode 100755 Tools/demo/queens.py create mode 100755 Tools/demo/rpython.py create mode 100755 Tools/demo/rpythond.py create mode 100644 Tools/demo/sortvisu.py create mode 100644 Tools/demo/ss1.py create mode 100644 Tools/test2to3/README create mode 100644 Tools/test2to3/maintest.py create mode 100644 Tools/test2to3/setup.py create mode 100644 Tools/test2to3/test/runtests.py create mode 100644 Tools/test2to3/test/test_foo.py create mode 100644 Tools/test2to3/test2to3/__init__.py create mode 100644 Tools/test2to3/test2to3/hello.py diff --git a/Demo/README b/Demo/README deleted file mode 100644 index 5105e0f..0000000 --- a/Demo/README +++ /dev/null @@ -1,62 +0,0 @@ -This directory contains various demonstrations of what you can do with -Python. They were all written by me except where explicitly stated -otherwise -- in general, demos contributed by others ends up in the -../Contrib directory, unless I think they're of utmost general -importance (like Matt Conway's Tk demos). - -A fair number of utilities that are useful when while developing -Python code can be found in the ../Tools directory -- some of these -can also be considered good examples of how to write Python code. - -Finally, in order to save disk space and net bandwidth, not all -subdirectories listed here are distributed. They are listed just -in case I change my mind about them. - - -cgi CGI examples. - -classes Some examples of how to use classes. - -comparisons A set of responses to a really old language-comparison - challenge. - -curses A set of curses demos. - -distutils Test for using transparent 2to3 conversion in distutils. - -embed An example of embedding Python in another application - (see also pysvr). - -imputil Demonstration subclasses of imputil.Importer. - -md5test Test program for the optional md5 module. - -newmetaclasses Demonstration of metaclasses. - -parser Example using the parser module. - -pysvr An example of embedding Python in a threaded - application. - -rpc A set of classes for building clients and servers for - Sun RPC. - -scripts Some useful Python scripts that I put in my bin - directory. No optional built-in modules needed. - -sockets Examples for the new built-in module 'socket'. - -threads Demos that use the 'thread' module. (Currently these - only run on SGIs, but this may change in the future.) - -tix Demos using the Tix widget set addition to Tkinter. - -tkinter Demos using the Tk interface (including Matt Conway's - excellent set of demos). - -turtle Demos for the "turtle" module. - -xml Some XML demos. - -zlib Some demos for the zlib module (see also the standard - library module gzip.py). diff --git a/Demo/classes/Complex.py b/Demo/classes/Complex.py deleted file mode 100644 index 06f2212..0000000 --- a/Demo/classes/Complex.py +++ /dev/null @@ -1,304 +0,0 @@ -# Complex numbers -# --------------- - -# [Now that Python has a complex data type built-in, this is not very -# useful, but it's still a nice example class] - -# This module represents complex numbers as instances of the class Complex. -# A Complex instance z has two data attribues, z.re (the real part) and z.im -# (the imaginary part). In fact, z.re and z.im can have any value -- all -# arithmetic operators work regardless of the type of z.re and z.im (as long -# as they support numerical operations). -# -# The following functions exist (Complex is actually a class): -# Complex([re [,im]) -> creates a complex number from a real and an imaginary part -# IsComplex(z) -> true iff z is a complex number (== has .re and .im attributes) -# ToComplex(z) -> a complex number equal to z; z itself if IsComplex(z) is true -# if z is a tuple(re, im) it will also be converted -# PolarToComplex([r [,phi [,fullcircle]]]) -> -# the complex number z for which r == z.radius() and phi == z.angle(fullcircle) -# (r and phi default to 0) -# exp(z) -> returns the complex exponential of z. Equivalent to pow(math.e,z). -# -# Complex numbers have the following methods: -# z.abs() -> absolute value of z -# z.radius() == z.abs() -# z.angle([fullcircle]) -> angle from positive X axis; fullcircle gives units -# z.phi([fullcircle]) == z.angle(fullcircle) -# -# These standard functions and unary operators accept complex arguments: -# abs(z) -# -z -# +z -# not z -# repr(z) == `z` -# str(z) -# hash(z) -> a combination of hash(z.re) and hash(z.im) such that if z.im is zero -# the result equals hash(z.re) -# Note that hex(z) and oct(z) are not defined. -# -# These conversions accept complex arguments only if their imaginary part is zero: -# int(z) -# float(z) -# -# The following operators accept two complex numbers, or one complex number -# and one real number (int, long or float): -# z1 + z2 -# z1 - z2 -# z1 * z2 -# z1 / z2 -# pow(z1, z2) -# cmp(z1, z2) -# Note that z1 % z2 and divmod(z1, z2) are not defined, -# nor are shift and mask operations. -# -# The standard module math does not support complex numbers. -# The cmath modules should be used instead. -# -# Idea: -# add a class Polar(r, phi) and mixed-mode arithmetic which -# chooses the most appropriate type for the result: -# Complex for +,-,cmp -# Polar for *,/,pow - -import math -import sys - -twopi = math.pi*2.0 -halfpi = math.pi/2.0 - -def IsComplex(obj): - return hasattr(obj, 're') and hasattr(obj, 'im') - -def ToComplex(obj): - if IsComplex(obj): - return obj - elif isinstance(obj, tuple): - return Complex(*obj) - else: - return Complex(obj) - -def PolarToComplex(r = 0, phi = 0, fullcircle = twopi): - phi = phi * (twopi / fullcircle) - return Complex(math.cos(phi)*r, math.sin(phi)*r) - -def Re(obj): - if IsComplex(obj): - return obj.re - return obj - -def Im(obj): - if IsComplex(obj): - return obj.im - return 0 - -class Complex: - - def __init__(self, re=0, im=0): - _re = 0 - _im = 0 - if IsComplex(re): - _re = re.re - _im = re.im - else: - _re = re - if IsComplex(im): - _re = _re - im.im - _im = _im + im.re - else: - _im = _im + im - # this class is immutable, so setting self.re directly is - # not possible. - self.__dict__['re'] = _re - self.__dict__['im'] = _im - - def __setattr__(self, name, value): - raise TypeError('Complex numbers are immutable') - - def __hash__(self): - if not self.im: - return hash(self.re) - return hash((self.re, self.im)) - - def __repr__(self): - if not self.im: - return 'Complex(%r)' % (self.re,) - else: - return 'Complex(%r, %r)' % (self.re, self.im) - - def __str__(self): - if not self.im: - return repr(self.re) - else: - return 'Complex(%r, %r)' % (self.re, self.im) - - def __neg__(self): - return Complex(-self.re, -self.im) - - def __pos__(self): - return self - - def __abs__(self): - return math.hypot(self.re, self.im) - - def __int__(self): - if self.im: - raise ValueError("can't convert Complex with nonzero im to int") - return int(self.re) - - def __float__(self): - if self.im: - raise ValueError("can't convert Complex with nonzero im to float") - return float(self.re) - - def __eq__(self, other): - other = ToComplex(other) - return (self.re, self.im) == (other.re, other.im) - - def __bool__(self): - return not (self.re == self.im == 0) - - abs = radius = __abs__ - - def angle(self, fullcircle = twopi): - return (fullcircle/twopi) * ((halfpi - math.atan2(self.re, self.im)) % twopi) - - phi = angle - - def __add__(self, other): - other = ToComplex(other) - return Complex(self.re + other.re, self.im + other.im) - - __radd__ = __add__ - - def __sub__(self, other): - other = ToComplex(other) - return Complex(self.re - other.re, self.im - other.im) - - def __rsub__(self, other): - other = ToComplex(other) - return other - self - - def __mul__(self, other): - other = ToComplex(other) - return Complex(self.re*other.re - self.im*other.im, - self.re*other.im + self.im*other.re) - - __rmul__ = __mul__ - - def __truediv__(self, other): - other = ToComplex(other) - d = float(other.re*other.re + other.im*other.im) - if not d: raise ZeroDivisionError('Complex division') - return Complex((self.re*other.re + self.im*other.im) / d, - (self.im*other.re - self.re*other.im) / d) - - def __rtruediv__(self, other): - other = ToComplex(other) - return other / self - - def __pow__(self, n, z=None): - if z is not None: - raise TypeError('Complex does not support ternary pow()') - if IsComplex(n): - if n.im: - if self.im: raise TypeError('Complex to the Complex power') - else: return exp(math.log(self.re)*n) - n = n.re - r = pow(self.abs(), n) - phi = n*self.angle() - return Complex(math.cos(phi)*r, math.sin(phi)*r) - - def __rpow__(self, base): - base = ToComplex(base) - return pow(base, self) - -def exp(z): - r = math.exp(z.re) - return Complex(math.cos(z.im)*r,math.sin(z.im)*r) - - -def checkop(expr, a, b, value, fuzz = 1e-6): - print(' ', a, 'and', b, end=' ') - try: - result = eval(expr) - except Exception as e: - print('!!\t!!\t!! error: {}'.format(e)) - return - print('->', result) - if isinstance(result, str) or isinstance(value, str): - ok = (result == value) - else: - ok = abs(result - value) <= fuzz - if not ok: - print('!!\t!!\t!! should be', value, 'diff', abs(result - value)) - -def test(): - print('test constructors') - constructor_test = ( - # "expect" is an array [re,im] "got" the Complex. - ( (0,0), Complex() ), - ( (0,0), Complex() ), - ( (1,0), Complex(1) ), - ( (0,1), Complex(0,1) ), - ( (1,2), Complex(Complex(1,2)) ), - ( (1,3), Complex(Complex(1,2),1) ), - ( (0,0), Complex(0,Complex(0,0)) ), - ( (3,4), Complex(3,Complex(4)) ), - ( (-1,3), Complex(1,Complex(3,2)) ), - ( (-7,6), Complex(Complex(1,2),Complex(4,8)) ) ) - cnt = [0,0] - for t in constructor_test: - cnt[0] += 1 - if ((t[0][0]!=t[1].re)or(t[0][1]!=t[1].im)): - print(" expected", t[0], "got", t[1]) - cnt[1] += 1 - print(" ", cnt[1], "of", cnt[0], "tests failed") - # test operators - testsuite = { - 'a+b': [ - (1, 10, 11), - (1, Complex(0,10), Complex(1,10)), - (Complex(0,10), 1, Complex(1,10)), - (Complex(0,10), Complex(1), Complex(1,10)), - (Complex(1), Complex(0,10), Complex(1,10)), - ], - 'a-b': [ - (1, 10, -9), - (1, Complex(0,10), Complex(1,-10)), - (Complex(0,10), 1, Complex(-1,10)), - (Complex(0,10), Complex(1), Complex(-1,10)), - (Complex(1), Complex(0,10), Complex(1,-10)), - ], - 'a*b': [ - (1, 10, 10), - (1, Complex(0,10), Complex(0, 10)), - (Complex(0,10), 1, Complex(0,10)), - (Complex(0,10), Complex(1), Complex(0,10)), - (Complex(1), Complex(0,10), Complex(0,10)), - ], - 'a/b': [ - (1., 10, 0.1), - (1, Complex(0,10), Complex(0, -0.1)), - (Complex(0, 10), 1, Complex(0, 10)), - (Complex(0, 10), Complex(1), Complex(0, 10)), - (Complex(1), Complex(0,10), Complex(0, -0.1)), - ], - 'pow(a,b)': [ - (1, 10, 1), - (1, Complex(0,10), 1), - (Complex(0,10), 1, Complex(0,10)), - (Complex(0,10), Complex(1), Complex(0,10)), - (Complex(1), Complex(0,10), 1), - (2, Complex(4,0), 16), - ], - } - for expr in sorted(testsuite): - print(expr + ':') - t = (expr,) - for item in testsuite[expr]: - checkop(*(t+item)) - - -if __name__ == '__main__': - test() diff --git a/Demo/classes/Dates.py b/Demo/classes/Dates.py deleted file mode 100644 index 63488ce..0000000 --- a/Demo/classes/Dates.py +++ /dev/null @@ -1,227 +0,0 @@ -""" -Class Date supplies date objects that support date arithmetic. - -Date(month,day,year) returns a Date object. An instance prints as, -e.g., 'Mon 16 Aug 1993'. - -Addition, subtraction, comparison operators, min, max, and sorting -all work as expected for date objects: int+date or date+int returns -the date `int' days from `date'; date+date raises an exception; -date-int returns the date `int' days before `date'; date2-date1 returns -an integer, the number of days from date1 to date2; int-date raises an -exception; date1 < date2 is true iff date1 occurs before date2 (& -similarly for other comparisons); min(date1,date2) is the earlier of -the two dates and max(date1,date2) the later; and date objects can be -used as dictionary keys. - -Date objects support one visible method, date.weekday(). This returns -the day of the week the date falls on, as a string. - -Date objects also have 4 read-only data attributes: - .month in 1..12 - .day in 1..31 - .year int or long int - .ord the ordinal of the date relative to an arbitrary staring point - -The Dates module also supplies function today(), which returns the -current date as a date object. - -Those entranced by calendar trivia will be disappointed, as no attempt -has been made to accommodate the Julian (etc) system. On the other -hand, at least this package knows that 2000 is a leap year but 2100 -isn't, and works fine for years with a hundred decimal digits . - -Tim Peters tim@ksr.com -not speaking for Kendall Square Research Corp - -Adapted to Python 1.1 (where some hacks to overcome coercion are unnecessary) -by Guido van Rossum - -Note that as of Python 2.3, a datetime module is included in the stardard -library. -""" - -import functools - -_MONTH_NAMES = [ 'January', 'February', 'March', 'April', 'May', - 'June', 'July', 'August', 'September', 'October', - 'November', 'December' ] - -_DAY_NAMES = [ 'Friday', 'Saturday', 'Sunday', 'Monday', - 'Tuesday', 'Wednesday', 'Thursday' ] - -_DAYS_IN_MONTH = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ] - -_DAYS_BEFORE_MONTH = [] -dbm = 0 -for dim in _DAYS_IN_MONTH: - _DAYS_BEFORE_MONTH.append(dbm) - dbm = dbm + dim -del dbm, dim - -def _is_leap(year): # 1 if leap year, else 0 - if year % 4 != 0: return 0 - if year % 400 == 0: return 1 - return year % 100 != 0 - -def _days_in_year(year): # number of days in year - return 365 + _is_leap(year) - -def _days_before_year(year): # number of days before year - return year*365 + (year+3)//4 - (year+99)//100 + (year+399)//400 - -def _days_in_month(month, year): # number of days in month of year - if month == 2 and _is_leap(year): return 29 - return _DAYS_IN_MONTH[month-1] - -def _days_before_month(month, year): # number of days in year before month - return _DAYS_BEFORE_MONTH[month-1] + (month > 2 and _is_leap(year)) - -def _date2num(date): # compute ordinal of date.month,day,year - return _days_before_year(date.year) + \ - _days_before_month(date.month, date.year) + \ - date.day - -_DI400Y = _days_before_year(400) # number of days in 400 years - -def _num2date(n): # return date with ordinal n - if not isinstance(n, int): - raise TypeError('argument must be integer: %r' % type(n)) - - # Get uninitialized Date object. This is necesary because once - # attributes are set, they cannot be changed. - ans = Date.__new__(Date) - ans.ord = n - - n400 = (n-1)//_DI400Y # # of 400-year blocks preceding - year, n = 400 * n400, n - _DI400Y * n400 - more = n // 365 - dby = _days_before_year(more) - if dby >= n: - more = more - 1 - dby = dby - _days_in_year(more) - year, n = year + more, n - dby - month = min(n//29 + 1, 12) - dbm = _days_before_month(month, year) - if dbm >= n: - month = month - 1 - dbm = dbm - _days_in_month(month, year) - - ans.month, ans.day, ans.year = month, n-dbm, year - return ans - -def _num2day(n): # return weekday name of day with ordinal n - return _DAY_NAMES[n % 7] - -@functools.total_ordering -class Date: - def __init__(self, month, day, year): - if not 1 <= month <= 12: - raise ValueError('month must be in 1..12: %r' % (month,)) - dim = _days_in_month(month, year) - if not 1 <= day <= dim: - raise ValueError('day must be in 1..%r: %r' % (dim, day)) - self.month, self.day, self.year = map(int, (month, day, year)) - self.ord = _date2num(self) - - # don't allow setting existing attributes - def __setattr__(self, name, value): - if name in self.__dict__: - raise AttributeError('read-only attribute ' + name) - self.__dict__[name] = value - - def __eq__(self, other): - return self.ord == other.ord - - def __lt__(self, other): - return self.ord < other.ord - - # define a hash function so dates can be used as dictionary keys - def __hash__(self): - return hash(self.ord) - - # print as, e.g., Mon 16 Aug 1993 - def __repr__(self): - return '%.3s %2d %.3s %r' % ( - self.weekday(), - self.day, - _MONTH_NAMES[self.month-1], - self.year) - - # Python 1.1 coerces neither int+date nor date+int - def __add__(self, n): - if not isinstance(n, int): - raise TypeError('can\'t add %r to date' % type(n)) - return _num2date(self.ord + n) - __radd__ = __add__ # handle int+date - - # Python 1.1 coerces neither date-int nor date-date - def __sub__(self, other): - if isinstance(other, int): # date-int - return _num2date(self.ord - other) - else: - return self.ord - other.ord # date-date - - # complain about int-date - def __rsub__(self, other): - raise TypeError('Can\'t subtract date from integer') - - def weekday(self): - return _num2day(self.ord) - -def today(): - import time - local = time.localtime(time.time()) - return Date(local[1], local[2], local[0]) - -class DateTestError(Exception): - pass - -def test(firstyear, lastyear): - a = Date(9,30,1913) - b = Date(9,30,1914) - if repr(a) != 'Tue 30 Sep 1913': - raise DateTestError('__repr__ failure') - if (not a < b) or a == b or a > b or b != b: - raise DateTestError('__cmp__ failure') - if a+365 != b or 365+a != b: - raise DateTestError('__add__ failure') - if b-a != 365 or b-365 != a: - raise DateTestError('__sub__ failure') - try: - x = 1 - a - raise DateTestError('int-date should have failed') - except TypeError: - pass - try: - x = a + b - raise DateTestError('date+date should have failed') - except TypeError: - pass - if a.weekday() != 'Tuesday': - raise DateTestError('weekday() failure') - if max(a,b) is not b or min(a,b) is not a: - raise DateTestError('min/max failure') - d = {a-1:b, b:a+1} - if d[b-366] != b or d[a+(b-a)] != Date(10,1,1913): - raise DateTestError('dictionary failure') - - # verify date<->number conversions for first and last days for - # all years in firstyear .. lastyear - - lord = _days_before_year(firstyear) - y = firstyear - while y <= lastyear: - ford = lord + 1 - lord = ford + _days_in_year(y) - 1 - fd, ld = Date(1,1,y), Date(12,31,y) - if (fd.ord,ld.ord) != (ford,lord): - raise DateTestError('date->num failed', y) - fd, ld = _num2date(ford), _num2date(lord) - if (1,1,y,12,31,y) != \ - (fd.month,fd.day,fd.year,ld.month,ld.day,ld.year): - raise DateTestError('num->date failed', y) - y = y + 1 - -if __name__ == '__main__': - test(1850, 2150) diff --git a/Demo/classes/README b/Demo/classes/README deleted file mode 100644 index 3c636f0..0000000 --- a/Demo/classes/README +++ /dev/null @@ -1,11 +0,0 @@ -Examples of classes that implement special operators (see reference manual): - -Complex.py Complex numbers -Dates.py Date manipulation package by Tim Peters -Range.py Example of a generator: re-implement built-in range() -Rev.py Yield the reverse of a sequence -Vec.py A simple vector class -bitvec.py A bit-vector class by Jan-Hein B\"uhrman - -(For straightforward examples of basic class features, such as use of -methods and inheritance, see the library code.) diff --git a/Demo/classes/Range.py b/Demo/classes/Range.py deleted file mode 100644 index 4e6f45d..0000000 --- a/Demo/classes/Range.py +++ /dev/null @@ -1,93 +0,0 @@ -"""Example of a generator: re-implement the built-in range function -without actually constructing the list of values. - -OldStyleRange is coded in the way required to work in a 'for' loop before -iterators were introduced into the language; using __getitem__ and __len__ . - -""" -def handleargs(arglist): - """Take list of arguments and extract/create proper start, stop, and step - values and return in a tuple""" - try: - if len(arglist) == 1: - return 0, int(arglist[0]), 1 - elif len(arglist) == 2: - return int(arglist[0]), int(arglist[1]), 1 - elif len(arglist) == 3: - if arglist[2] == 0: - raise ValueError("step argument must not be zero") - return tuple(int(x) for x in arglist) - else: - raise TypeError("range() accepts 1-3 arguments, given", len(arglist)) - except TypeError: - raise TypeError("range() arguments must be numbers or strings " - "representing numbers") - -def genrange(*a): - """Function to implement 'range' as a generator""" - start, stop, step = handleargs(a) - value = start - while value < stop: - yield value - value += step - -class oldrange: - """Class implementing a range object. - To the user the instances feel like immutable sequences - (and you can't concatenate or slice them) - - Done using the old way (pre-iterators; __len__ and __getitem__) to have an - object be used by a 'for' loop. - - """ - - def __init__(self, *a): - """ Initialize start, stop, and step values along with calculating the - nubmer of values (what __len__ will return) in the range""" - self.start, self.stop, self.step = handleargs(a) - self.len = max(0, (self.stop - self.start) // self.step) - - def __repr__(self): - """implement repr(x) which is also used by print""" - return 'range(%r, %r, %r)' % (self.start, self.stop, self.step) - - def __len__(self): - """implement len(x)""" - return self.len - - def __getitem__(self, i): - """implement x[i]""" - if 0 <= i <= self.len: - return self.start + self.step * i - else: - raise IndexError('range[i] index out of range') - - -def test(): - import time, builtins - #Just a quick sanity check - correct_result = list(builtins.range(5, 100, 3)) - oldrange_result = list(oldrange(5, 100, 3)) - genrange_result = list(genrange(5, 100, 3)) - if genrange_result != correct_result or oldrange_result != correct_result: - raise Exception("error in implementation:\ncorrect = %s" - "\nold-style = %s\ngenerator = %s" % - (correct_result, oldrange_result, genrange_result)) - print("Timings for range(1000):") - t1 = time.time() - for i in oldrange(1000): - pass - t2 = time.time() - for i in genrange(1000): - pass - t3 = time.time() - for i in builtins.range(1000): - pass - t4 = time.time() - print(t2-t1, 'sec (old-style class)') - print(t3-t2, 'sec (generator)') - print(t4-t3, 'sec (built-in)') - - -if __name__ == '__main__': - test() diff --git a/Demo/classes/Rev.py b/Demo/classes/Rev.py deleted file mode 100644 index d36ddb9..0000000 --- a/Demo/classes/Rev.py +++ /dev/null @@ -1,93 +0,0 @@ -''' -A class which presents the reverse of a sequence without duplicating it. -From: "Steven D. Majewski" - -It works on mutable or inmutable sequences. - ->>> Rev('Hello World!') -!dlroW olleH - -The .forw is so you can use anonymous sequences in __init__, and still -keep a reference the forward sequence. ) -If you give it a non-anonymous mutable sequence, the reverse sequence -will track the updated values. ( but not reassignment! - another -good reason to use anonymous values in creating the sequence to avoid -confusion. Maybe it should be change to copy input sequence to break -the connection completely ? ) - ->>> nnn = list(range(3)) ->>> rnn = Rev(nnn) ->>> for n in rnn: n -... -2 -1 -0 ->>> for n in range(4, 6): nnn.append(n) # update nnn -... ->>> for n in rnn: n # prints reversed updated values -... -5 -4 -2 -1 -0 ->>> nnn = nnn[1:-1] ->>> nnn -[1, 2, 4] ->>> for n in rnn: n # prints reversed values of old nnn -... -5 -4 -2 -1 -0 - -# ->>> WH = Rev('Hello World!') ->>> print(WH.forw, WH.back) -Hello World! !dlroW olleH ->>> nnn = Rev(list(range(1, 10))) ->>> print(nnn.forw) -[1, 2, 3, 4, 5, 6, 7, 8, 9] ->>> print(nnn.back) -[9, 8, 7, 6, 5, 4, 3, 2, 1] - ->>> Rev(nnn) -<1, 2, 3, 4, 5, 6, 7, 8, 9> - -''' - -class Rev: - def __init__(self, seq): - self.forw = seq - self.back = self - - def __len__(self): - return len(self.forw) - - def __getitem__(self, j): - return self.forw[-(j + 1)] - - def __repr__(self): - seq = self.forw - if isinstance(seq, list): - wrap = '[]' - sep = ', ' - elif isinstance(seq, tuple): - wrap = '()' - sep = ', ' - elif isinstance(seq, str): - wrap = '' - sep = '' - else: - wrap = '<>' - sep = ', ' - outstrs = [str(item) for item in self.back] - return wrap[:1] + sep.join(outstrs) + wrap[-1:] - -def _test(): - import doctest, Rev - return doctest.testmod(Rev) - -if __name__ == "__main__": - _test() diff --git a/Demo/classes/Vec.py b/Demo/classes/Vec.py deleted file mode 100644 index 787af69..0000000 --- a/Demo/classes/Vec.py +++ /dev/null @@ -1,68 +0,0 @@ -class Vec: - """ A simple vector class - - Instances of the Vec class can be constructed from numbers - - >>> a = Vec(1, 2, 3) - >>> b = Vec(3, 2, 1) - - added - >>> a + b - Vec(4, 4, 4) - - subtracted - >>> a - b - Vec(-2, 0, 2) - - and multiplied by a scalar on the left - >>> 3.0 * a - Vec(3.0, 6.0, 9.0) - - or on the right - >>> a * 3.0 - Vec(3.0, 6.0, 9.0) - """ - def __init__(self, *v): - self.v = list(v) - - @classmethod - def fromlist(cls, v): - if not isinstance(v, list): - raise TypeError - inst = cls() - inst.v = v - return inst - - def __repr__(self): - args = ', '.join(repr(x) for x in self.v) - return 'Vec({})'.format(args) - - def __len__(self): - return len(self.v) - - def __getitem__(self, i): - return self.v[i] - - def __add__(self, other): - # Element-wise addition - v = [x + y for x, y in zip(self.v, other.v)] - return Vec.fromlist(v) - - def __sub__(self, other): - # Element-wise subtraction - v = [x - y for x, y in zip(self.v, other.v)] - return Vec.fromlist(v) - - def __mul__(self, scalar): - # Multiply by scalar - v = [x * scalar for x in self.v] - return Vec.fromlist(v) - - __rmul__ = __mul__ - - -def test(): - import doctest - doctest.testmod() - -test() diff --git a/Demo/classes/bitvec.py b/Demo/classes/bitvec.py deleted file mode 100644 index 62b26cc..0000000 --- a/Demo/classes/bitvec.py +++ /dev/null @@ -1,322 +0,0 @@ -# -# this is a rather strict implementation of a bit vector class -# it is accessed the same way as an array of python-ints, except -# the value must be 0 or 1 -# - -import sys; rprt = sys.stderr.write #for debugging - -class error(Exception): - pass - - -def _check_value(value): - if type(value) != type(0) or not 0 <= value < 2: - raise error('bitvec() items must have int value 0 or 1') - - -import math - -def _compute_len(param): - mant, l = math.frexp(float(param)) - bitmask = 1 << l - if bitmask <= param: - raise ValueError('(param, l) = %r' % ((param, l),)) - while l: - bitmask = bitmask >> 1 - if param & bitmask: - break - l = l - 1 - return l - - -def _check_key(len, key): - if type(key) != type(0): - raise TypeError('sequence subscript not int') - if key < 0: - key = key + len - if not 0 <= key < len: - raise IndexError('list index out of range') - return key - -def _check_slice(len, i, j): - #the type is ok, Python already checked that - i, j = max(i, 0), min(len, j) - if i > j: - i = j - return i, j - - -class BitVec: - - def __init__(self, *params): - self._data = 0 - self._len = 0 - if not len(params): - pass - elif len(params) == 1: - param, = params - if type(param) == type([]): - value = 0 - bit_mask = 1 - for item in param: - # strict check - #_check_value(item) - if item: - value = value | bit_mask - bit_mask = bit_mask << 1 - self._data = value - self._len = len(param) - elif type(param) == type(0): - if param < 0: - raise error('bitvec() can\'t handle negative longs') - self._data = param - self._len = _compute_len(param) - else: - raise error('bitvec() requires array or long parameter') - elif len(params) == 2: - param, length = params - if type(param) == type(0): - if param < 0: - raise error('can\'t handle negative longs') - self._data = param - if type(length) != type(0): - raise error('bitvec()\'s 2nd parameter must be int') - computed_length = _compute_len(param) - if computed_length > length: - print('warning: bitvec() value is longer than the length indicates, truncating value') - self._data = self._data & \ - ((1 << length) - 1) - self._len = length - else: - raise error('bitvec() requires array or long parameter') - else: - raise error('bitvec() requires 0 -- 2 parameter(s)') - - - def append(self, item): - #_check_value(item) - #self[self._len:self._len] = [item] - self[self._len:self._len] = \ - BitVec(int(not not item), 1) - - - def count(self, value): - #_check_value(value) - if value: - data = self._data - else: - data = (~self)._data - count = 0 - while data: - data, count = data >> 1, count + (data & 1 != 0) - return count - - - def index(self, value): - #_check_value(value): - if value: - data = self._data - else: - data = (~self)._data - index = 0 - if not data: - raise ValueError('list.index(x): x not in list') - while not (data & 1): - data, index = data >> 1, index + 1 - return index - - - def insert(self, index, item): - #_check_value(item) - #self[index:index] = [item] - self[index:index] = BitVec(int(not not item), 1) - - - def remove(self, value): - del self[self.index(value)] - - - def reverse(self): - #ouch, this one is expensive! - #for i in self._len>>1: self[i], self[l-i] = self[l-i], self[i] - data, result = self._data, 0 - for i in range(self._len): - if not data: - result = result << (self._len - i) - break - result, data = (result << 1) | (data & 1), data >> 1 - self._data = result - - - def sort(self): - c = self.count(1) - self._data = ((1 << c) - 1) << (self._len - c) - - - def copy(self): - return BitVec(self._data, self._len) - - - def seq(self): - result = [] - for i in self: - result.append(i) - return result - - - def __repr__(self): - ##rprt('.' + '__repr__()\n') - return 'bitvec(%r, %r)' % (self._data, self._len) - - def __cmp__(self, other, *rest): - #rprt('%r.__cmp__%r\n' % (self, (other,) + rest)) - if type(other) != type(self): - other = bitvec(other, *rest) - #expensive solution... recursive binary, with slicing - length = self._len - if length == 0 or other._len == 0: - return cmp(length, other._len) - if length != other._len: - min_length = min(length, other._len) - return cmp(self[:min_length], other[:min_length]) or \ - cmp(self[min_length:], other[min_length:]) - #the lengths are the same now... - if self._data == other._data: - return 0 - if length == 1: - return cmp(self[0], other[0]) - else: - length = length >> 1 - return cmp(self[:length], other[:length]) or \ - cmp(self[length:], other[length:]) - - - def __len__(self): - #rprt('%r.__len__()\n' % (self,)) - return self._len - - def __getitem__(self, key): - #rprt('%r.__getitem__(%r)\n' % (self, key)) - key = _check_key(self._len, key) - return self._data & (1 << key) != 0 - - def __setitem__(self, key, value): - #rprt('%r.__setitem__(%r, %r)\n' % (self, key, value)) - key = _check_key(self._len, key) - #_check_value(value) - if value: - self._data = self._data | (1 << key) - else: - self._data = self._data & ~(1 << key) - - def __delitem__(self, key): - #rprt('%r.__delitem__(%r)\n' % (self, key)) - key = _check_key(self._len, key) - #el cheapo solution... - self._data = self[:key]._data | self[key+1:]._data >> key - self._len = self._len - 1 - - def __getslice__(self, i, j): - #rprt('%r.__getslice__(%r, %r)\n' % (self, i, j)) - i, j = _check_slice(self._len, i, j) - if i >= j: - return BitVec(0, 0) - if i: - ndata = self._data >> i - else: - ndata = self._data - nlength = j - i - if j != self._len: - #we'll have to invent faster variants here - #e.g. mod_2exp - ndata = ndata & ((1 << nlength) - 1) - return BitVec(ndata, nlength) - - def __setslice__(self, i, j, sequence, *rest): - #rprt('%s.__setslice__%r\n' % (self, (i, j, sequence) + rest)) - i, j = _check_slice(self._len, i, j) - if type(sequence) != type(self): - sequence = bitvec(sequence, *rest) - #sequence is now of our own type - ls_part = self[:i] - ms_part = self[j:] - self._data = ls_part._data | \ - ((sequence._data | \ - (ms_part._data << sequence._len)) << ls_part._len) - self._len = self._len - j + i + sequence._len - - def __delslice__(self, i, j): - #rprt('%r.__delslice__(%r, %r)\n' % (self, i, j)) - i, j = _check_slice(self._len, i, j) - if i == 0 and j == self._len: - self._data, self._len = 0, 0 - elif i < j: - self._data = self[:i]._data | (self[j:]._data >> i) - self._len = self._len - j + i - - def __add__(self, other): - #rprt('%r.__add__(%r)\n' % (self, other)) - retval = self.copy() - retval[self._len:self._len] = other - return retval - - def __mul__(self, multiplier): - #rprt('%r.__mul__(%r)\n' % (self, multiplier)) - if type(multiplier) != type(0): - raise TypeError('sequence subscript not int') - if multiplier <= 0: - return BitVec(0, 0) - elif multiplier == 1: - return self.copy() - #handle special cases all 0 or all 1... - if self._data == 0: - return BitVec(0, self._len * multiplier) - elif (~self)._data == 0: - return ~BitVec(0, self._len * multiplier) - #otherwise el cheapo again... - retval = BitVec(0, 0) - while multiplier: - retval, multiplier = retval + self, multiplier - 1 - return retval - - def __and__(self, otherseq, *rest): - #rprt('%r.__and__%r\n' % (self, (otherseq,) + rest)) - if type(otherseq) != type(self): - otherseq = bitvec(otherseq, *rest) - #sequence is now of our own type - return BitVec(self._data & otherseq._data, \ - min(self._len, otherseq._len)) - - - def __xor__(self, otherseq, *rest): - #rprt('%r.__xor__%r\n' % (self, (otherseq,) + rest)) - if type(otherseq) != type(self): - otherseq = bitvec(otherseq, *rest) - #sequence is now of our own type - return BitVec(self._data ^ otherseq._data, \ - max(self._len, otherseq._len)) - - - def __or__(self, otherseq, *rest): - #rprt('%r.__or__%r\n' % (self, (otherseq,) + rest)) - if type(otherseq) != type(self): - otherseq = bitvec(otherseq, *rest) - #sequence is now of our own type - return BitVec(self._data | otherseq._data, \ - max(self._len, otherseq._len)) - - - def __invert__(self): - #rprt('%r.__invert__()\n' % (self,)) - return BitVec(~self._data & ((1 << self._len) - 1), \ - self._len) - - def __int__(self): - return int(self._data) - - def __float__(self): - return float(self._data) - - -bitvec = BitVec diff --git a/Demo/curses/README b/Demo/curses/README deleted file mode 100644 index 2d1c4b1..0000000 --- a/Demo/curses/README +++ /dev/null @@ -1,25 +0,0 @@ -This is a collection of demos and tests for the curses module. - -ncurses demos -============= - -These demos are converted from the C versions in the ncurses -distribution, and were contributed by Thomas Gellekum -I didn't strive for a `pythonic' style, but bluntly copied the -originals. I won't attempt to `beautify' the program anytime soon, but -I wouldn't mind someone else making an effort in that direction, of -course. - -ncurses.py -- currently only a panels demo -rain.py -- raindrops keep falling on my desktop -tclock.py -- ASCII clock, by Howard Jones -xmas.py -- I'm dreaming of an ASCII christmas - -Please submit bugfixes and new contributions to the Python bug tracker. - - -Other demos -=========== - -life.py -- Simple game of Life -repeat.py -- Repeatedly execute a shell command (like watch(1)) diff --git a/Demo/curses/life.py b/Demo/curses/life.py deleted file mode 100755 index 3cbc053..0000000 --- a/Demo/curses/life.py +++ /dev/null @@ -1,250 +0,0 @@ -#!/usr/bin/env python3 -# life.py -- A curses-based version of Conway's Game of Life. -# Contributed by AMK -# Mouse support and color by Dafydd Crosby -# -# An empty board will be displayed, and the following commands are available: -# E : Erase the board -# R : Fill the board randomly -# S : Step for a single generation -# C : Update continuously until a key is struck -# Q : Quit -# Cursor keys : Move the cursor around the board -# Space or Enter : Toggle the contents of the cursor's position -# -# TODO : -# Make board updates faster -# - -import random, string, traceback -import curses - -class LifeBoard: - """Encapsulates a Life board - - Attributes: - X,Y : horizontal and vertical size of the board - state : dictionary mapping (x,y) to 0 or 1 - - Methods: - display(update_board) -- If update_board is true, compute the - next generation. Then display the state - of the board and refresh the screen. - erase() -- clear the entire board - makeRandom() -- fill the board randomly - set(y,x) -- set the given cell to Live; doesn't refresh the screen - toggle(y,x) -- change the given cell from live to dead, or vice - versa, and refresh the screen display - - """ - def __init__(self, scr, char=ord('*')): - """Create a new LifeBoard instance. - - scr -- curses screen object to use for display - char -- character used to render live cells (default: '*') - """ - self.state = {} - self.scr = scr - Y, X = self.scr.getmaxyx() - self.X, self.Y = X-2, Y-2-1 - self.char = char - self.scr.clear() - - # Draw a border around the board - border_line = '+'+(self.X*'-')+'+' - self.scr.addstr(0, 0, border_line) - self.scr.addstr(self.Y+1,0, border_line) - for y in range(0, self.Y): - self.scr.addstr(1+y, 0, '|') - self.scr.addstr(1+y, self.X+1, '|') - self.scr.refresh() - - def set(self, y, x): - """Set a cell to the live state""" - if x<0 or self.X<=x or y<0 or self.Y<=y: - raise ValueError("Coordinates out of range %i,%i"% (y,x)) - self.state[x,y] = 1 - - def toggle(self, y, x): - """Toggle a cell's state between live and dead""" - if x<0 or self.X<=x or y<0 or self.Y<=y: - raise ValueError("Coordinates out of range %i,%i"% (y,x)) - if (x,y) in self.state: - del self.state[x,y] - self.scr.addch(y+1, x+1, ' ') - else: - self.state[x,y] = 1 - if curses.has_colors(): - #Let's pick a random color! - self.scr.attrset(curses.color_pair(random.randrange(1,7))) - self.scr.addch(y+1, x+1, self.char) - self.scr.attrset(0) - self.scr.refresh() - - def erase(self): - """Clear the entire board and update the board display""" - self.state = {} - self.display(update_board=False) - - def display(self, update_board=True): - """Display the whole board, optionally computing one generation""" - M,N = self.X, self.Y - if not update_board: - for i in range(0, M): - for j in range(0, N): - if (i,j) in self.state: - self.scr.addch(j+1, i+1, self.char) - else: - self.scr.addch(j+1, i+1, ' ') - self.scr.refresh() - return - - d = {} - self.boring = 1 - for i in range(0, M): - L = range( max(0, i-1), min(M, i+2) ) - for j in range(0, N): - s = 0 - live = (i,j) in self.state - for k in range( max(0, j-1), min(N, j+2) ): - for l in L: - if (l,k) in self.state: - s += 1 - s -= live - if s == 3: - # Birth - d[i,j] = 1 - if curses.has_colors(): - #Let's pick a random color! - self.scr.attrset(curses.color_pair(random.randrange(1,7))) - self.scr.addch(j+1, i+1, self.char) - self.scr.attrset(0) - if not live: self.boring = 0 - elif s == 2 and live: d[i,j] = 1 # Survival - elif live: - # Death - self.scr.addch(j+1, i+1, ' ') - self.boring = 0 - self.state = d - self.scr.refresh() - - def makeRandom(self): - "Fill the board with a random pattern" - self.state = {} - for i in range(0, self.X): - for j in range(0, self.Y): - if random.random() > 0.5: - self.set(j,i) - - -def erase_menu(stdscr, menu_y): - "Clear the space where the menu resides" - stdscr.move(menu_y, 0) - stdscr.clrtoeol() - stdscr.move(menu_y+1, 0) - stdscr.clrtoeol() - -def display_menu(stdscr, menu_y): - "Display the menu of possible keystroke commands" - erase_menu(stdscr, menu_y) - - # If color, then light the menu up :-) - if curses.has_colors(): - stdscr.attrset(curses.color_pair(1)) - stdscr.addstr(menu_y, 4, - 'Use the cursor keys to move, and space or Enter to toggle a cell.') - stdscr.addstr(menu_y+1, 4, - 'E)rase the board, R)andom fill, S)tep once or C)ontinuously, Q)uit') - stdscr.attrset(0) - -def keyloop(stdscr): - # Clear the screen and display the menu of keys - stdscr.clear() - stdscr_y, stdscr_x = stdscr.getmaxyx() - menu_y = (stdscr_y-3)-1 - display_menu(stdscr, menu_y) - - # If color, then initialize the color pairs - if curses.has_colors(): - curses.init_pair(1, curses.COLOR_BLUE, 0) - curses.init_pair(2, curses.COLOR_CYAN, 0) - curses.init_pair(3, curses.COLOR_GREEN, 0) - curses.init_pair(4, curses.COLOR_MAGENTA, 0) - curses.init_pair(5, curses.COLOR_RED, 0) - curses.init_pair(6, curses.COLOR_YELLOW, 0) - curses.init_pair(7, curses.COLOR_WHITE, 0) - - # Set up the mask to listen for mouse events - curses.mousemask(curses.BUTTON1_CLICKED) - - # Allocate a subwindow for the Life board and create the board object - subwin = stdscr.subwin(stdscr_y-3, stdscr_x, 0, 0) - board = LifeBoard(subwin, char=ord('*')) - board.display(update_board=False) - - # xpos, ypos are the cursor's position - xpos, ypos = board.X//2, board.Y//2 - - # Main loop: - while (1): - stdscr.move(1+ypos, 1+xpos) # Move the cursor - c = stdscr.getch() # Get a keystroke - if 00: ypos -= 1 - elif c == curses.KEY_DOWN and ypos0: xpos -= 1 - elif c == curses.KEY_RIGHT and xpos0 and mouse_x0 and mouse_y - -This simple program repeatedly (at 1-second intervals) executes the -shell command given on the command line and displays the output (or as -much of it as fits on the screen). It uses curses to paint each new -output on top of the old output, so that if nothing changes, the -screen doesn't change. This is handy to watch for changes in e.g. a -directory or process listing. - -The -i option lets you override the sleep time between executions. - -To end, hit Control-C. -""" - -# Author: Guido van Rossum - -# Disclaimer: there's a Linux program named 'watch' that does the same -# thing. Honestly, I didn't know of its existence when I wrote this! - -# To do: add features until it has the same functionality as watch(1); -# then compare code size and development time. - -import os -import sys -import time -import curses -import getopt - -def main(): - interval = 1.0 - try: - opts, args = getopt.getopt(sys.argv[1:], "hi:") - except getopt.error as err: - print(err, file=sys.stderr) - sys.exit(2) - if not args: - print(__doc__) - sys.exit(0) - for opt, arg in opts: - if opt == "-i": - interval = float(arg) - if opt == "-h": - print(__doc__) - sys.exit(0) - cmd = " ".join(args) - cmd_really = cmd + " 2>&1" - p = os.popen(cmd_really, "r") - text = p.read() - sts = p.close() - text = addsts(interval, cmd, text, sts) - w = curses.initscr() - try: - while True: - w.erase() - try: - w.addstr(text) - except curses.error: - pass - w.refresh() - time.sleep(interval) - p = os.popen(cmd_really, "r") - text = p.read() - sts = p.close() - text = addsts(interval, cmd, text, sts) - finally: - curses.endwin() - -def addsts(interval, cmd, text, sts): - now = time.strftime("%H:%M:%S") - text = "%s, every %g sec: %s\n%s" % (now, interval, cmd, text) - if sts: - msg = "Exit status: %d; signal: %d" % (sts>>8, sts&0xFF) - if text and not text.endswith("\n"): - msg = "\n" + msg - text += msg - return text - -main() diff --git a/Demo/distutils/test2to3/README b/Demo/distutils/test2to3/README deleted file mode 100644 index 9365593..0000000 --- a/Demo/distutils/test2to3/README +++ /dev/null @@ -1,3 +0,0 @@ -This project demonstrates how a distutils package -can support Python 2.x and Python 3.x from a single -source, using lib2to3. \ No newline at end of file diff --git a/Demo/distutils/test2to3/maintest.py b/Demo/distutils/test2to3/maintest.py deleted file mode 100644 index 036dd4f..0000000 --- a/Demo/distutils/test2to3/maintest.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env python3 - -# The above line should get replaced with the path to the Python -# interpreter; the block below should get 2to3-converted. - -try: - from test2to3.hello import hello -except ImportError, e: - print "Import failed", e -hello() diff --git a/Demo/distutils/test2to3/setup.py b/Demo/distutils/test2to3/setup.py deleted file mode 100644 index a0f9024..0000000 --- a/Demo/distutils/test2to3/setup.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: iso-8859-1 -*- -from distutils.core import setup - -try: - from distutils.command.build_py import build_py_2to3 as build_py -except ImportError: - from distutils.command.build_py import build_py - -try: - from distutils.command.build_scripts import build_scripts_2to3 as build_scripts -except ImportError: - from distutils.command.build_scripts import build_scripts - -setup( - name = "test2to3", - version = "1.0", - description = "2to3 distutils test package", - author = "Martin v. Löwis", - author_email = "python-dev@python.org", - license = "PSF license", - packages = ["test2to3"], - scripts = ["maintest.py"], - cmdclass = {'build_py': build_py, - 'build_scripts': build_scripts, - } -) diff --git a/Demo/distutils/test2to3/test/runtests.py b/Demo/distutils/test2to3/test/runtests.py deleted file mode 100644 index 1730f0d..0000000 --- a/Demo/distutils/test2to3/test/runtests.py +++ /dev/null @@ -1,19 +0,0 @@ -# Fictitious test runner for the project - -import sys, os - -if sys.version_info > (3,): - # copy test suite over to "build/lib" and convert it - from distutils.util import copydir_run_2to3 - testroot = os.path.dirname(__file__) - newroot = os.path.join(testroot, '..', 'build/lib/test') - copydir_run_2to3(testroot, newroot) - # in the following imports, pick up the converted modules - sys.path[0] = newroot - -# run the tests here... - -from test_foo import FooTest - -import unittest -unittest.main() diff --git a/Demo/distutils/test2to3/test/test_foo.py b/Demo/distutils/test2to3/test/test_foo.py deleted file mode 100644 index ec8f26a..0000000 --- a/Demo/distutils/test2to3/test/test_foo.py +++ /dev/null @@ -1,8 +0,0 @@ -import sys -import unittest - -class FooTest(unittest.TestCase): - def test_foo(self): - # use 2.6 syntax to demonstrate conversion - print 'In test_foo, using Python %s...' % (sys.version_info,) - self.assertTrue(False) diff --git a/Demo/distutils/test2to3/test2to3/__init__.py b/Demo/distutils/test2to3/test2to3/__init__.py deleted file mode 100644 index 1bb8bf6..0000000 --- a/Demo/distutils/test2to3/test2to3/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# empty diff --git a/Demo/distutils/test2to3/test2to3/hello.py b/Demo/distutils/test2to3/test2to3/hello.py deleted file mode 100644 index f52926b..0000000 --- a/Demo/distutils/test2to3/test2to3/hello.py +++ /dev/null @@ -1,5 +0,0 @@ -def hello(): - try: - print "Hello, world" - except IOError, e: - print e.errno diff --git a/Demo/embed/Makefile b/Demo/embed/Makefile deleted file mode 100644 index b02772f..0000000 --- a/Demo/embed/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# Makefile for embedded Python use demo. -# (This version originally written on Red Hat Linux 6.1; -# edit lines marked with XXX.) - -# XXX The compiler you are using -CC= gcc - -# XXX Top of the build tree and source tree -blddir= ../.. -srcdir= ../.. - -# Python version -VERSION= 3.2 - -# Compiler flags -OPT= -g -INCLUDES= -I$(srcdir)/Include -I$(blddir) -CFLAGS= $(OPT) -CPPFLAGS= $(INCLUDES) - -# The Python library -LIBPYTHON= $(blddir)/libpython$(VERSION).a - -# XXX edit LIBS (in particular) to match $(blddir)/Makefile -LIBS= -lnsl -ldl -lreadline -lieee -lpthread -lutil -LDFLAGS= -Xlinker -export-dynamic -SYSLIBS= -lm -MODLIBS= -ALLLIBS= $(LIBPYTHON) $(MODLIBS) $(LIBS) $(SYSLIBS) - -# Build the demo applications -all: demo loop importexc -demo: demo.o - $(CC) $(LDFLAGS) demo.o $(ALLLIBS) -o demo - -loop: loop.o - $(CC) $(LDFLAGS) loop.o $(ALLLIBS) -o loop - -importexc: importexc.o - $(CC) $(LDFLAGS) importexc.o $(ALLLIBS) -o importexc - -# Administrative targets - -test: demo - ./demo - -COMMAND="print 'hello world'" -looptest: loop - ./loop $(COMMAND) - -clean: - -rm -f *.o core - -clobber: clean - -rm -f *~ @* '#'* demo loop importexc - -realclean: clobber diff --git a/Demo/embed/README b/Demo/embed/README deleted file mode 100644 index a0f7af8..0000000 --- a/Demo/embed/README +++ /dev/null @@ -1,19 +0,0 @@ -This directory show how to embed the Python interpreter in your own -application. The file demo.c shows you all that is needed in your C -code. - -To build it, you may have to edit the Makefile: - -1) set blddir to the directory where you built Python, if it isn't in -the source directory (../..) - -2) change the variables that together define the list of libraries -(MODLIBS, LIBS, SYSLIBS) to link with, to match their definitions in -$(blddir)/Modules/Makefile - -An additional test program, loop.c, is used to experiment with memory -leakage caused by repeated initialization and finalization of the -interpreter. It can be build by saying "make loop" and tested with -"make looptest". Command line usage is "./loop ", -e.g. "./loop 'print 2+2'" should spit out an endless number of lines -containing the number 4. diff --git a/Demo/embed/demo.c b/Demo/embed/demo.c deleted file mode 100644 index 8d92820..0000000 --- a/Demo/embed/demo.c +++ /dev/null @@ -1,89 +0,0 @@ -/* Example of embedding Python in another program */ - -#include "Python.h" - -PyObject* PyInit_xyzzy(void); /* Forward */ - -main(int argc, char **argv) -{ - /* Ignore passed-in argc/argv. If desired, conversion - should use mbstowcs to convert them. */ - wchar_t *args[] = {L"embed", L"hello", 0}; - - /* Pass argv[0] to the Python interpreter */ - Py_SetProgramName(args[0]); - - /* Add a static module */ - PyImport_AppendInittab("xyzzy", PyInit_xyzzy); - - /* Initialize the Python interpreter. Required. */ - Py_Initialize(); - - /* Define sys.argv. It is up to the application if you - want this; you can also leave it undefined (since the Python - code is generally not a main program it has no business - touching sys.argv...) - - If the third argument is true, sys.path is modified to include - either the directory containing the script named by argv[0], or - the current working directory. This can be risky; if you run - an application embedding Python in a directory controlled by - someone else, attackers could put a Trojan-horse module in the - directory (say, a file named os.py) that your application would - then import and run. - */ - PySys_SetArgvEx(2, args, 0); - - /* Do some application specific code */ - printf("Hello, brave new world\n\n"); - - /* Execute some Python statements (in module __main__) */ - PyRun_SimpleString("import sys\n"); - PyRun_SimpleString("print(sys.builtin_module_names)\n"); - PyRun_SimpleString("print(sys.modules.keys())\n"); - PyRun_SimpleString("print(sys.executable)\n"); - PyRun_SimpleString("print(sys.argv)\n"); - - /* Note that you can call any public function of the Python - interpreter here, e.g. call_object(). */ - - /* Some more application specific code */ - printf("\nGoodbye, cruel world\n"); - - /* Exit, cleaning up the interpreter */ - Py_Exit(0); - /*NOTREACHED*/ -} - -/* A static module */ - -/* 'self' is not used */ -static PyObject * -xyzzy_foo(PyObject *self, PyObject* args) -{ - return PyLong_FromLong(42L); -} - -static PyMethodDef xyzzy_methods[] = { - {"foo", xyzzy_foo, METH_NOARGS, - "Return the meaning of everything."}, - {NULL, NULL} /* sentinel */ -}; - -static struct PyModuleDef xyzzymodule = { - {}, /* m_base */ - "xyzzy", /* m_name */ - 0, /* m_doc */ - 0, /* m_size */ - xyzzy_methods, /* m_methods */ - 0, /* m_reload */ - 0, /* m_traverse */ - 0, /* m_clear */ - 0, /* m_free */ -}; - -PyObject* -PyInit_xyzzy(void) -{ - return PyModule_Create(&xyzzymodule); -} diff --git a/Demo/embed/importexc.c b/Demo/embed/importexc.c deleted file mode 100644 index 59b1d01..0000000 --- a/Demo/embed/importexc.c +++ /dev/null @@ -1,23 +0,0 @@ -#include - -#if 0 -char* cmd = "import codecs, encodings.utf_8, types; print(types)"; -#else -char* cmd = "import types; print(types)"; -#endif - -int main() -{ - printf("Initialize interpreter\n"); - Py_Initialize(); - PyEval_InitThreads(); - PyRun_SimpleString(cmd); - Py_EndInterpreter(PyThreadState_Get()); - - printf("\nInitialize subinterpreter\n"); - Py_NewInterpreter(); - PyRun_SimpleString(cmd); - Py_Finalize(); - - return 0; -} diff --git a/Demo/embed/loop.c b/Demo/embed/loop.c deleted file mode 100644 index 4a341fd..0000000 --- a/Demo/embed/loop.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Simple program that repeatedly calls Py_Initialize(), does something, and - then calls Py_Finalize(). This should help finding leaks related to - initialization. */ - -#include "Python.h" - -main(int argc, char **argv) -{ - int count = -1; - char *command; - - if (argc < 2 || argc > 3) { - fprintf(stderr, "usage: loop [count]\n"); - exit(2); - } - command = argv[1]; - - if (argc == 3) { - count = atoi(argv[2]); - } - - Py_SetProgramName(L"loop"); - - /* uncomment this if you don't want to load site.py */ - /* Py_NoSiteFlag = 1; */ - - while (count == -1 || --count >= 0 ) { - Py_Initialize(); - PyRun_SimpleString(command); - Py_Finalize(); - } - return 0; -} diff --git a/Demo/newmetaclasses/Eiffel.py b/Demo/newmetaclasses/Eiffel.py deleted file mode 100644 index 15fa58a..0000000 --- a/Demo/newmetaclasses/Eiffel.py +++ /dev/null @@ -1,141 +0,0 @@ -"""Support Eiffel-style preconditions and postconditions.""" - -from types import FunctionType as function - -class EiffelBaseMetaClass(type): - - def __new__(meta, name, bases, dict): - meta.convert_methods(dict) - return super(EiffelBaseMetaClass, meta).__new__(meta, name, bases, - dict) - - @classmethod - def convert_methods(cls, dict): - """Replace functions in dict with EiffelMethod wrappers. - - The dict is modified in place. - - If a method ends in _pre or _post, it is removed from the dict - regardless of whether there is a corresponding method. - """ - # find methods with pre or post conditions - methods = [] - for k, v in dict.items(): - if k.endswith('_pre') or k.endswith('_post'): - assert isinstance(v, function) - elif isinstance(v, function): - methods.append(k) - for m in methods: - pre = dict.get("%s_pre" % m) - post = dict.get("%s_post" % m) - if pre or post: - dict[k] = cls.make_eiffel_method(dict[m], pre, post) - -class EiffelMetaClass1(EiffelBaseMetaClass): - # an implementation of the "eiffel" meta class that uses nested functions - - @staticmethod - def make_eiffel_method(func, pre, post): - def method(self, *args, **kwargs): - if pre: - pre(self, *args, **kwargs) - x = func(self, *args, **kwargs) - if post: - post(self, x, *args, **kwargs) - return x - - if func.__doc__: - method.__doc__ = func.__doc__ - - return method - -class EiffelMethodWrapper: - - def __init__(self, inst, descr): - self._inst = inst - self._descr = descr - - def __call__(self, *args, **kwargs): - return self._descr.callmethod(self._inst, args, kwargs) - -class EiffelDescriptor(object): - - def __init__(self, func, pre, post): - self._func = func - self._pre = pre - self._post = post - - self.__name__ = func.__name__ - self.__doc__ = func.__doc__ - - def __get__(self, obj, cls): - return EiffelMethodWrapper(obj, self) - - def callmethod(self, inst, args, kwargs): - if self._pre: - self._pre(inst, *args, **kwargs) - x = self._func(inst, *args, **kwargs) - if self._post: - self._post(inst, x, *args, **kwargs) - return x - -class EiffelMetaClass2(EiffelBaseMetaClass): - # an implementation of the "eiffel" meta class that uses descriptors - - make_eiffel_method = EiffelDescriptor - -def _test(metaclass): - class Eiffel(metaclass=metaclass): - pass - - class Test(Eiffel): - - def m(self, arg): - """Make it a little larger""" - return arg + 1 - - def m2(self, arg): - """Make it a little larger""" - return arg + 1 - - def m2_pre(self, arg): - assert arg > 0 - - def m2_post(self, result, arg): - assert result > arg - - class Sub(Test): - def m2(self, arg): - return arg**2 - def m2_post(self, Result, arg): - super(Sub, self).m2_post(Result, arg) - assert Result < 100 - - t = Test() - t.m(1) - t.m2(1) - try: - t.m2(0) - except AssertionError: - pass - else: - assert False - - s = Sub() - try: - s.m2(1) - except AssertionError: - pass # result == arg - else: - assert False - try: - s.m2(10) - except AssertionError: - pass # result == 100 - else: - assert False - s.m2(5) - -if __name__ == "__main__": - _test(EiffelMetaClass1) - _test(EiffelMetaClass2) diff --git a/Demo/newmetaclasses/Enum.py b/Demo/newmetaclasses/Enum.py deleted file mode 100644 index 3ff8ddd..0000000 --- a/Demo/newmetaclasses/Enum.py +++ /dev/null @@ -1,177 +0,0 @@ -"""Enumeration metaclass.""" - -class EnumMetaclass(type): - """Metaclass for enumeration. - - To define your own enumeration, do something like - - class Color(Enum): - red = 1 - green = 2 - blue = 3 - - Now, Color.red, Color.green and Color.blue behave totally - different: they are enumerated values, not integers. - - Enumerations cannot be instantiated; however they can be - subclassed. - """ - - def __init__(cls, name, bases, dict): - super(EnumMetaclass, cls).__init__(name, bases, dict) - cls._members = [] - for attr in dict.keys(): - if not (attr.startswith('__') and attr.endswith('__')): - enumval = EnumInstance(name, attr, dict[attr]) - setattr(cls, attr, enumval) - cls._members.append(attr) - - def __getattr__(cls, name): - if name == "__members__": - return cls._members - raise AttributeError(name) - - def __repr__(cls): - s1 = s2 = "" - enumbases = [base.__name__ for base in cls.__bases__ - if isinstance(base, EnumMetaclass) and not base is Enum] - if enumbases: - s1 = "(%s)" % ", ".join(enumbases) - enumvalues = ["%s: %d" % (val, getattr(cls, val)) - for val in cls._members] - if enumvalues: - s2 = ": {%s}" % ", ".join(enumvalues) - return "%s%s%s" % (cls.__name__, s1, s2) - -class FullEnumMetaclass(EnumMetaclass): - """Metaclass for full enumerations. - - A full enumeration displays all the values defined in base classes. - """ - - def __init__(cls, name, bases, dict): - super(FullEnumMetaclass, cls).__init__(name, bases, dict) - for obj in cls.__mro__: - if isinstance(obj, EnumMetaclass): - for attr in obj._members: - # XXX inefficient - if not attr in cls._members: - cls._members.append(attr) - -class EnumInstance(int): - """Class to represent an enumeration value. - - EnumInstance('Color', 'red', 12) prints as 'Color.red' and behaves - like the integer 12 when compared, but doesn't support arithmetic. - - XXX Should it record the actual enumeration rather than just its - name? - """ - - def __new__(cls, classname, enumname, value): - return int.__new__(cls, value) - - def __init__(self, classname, enumname, value): - self.__classname = classname - self.__enumname = enumname - - def __repr__(self): - return "EnumInstance(%s, %s, %d)" % (self.__classname, self.__enumname, - self) - - def __str__(self): - return "%s.%s" % (self.__classname, self.__enumname) - -class Enum(metaclass=EnumMetaclass): - pass - -class FullEnum(metaclass=FullEnumMetaclass): - pass - -def _test(): - - class Color(Enum): - red = 1 - green = 2 - blue = 3 - - print(Color.red) - - print(repr(Color.red)) - print(Color.red == Color.red) - print(Color.red == Color.blue) - print(Color.red == 1) - print(Color.red == 2) - - class ExtendedColor(Color): - white = 0 - orange = 4 - yellow = 5 - purple = 6 - black = 7 - - print(ExtendedColor.orange) - print(ExtendedColor.red) - - print(Color.red == ExtendedColor.red) - - class OtherColor(Enum): - white = 4 - blue = 5 - - class MergedColor(Color, OtherColor): - pass - - print(MergedColor.red) - print(MergedColor.white) - - print(Color) - print(ExtendedColor) - print(OtherColor) - print(MergedColor) - -def _test2(): - - class Color(FullEnum): - red = 1 - green = 2 - blue = 3 - - print(Color.red) - - print(repr(Color.red)) - print(Color.red == Color.red) - print(Color.red == Color.blue) - print(Color.red == 1) - print(Color.red == 2) - - class ExtendedColor(Color): - white = 0 - orange = 4 - yellow = 5 - purple = 6 - black = 7 - - print(ExtendedColor.orange) - print(ExtendedColor.red) - - print(Color.red == ExtendedColor.red) - - class OtherColor(FullEnum): - white = 4 - blue = 5 - - class MergedColor(Color, OtherColor): - pass - - print(MergedColor.red) - print(MergedColor.white) - - print(Color) - print(ExtendedColor) - print(OtherColor) - print(MergedColor) - -if __name__ == '__main__': - _test() - _test2() diff --git a/Demo/scripts/README b/Demo/scripts/README deleted file mode 100644 index b80704c..0000000 --- a/Demo/scripts/README +++ /dev/null @@ -1,22 +0,0 @@ -This directory contains a collection of executable Python scripts. - -See also the Tools/scripts directory! - -beer.py Print the classic 'bottles of beer' list -eqfix.py Fix .py files to use the correct equality test operator -fact.py Factorize numbers -find-uname.py Search for Unicode characters using regexps -from.py Summarize mailbox -lpwatch.py Watch BSD line printer queues -makedir.py Like mkdir -p -markov.py Markov chain simulation of words or characters -mboxconvert.py Convert MH or MMDF mailboxes to unix mailbox format -morse.py Produce morse code (as an AIFF file) -newslist.py List all newsgroups on a NNTP server as HTML pages -pi.py Print all digits of pi -- given enough time and memory -pp.py Emulate some Perl command line options -primes.py Print prime numbers -queens.py Dijkstra's solution to Wirth's "N Queens problem" -script.py Equivalent to BSD script(1) -- by Steen Lumholt -unbirthday.py Print unbirthday count -update.py Update a bunch of files according to a script diff --git a/Demo/scripts/beer.py b/Demo/scripts/beer.py deleted file mode 100755 index 56eec7b..0000000 --- a/Demo/scripts/beer.py +++ /dev/null @@ -1,20 +0,0 @@ -#! /usr/bin/env python3 - -# By GvR, demystified after a version by Fredrik Lundh. - -import sys - -n = 100 -if sys.argv[1:]: - n = int(sys.argv[1]) - -def bottle(n): - if n == 0: return "no more bottles of beer" - if n == 1: return "one bottle of beer" - return str(n) + " bottles of beer" - -for i in range(n, 0, -1): - print(bottle(i), "on the wall,") - print(bottle(i) + ".") - print("Take one down, pass it around,") - print(bottle(i-1), "on the wall.") diff --git a/Demo/scripts/fact.py b/Demo/scripts/fact.py deleted file mode 100755 index 2a3bef2..0000000 --- a/Demo/scripts/fact.py +++ /dev/null @@ -1,49 +0,0 @@ -#! /usr/bin/env python3 - -# Factorize numbers. -# The algorithm is not efficient, but easy to understand. -# If there are large factors, it will take forever to find them, -# because we try all odd numbers between 3 and sqrt(n)... - -import sys -from math import sqrt - -def fact(n): - if n < 1: - raise ValueError('fact() argument should be >= 1') - if n == 1: - return [] # special case - res = [] - # Treat even factors special, so we can use i += 2 later - while n % 2 == 0: - res.append(2) - n //= 2 - # Try odd numbers up to sqrt(n) - limit = sqrt(n+1) - i = 3 - while i <= limit: - if n % i == 0: - res.append(i) - n //= i - limit = sqrt(n+1) - else: - i += 2 - if n != 1: - res.append(n) - return res - -def main(): - if len(sys.argv) > 1: - source = sys.argv[1:] - else: - source = iter(input, '') - for arg in source: - try: - n = int(arg) - except ValueError: - print(arg, 'is not an integer') - else: - print(n, fact(n)) - -if __name__ == "__main__": - main() diff --git a/Demo/scripts/markov.py b/Demo/scripts/markov.py deleted file mode 100755 index 7c08bdb..0000000 --- a/Demo/scripts/markov.py +++ /dev/null @@ -1,121 +0,0 @@ -#! /usr/bin/env python3 - -class Markov: - def __init__(self, histsize, choice): - self.histsize = histsize - self.choice = choice - self.trans = {} - - def add(self, state, next): - self.trans.setdefault(state, []).append(next) - - def put(self, seq): - n = self.histsize - add = self.add - add(None, seq[:0]) - for i in range(len(seq)): - add(seq[max(0, i-n):i], seq[i:i+1]) - add(seq[len(seq)-n:], None) - - def get(self): - choice = self.choice - trans = self.trans - n = self.histsize - seq = choice(trans[None]) - while True: - subseq = seq[max(0, len(seq)-n):] - options = trans[subseq] - next = choice(options) - if not next: - break - seq += next - return seq - - -def test(): - import sys, random, getopt - args = sys.argv[1:] - try: - opts, args = getopt.getopt(args, '0123456789cdwq') - except getopt.error: - print('Usage: %s [-#] [-cddqw] [file] ...' % sys.argv[0]) - print('Options:') - print('-#: 1-digit history size (default 2)') - print('-c: characters (default)') - print('-w: words') - print('-d: more debugging output') - print('-q: no debugging output') - print('Input files (default stdin) are split in paragraphs') - print('separated blank lines and each paragraph is split') - print('in words by whitespace, then reconcatenated with') - print('exactly one space separating words.') - print('Output consists of paragraphs separated by blank') - print('lines, where lines are no longer than 72 characters.') - sys.exit(2) - histsize = 2 - do_words = False - debug = 1 - for o, a in opts: - if '-0' <= o <= '-9': histsize = int(o[1:]) - if o == '-c': do_words = False - if o == '-d': debug += 1 - if o == '-q': debug = 0 - if o == '-w': do_words = True - if not args: - args = ['-'] - - m = Markov(histsize, random.choice) - try: - for filename in args: - if filename == '-': - f = sys.stdin - if f.isatty(): - print('Sorry, need stdin from file') - continue - else: - f = open(filename, 'r') - if debug: print('processing', filename, '...') - text = f.read() - f.close() - paralist = text.split('\n\n') - for para in paralist: - if debug > 1: print('feeding ...') - words = para.split() - if words: - if do_words: - data = tuple(words) - else: - data = ' '.join(words) - m.put(data) - except KeyboardInterrupt: - print('Interrupted -- continue with data read so far') - if not m.trans: - print('No valid input files') - return - if debug: print('done.') - - if debug > 1: - for key in m.trans.keys(): - if key is None or len(key) < histsize: - print(repr(key), m.trans[key]) - if histsize == 0: print(repr(''), m.trans['']) - print() - while True: - data = m.get() - if do_words: - words = data - else: - words = data.split() - n = 0 - limit = 72 - for w in words: - if n + len(w) > limit: - print() - n = 0 - print(w, end=' ') - n += len(w) + 1 - print() - print() - -if __name__ == "__main__": - test() diff --git a/Demo/scripts/queens.py b/Demo/scripts/queens.py deleted file mode 100755 index ffd4bea..0000000 --- a/Demo/scripts/queens.py +++ /dev/null @@ -1,85 +0,0 @@ -#! /usr/bin/env python3 - -"""N queens problem. - -The (well-known) problem is due to Niklaus Wirth. - -This solution is inspired by Dijkstra (Structured Programming). It is -a classic recursive backtracking approach. - -""" - -N = 8 # Default; command line overrides - -class Queens: - - def __init__(self, n=N): - self.n = n - self.reset() - - def reset(self): - n = self.n - self.y = [None] * n # Where is the queen in column x - self.row = [0] * n # Is row[y] safe? - self.up = [0] * (2*n-1) # Is upward diagonal[x-y] safe? - self.down = [0] * (2*n-1) # Is downward diagonal[x+y] safe? - self.nfound = 0 # Instrumentation - - def solve(self, x=0): # Recursive solver - for y in range(self.n): - if self.safe(x, y): - self.place(x, y) - if x+1 == self.n: - self.display() - else: - self.solve(x+1) - self.remove(x, y) - - def safe(self, x, y): - return not self.row[y] and not self.up[x-y] and not self.down[x+y] - - def place(self, x, y): - self.y[x] = y - self.row[y] = 1 - self.up[x-y] = 1 - self.down[x+y] = 1 - - def remove(self, x, y): - self.y[x] = None - self.row[y] = 0 - self.up[x-y] = 0 - self.down[x+y] = 0 - - silent = 0 # If true, count solutions only - - def display(self): - self.nfound = self.nfound + 1 - if self.silent: - return - print('+-' + '--'*self.n + '+') - for y in range(self.n-1, -1, -1): - print('|', end=' ') - for x in range(self.n): - if self.y[x] == y: - print("Q", end=' ') - else: - print(".", end=' ') - print('|') - print('+-' + '--'*self.n + '+') - -def main(): - import sys - silent = 0 - n = N - if sys.argv[1:2] == ['-n']: - silent = 1 - del sys.argv[1] - if sys.argv[1:]: - n = int(sys.argv[1]) - q = Queens(n) - q.silent = silent - q.solve() - print("Found", q.nfound, "solutions.") - -if __name__ == "__main__": - main() diff --git a/Demo/scripts/unbirthday.py b/Demo/scripts/unbirthday.py deleted file mode 100755 index b3c7d23..0000000 --- a/Demo/scripts/unbirthday.py +++ /dev/null @@ -1,106 +0,0 @@ -#! /usr/bin/env python3 - -# Calculate your unbirthday count (see Alice in Wonderland). -# This is defined as the number of days from your birth until today -# that weren't your birthday. (The day you were born is not counted). -# Leap years make it interesting. - -import sys -import time -import calendar - -def main(): - if sys.argv[1:]: - year = int(sys.argv[1]) - else: - year = int(input('In which year were you born? ')) - if 0 <= year < 100: - print("I'll assume that by", year, end=' ') - year = year + 1900 - print('you mean', year, 'and not the early Christian era') - elif not (1850 <= year <= time.localtime()[0]): - print("It's hard to believe you were born in", year) - return - - if sys.argv[2:]: - month = int(sys.argv[2]) - else: - month = int(input('And in which month? (1-12) ')) - if not (1 <= month <= 12): - print('There is no month numbered', month) - return - - if sys.argv[3:]: - day = int(sys.argv[3]) - else: - day = int(input('And on what day of that month? (1-31) ')) - if month == 2 and calendar.isleap(year): - maxday = 29 - else: - maxday = calendar.mdays[month] - if not (1 <= day <= maxday): - print('There are no', day, 'days in that month!') - return - - bdaytuple = (year, month, day) - bdaydate = mkdate(bdaytuple) - print('You were born on', format(bdaytuple)) - - todaytuple = time.localtime()[:3] - todaydate = mkdate(todaytuple) - print('Today is', format(todaytuple)) - - if bdaytuple > todaytuple: - print('You are a time traveler. Go back to the future!') - return - - if bdaytuple == todaytuple: - print('You were born today. Have a nice life!') - return - - days = todaydate - bdaydate - print('You have lived', days, 'days') - - age = 0 - for y in range(year, todaytuple[0] + 1): - if bdaytuple < (y, month, day) <= todaytuple: - age = age + 1 - - print('You are', age, 'years old') - - if todaytuple[1:] == bdaytuple[1:]: - print('Congratulations! Today is your', nth(age), 'birthday') - print('Yesterday was your', end=' ') - else: - print('Today is your', end=' ') - print(nth(days - age), 'unbirthday') - -def format(date): - (year, month, day) = date - return '%d %s %d' % (day, calendar.month_name[month], year) - -def nth(n): - if n == 1: return '1st' - if n == 2: return '2nd' - if n == 3: return '3rd' - return '%dth' % n - -def mkdate(date): - # January 1st, in 0 A.D. is arbitrarily defined to be day 1, - # even though that day never actually existed and the calendar - # was different then... - (year, month, day) = date - days = year*365 # years, roughly - days = days + (year+3)//4 # plus leap years, roughly - days = days - (year+99)//100 # minus non-leap years every century - days = days + (year+399)//400 # plus leap years every 4 centirues - for i in range(1, month): - if i == 2 and calendar.isleap(year): - days = days + 29 - else: - days = days + calendar.mdays[i] - days = days + day - return days - -if __name__ == "__main__": - main() diff --git a/Demo/sockets/README b/Demo/sockets/README deleted file mode 100644 index eba7c23..0000000 --- a/Demo/sockets/README +++ /dev/null @@ -1,14 +0,0 @@ -This directory contains some demonstrations of the socket module: - -broadcast.py Broadcast the time to radio.py. -echosvr.py About the simplest TCP server possible. -finger.py Client for the 'finger' protocol. -ftp.py A very simple ftp client. -gopher.py A simple gopher client. -mcast.py IPv4/v6 multicast example -radio.py Receive time broadcasts from broadcast.py. -telnet.py Client for the 'telnet' protocol. -throughput.py Client and server to measure TCP throughput. -unixclient.py Unix socket example, client side -unixserver.py Unix socket example, server side -udpecho.py Client and server for the UDP echo protocol. diff --git a/Demo/sockets/broadcast.py b/Demo/sockets/broadcast.py deleted file mode 100644 index 6d2b1e8..0000000 --- a/Demo/sockets/broadcast.py +++ /dev/null @@ -1,15 +0,0 @@ -# Send UDP broadcast packets - -MYPORT = 50000 - -import sys, time -from socket import * - -s = socket(AF_INET, SOCK_DGRAM) -s.bind(('', 0)) -s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) - -while 1: - data = repr(time.time()) + '\n' - s.sendto(data, ('', MYPORT)) - time.sleep(2) diff --git a/Demo/sockets/echosvr.py b/Demo/sockets/echosvr.py deleted file mode 100755 index 6f7030e..0000000 --- a/Demo/sockets/echosvr.py +++ /dev/null @@ -1,31 +0,0 @@ -#! /usr/bin/env python3 - -# Python implementation of an 'echo' tcp server: echo all data it receives. -# -# This is the simplest possible server, servicing a single request only. - -import sys -from socket import * - -# The standard echo port isn't very useful, it requires root permissions! -# ECHO_PORT = 7 -ECHO_PORT = 50000 + 7 -BUFSIZE = 1024 - -def main(): - if len(sys.argv) > 1: - port = int(eval(sys.argv[1])) - else: - port = ECHO_PORT - s = socket(AF_INET, SOCK_STREAM) - s.bind(('', port)) - s.listen(1) - conn, (remotehost, remoteport) = s.accept() - print('connected by', remotehost, remoteport) - while 1: - data = conn.recv(BUFSIZE) - if not data: - break - conn.send(data) - -main() diff --git a/Demo/sockets/finger.py b/Demo/sockets/finger.py deleted file mode 100755 index 4d49391..0000000 --- a/Demo/sockets/finger.py +++ /dev/null @@ -1,58 +0,0 @@ -#! /usr/bin/env python3 - -# Python interface to the Internet finger daemon. -# -# Usage: finger [options] [user][@host] ... -# -# If no host is given, the finger daemon on the local host is contacted. -# Options are passed uninterpreted to the finger daemon! - - -import sys, string -from socket import * - - -# Hardcode the number of the finger port here. -# It's not likely to change soon... -# -FINGER_PORT = 79 - - -# Function to do one remote finger invocation. -# Output goes directly to stdout (although this can be changed). -# -def finger(host, args): - s = socket(AF_INET, SOCK_STREAM) - s.connect((host, FINGER_PORT)) - s.send(args + '\n') - while 1: - buf = s.recv(1024) - if not buf: break - sys.stdout.write(buf) - sys.stdout.flush() - - -# Main function: argument parsing. -# -def main(): - options = '' - i = 1 - while i < len(sys.argv) and sys.argv[i][:1] == '-': - options = options + sys.argv[i] + ' ' - i = i+1 - args = sys.argv[i:] - if not args: - args = [''] - for arg in args: - if '@' in arg: - at = string.index(arg, '@') - host = arg[at+1:] - arg = arg[:at] - else: - host = '' - finger(host, options + arg) - - -# Call the main function. -# -main() diff --git a/Demo/sockets/ftp.py b/Demo/sockets/ftp.py deleted file mode 100644 index 5ea99c7..0000000 --- a/Demo/sockets/ftp.py +++ /dev/null @@ -1,152 +0,0 @@ -# A simple FTP client. -# -# The information to write this program was gathered from RFC 959, -# but this is not a complete implementation! Yet it shows how a simple -# FTP client can be built, and you are welcome to extend it to suit -# it to your needs... -# -# How it works (assuming you've read the RFC): -# -# User commands are passed uninterpreted to the server. However, the -# user never needs to send a PORT command. Rather, the client opens a -# port right away and sends the appropriate PORT command to the server. -# When a response code 150 is received, this port is used to receive -# the data (which is written to stdout in this version), and when the -# data is exhausted, a new port is opened and a corresponding PORT -# command sent. In order to avoid errors when reusing ports quickly -# (and because there is no s.getsockname() method in Python yet) we -# cycle through a number of ports in the 50000 range. - - -import sys, posix, string -from socket import * - - -BUFSIZE = 1024 - -# Default port numbers used by the FTP protocol. -# -FTP_PORT = 21 -FTP_DATA_PORT = FTP_PORT - 1 - -# Change the data port to something not needing root permissions. -# -FTP_DATA_PORT = FTP_DATA_PORT + 50000 - - -# Main program (called at the end of this file). -# -def main(): - hostname = sys.argv[1] - control(hostname) - - -# Control process (user interface and user protocol interpreter). -# -def control(hostname): - # - # Create control connection - # - s = socket(AF_INET, SOCK_STREAM) - s.connect((hostname, FTP_PORT)) - f = s.makefile('r') # Reading the replies is easier from a file... - # - # Control loop - # - r = None - while 1: - code = getreply(f) - if code in ('221', 'EOF'): break - if code == '150': - getdata(r) - code = getreply(f) - r = None - if not r: - r = newdataport(s, f) - cmd = getcommand() - if not cmd: break - s.send(cmd + '\r\n') - - -# Create a new data port and send a PORT command to the server for it. -# (Cycle through a number of ports to avoid problems with reusing -# a port within a short time.) -# -nextport = 0 -# -def newdataport(s, f): - global nextport - port = nextport + FTP_DATA_PORT - nextport = (nextport+1) % 16 - r = socket(AF_INET, SOCK_STREAM) - r.bind((gethostbyname(gethostname()), port)) - r.listen(1) - sendportcmd(s, f, port) - return r - - -# Send an appropriate port command. -# -def sendportcmd(s, f, port): - hostname = gethostname() - hostaddr = gethostbyname(hostname) - hbytes = string.splitfields(hostaddr, '.') - pbytes = [repr(port//256), repr(port%256)] - bytes = hbytes + pbytes - cmd = 'PORT ' + string.joinfields(bytes, ',') - s.send(cmd + '\r\n') - code = getreply(f) - - -# Process an ftp reply and return the 3-digit reply code (as a string). -# The reply should be a line of text starting with a 3-digit number. -# If the 4th char is '-', it is a multi-line reply and is -# terminate by a line starting with the same 3-digit number. -# Any text while receiving the reply is echoed to the file. -# -def getreply(f): - line = f.readline() - if not line: return 'EOF' - print(line, end=' ') - code = line[:3] - if line[3:4] == '-': - while 1: - line = f.readline() - if not line: break # Really an error - print(line, end=' ') - if line[:3] == code and line[3:4] != '-': break - return code - - -# Get the data from the data connection. -# -def getdata(r): - print('(accepting data connection)') - conn, host = r.accept() - print('(data connection accepted)') - while 1: - data = conn.recv(BUFSIZE) - if not data: break - sys.stdout.write(data) - print('(end of data connection)') - -def raw_input(prompt): - sys.stdout.write(prompt) - sys.stdout.flush() - return sys.stdin.readline() - -# Get a command from the user. -# -def getcommand(): - try: - while 1: - line = input('ftp.py> ') - if line: return line - except EOFError: - return '' - - -# Call the main program. -# -if __name__ == '__main__': - main() diff --git a/Demo/sockets/gopher.py b/Demo/sockets/gopher.py deleted file mode 100755 index bd29ec0..0000000 --- a/Demo/sockets/gopher.py +++ /dev/null @@ -1,352 +0,0 @@ -#! /usr/bin/env python3 - -# A simple gopher client. -# -# Usage: gopher [ [selector] host [port] ] - -import sys -import os -import socket - -# Default selector, host and port -DEF_SELECTOR = '' -DEF_HOST = 'gopher.micro.umn.edu' -DEF_PORT = 70 - -# Recognized file types -T_TEXTFILE = '0' -T_MENU = '1' -T_CSO = '2' -T_ERROR = '3' -T_BINHEX = '4' -T_DOS = '5' -T_UUENCODE = '6' -T_SEARCH = '7' -T_TELNET = '8' -T_BINARY = '9' -T_REDUNDANT = '+' -T_SOUND = 's' - -# Dictionary mapping types to strings -typename = {'0': '', '1': '', '2': '', '3': '', \ - '4': '', '5': '', '6': '', '7': '', \ - '8': '', '9': '', '+': '', 's': ''} - -# Oft-used characters and strings -CRLF = '\r\n' -TAB = '\t' - -# Open a TCP connection to a given host and port -def open_socket(host, port): - if not port: - port = DEF_PORT - elif type(port) == type(''): - port = int(port) - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect((host, port)) - return s - -# Send a selector to a given host and port, return a file with the reply -def send_request(selector, host, port): - s = open_socket(host, port) - s.send(selector + CRLF) - s.shutdown(1) - return s.makefile('r') - -# Get a menu in the form of a list of entries -def get_menu(selector, host, port): - f = send_request(selector, host, port) - list = [] - while 1: - line = f.readline() - if not line: - print('(Unexpected EOF from server)') - break - if line[-2:] == CRLF: - line = line[:-2] - elif line[-1:] in CRLF: - line = line[:-1] - if line == '.': - break - if not line: - print('(Empty line from server)') - continue - typechar = line[0] - parts = line[1:].split(TAB) - if len(parts) < 4: - print('(Bad line from server: %r)' % (line,)) - continue - if len(parts) > 4: - print('(Extra info from server: %r)' % (parts[4:],)) - parts.insert(0, typechar) - list.append(parts) - f.close() - return list - -# Get a text file as a list of lines, with trailing CRLF stripped -def get_textfile(selector, host, port): - list = [] - get_alt_textfile(selector, host, port, list.append) - return list - -# Get a text file and pass each line to a function, with trailing CRLF stripped -def get_alt_textfile(selector, host, port, func): - f = send_request(selector, host, port) - while 1: - line = f.readline() - if not line: - print('(Unexpected EOF from server)') - break - if line[-2:] == CRLF: - line = line[:-2] - elif line[-1:] in CRLF: - line = line[:-1] - if line == '.': - break - if line[:2] == '..': - line = line[1:] - func(line) - f.close() - -# Get a binary file as one solid data block -def get_binary(selector, host, port): - f = send_request(selector, host, port) - data = f.read() - f.close() - return data - -# Get a binary file and pass each block to a function -def get_alt_binary(selector, host, port, func, blocksize): - f = send_request(selector, host, port) - while 1: - data = f.read(blocksize) - if not data: - break - func(data) - -# A *very* simple interactive browser - -# Browser main command, has default arguments -def browser(*args): - selector = DEF_SELECTOR - host = DEF_HOST - port = DEF_PORT - n = len(args) - if n > 0 and args[0]: - selector = args[0] - if n > 1 and args[1]: - host = args[1] - if n > 2 and args[2]: - port = args[2] - if n > 3: - raise RuntimeError('too many args') - try: - browse_menu(selector, host, port) - except socket.error as msg: - print('Socket error:', msg) - sys.exit(1) - except KeyboardInterrupt: - print('\n[Goodbye]') - -# Browse a menu -def browse_menu(selector, host, port): - list = get_menu(selector, host, port) - while 1: - print('----- MENU -----') - print('Selector:', repr(selector)) - print('Host:', host, ' Port:', port) - print() - for i in range(len(list)): - item = list[i] - typechar, description = item[0], item[1] - print(repr(i+1).rjust(3) + ':', description, end=' ') - if typechar in typename: - print(typename[typechar]) - else: - print('') - print() - while 1: - try: - str = input('Choice [CR == up a level]: ') - except EOFError: - print() - return - if not str: - return - try: - choice = int(str) - except ValueError: - print('Choice must be a number; try again:') - continue - if not 0 < choice <= len(list): - print('Choice out of range; try again:') - continue - break - item = list[choice-1] - typechar = item[0] - [i_selector, i_host, i_port] = item[2:5] - if typechar in typebrowser: - browserfunc = typebrowser[typechar] - try: - browserfunc(i_selector, i_host, i_port) - except (IOError, socket.error): - t, v, tb = sys.exc_info() - print('***', t, ':', v) - else: - print('Unsupported object type') - -# Browse a text file -def browse_textfile(selector, host, port): - x = None - try: - p = os.popen('${PAGER-more}', 'w') - x = SaveLines(p) - get_alt_textfile(selector, host, port, x.writeln) - except IOError as msg: - print('IOError:', msg) - if x: - x.close() - f = open_savefile() - if not f: - return - x = SaveLines(f) - try: - get_alt_textfile(selector, host, port, x.writeln) - print('Done.') - except IOError as msg: - print('IOError:', msg) - x.close() - -def raw_input(prompt): - sys.stdout.write(prompt) - sys.stdout.flush() - return sys.stdin.readline() - -# Browse a search index -def browse_search(selector, host, port): - while 1: - print('----- SEARCH -----') - print('Selector:', repr(selector)) - print('Host:', host, ' Port:', port) - print() - try: - query = input('Query [CR == up a level]: ') - except EOFError: - print() - break - query = query.strip() - if not query: - break - if '\t' in query: - print('Sorry, queries cannot contain tabs') - continue - browse_menu(selector + TAB + query, host, port) - -# "Browse" telnet-based information, i.e. open a telnet session -def browse_telnet(selector, host, port): - if selector: - print('Log in as', repr(selector)) - if type(port) != type(''): - port = repr(port) - sts = os.system('set -x; exec telnet ' + host + ' ' + port) - if sts: - print('Exit status:', sts) - -# "Browse" a binary file, i.e. save it to a file -def browse_binary(selector, host, port): - f = open_savefile() - if not f: - return - x = SaveWithProgress(f) - get_alt_binary(selector, host, port, x.write, 8*1024) - x.close() - -# "Browse" a sound file, i.e. play it or save it -def browse_sound(selector, host, port): - browse_binary(selector, host, port) - -# Dictionary mapping types to browser functions -typebrowser = {'0': browse_textfile, '1': browse_menu, \ - '4': browse_binary, '5': browse_binary, '6': browse_textfile, \ - '7': browse_search, \ - '8': browse_telnet, '9': browse_binary, 's': browse_sound} - -# Class used to save lines, appending a newline to each line -class SaveLines: - def __init__(self, f): - self.f = f - def writeln(self, line): - self.f.write(line + '\n') - def close(self): - sts = self.f.close() - if sts: - print('Exit status:', sts) - -# Class used to save data while showing progress -class SaveWithProgress: - def __init__(self, f): - self.f = f - def write(self, data): - sys.stdout.write('#') - sys.stdout.flush() - self.f.write(data) - def close(self): - print() - sts = self.f.close() - if sts: - print('Exit status:', sts) - -# Ask for and open a save file, or return None if not to save -def open_savefile(): - try: - savefile = input( \ - 'Save as file [CR == don\'t save; |pipeline or ~user/... OK]: ') - except EOFError: - print() - return None - savefile = savefile.strip() - if not savefile: - return None - if savefile[0] == '|': - cmd = savefile[1:].strip() - try: - p = os.popen(cmd, 'w') - except IOError as msg: - print(repr(cmd), ':', msg) - return None - print('Piping through', repr(cmd), '...') - return p - if savefile[0] == '~': - savefile = os.path.expanduser(savefile) - try: - f = open(savefile, 'w') - except IOError as msg: - print(repr(savefile), ':', msg) - return None - print('Saving to', repr(savefile), '...') - return f - -# Test program -def test(): - if sys.argv[4:]: - print('usage: gopher [ [selector] host [port] ]') - sys.exit(2) - elif sys.argv[3:]: - browser(sys.argv[1], sys.argv[2], sys.argv[3]) - elif sys.argv[2:]: - try: - port = int(sys.argv[2]) - selector = '' - host = sys.argv[1] - except ValueError: - selector = sys.argv[1] - host = sys.argv[2] - port = '' - browser(selector, host, port) - elif sys.argv[1:]: - browser('', sys.argv[1]) - else: - browser() - -# Call the test program as a main program -test() diff --git a/Demo/sockets/mcast.py b/Demo/sockets/mcast.py deleted file mode 100755 index 6ce7c6d..0000000 --- a/Demo/sockets/mcast.py +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env python3 -# -# Send/receive UDP multicast packets. -# Requires that your OS kernel supports IP multicast. -# -# Usage: -# mcast -s (sender, IPv4) -# mcast -s -6 (sender, IPv6) -# mcast (receivers, IPv4) -# mcast -6 (receivers, IPv6) - -MYPORT = 8123 -MYGROUP_4 = '225.0.0.250' -MYGROUP_6 = 'ff15:7079:7468:6f6e:6465:6d6f:6d63:6173' -MYTTL = 1 # Increase to reach other networks - -import time -import struct -import socket -import sys - -def main(): - group = MYGROUP_6 if "-6" in sys.argv[1:] else MYGROUP_4 - - if "-s" in sys.argv[1:]: - sender(group) - else: - receiver(group) - - -def sender(group): - addrinfo = socket.getaddrinfo(group, None)[0] - - s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) - - # Set Time-to-live (optional) - ttl_bin = struct.pack('@i', MYTTL) - if addrinfo[0] == socket.AF_INET: # IPv4 - s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin) - else: - s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin) - - while True: - data = repr(time.time()).encode('utf-8') + b'\0' - s.sendto(data, (addrinfo[4][0], MYPORT)) - time.sleep(1) - - -def receiver(group): - # Look up multicast group address in name server and find out IP version - addrinfo = socket.getaddrinfo(group, None)[0] - - # Create a socket - s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) - - # Allow multiple copies of this program on one machine - # (not strictly needed) - s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - - # Bind it to the port - s.bind(('', MYPORT)) - - group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0]) - # Join group - if addrinfo[0] == socket.AF_INET: # IPv4 - mreq = group_bin + struct.pack('=I', socket.INADDR_ANY) - s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) - else: - mreq = group_bin + struct.pack('@I', 0) - s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq) - - # Loop, printing any data we receive - while True: - data, sender = s.recvfrom(1500) - while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's - print(str(sender) + ' ' + repr(data)) - - -if __name__ == '__main__': - main() diff --git a/Demo/sockets/radio.py b/Demo/sockets/radio.py deleted file mode 100644 index fa4ce75..0000000 --- a/Demo/sockets/radio.py +++ /dev/null @@ -1,14 +0,0 @@ -# Receive UDP packets transmitted by a broadcasting service - -MYPORT = 50000 - -import sys -from socket import * - -s = socket(AF_INET, SOCK_DGRAM) -s.bind(('', MYPORT)) - -while 1: - data, wherefrom = s.recvfrom(1500, 0) - sys.stderr.write(repr(wherefrom) + '\n') - sys.stdout.write(data) diff --git a/Demo/sockets/rpython.py b/Demo/sockets/rpython.py deleted file mode 100755 index 7dcf979..0000000 --- a/Demo/sockets/rpython.py +++ /dev/null @@ -1,35 +0,0 @@ -#! /usr/bin/env python3 - -# Remote python client. -# Execute Python commands remotely and send output back. - -import sys -import string -from socket import * - -PORT = 4127 -BUFSIZE = 1024 - -def main(): - if len(sys.argv) < 3: - print("usage: rpython host command") - sys.exit(2) - host = sys.argv[1] - port = PORT - i = string.find(host, ':') - if i >= 0: - port = string.atoi(port[i+1:]) - host = host[:i] - command = string.join(sys.argv[2:]) - s = socket(AF_INET, SOCK_STREAM) - s.connect((host, port)) - s.send(command) - s.shutdown(1) - reply = '' - while 1: - data = s.recv(BUFSIZE) - if not data: break - reply = reply + data - print(reply, end=' ') - -main() diff --git a/Demo/sockets/rpythond.py b/Demo/sockets/rpythond.py deleted file mode 100755 index e244d6c..0000000 --- a/Demo/sockets/rpythond.py +++ /dev/null @@ -1,52 +0,0 @@ -#! /usr/bin/env python3 - -# Remote python server. -# Execute Python commands remotely and send output back. -# WARNING: This version has a gaping security hole -- it accepts requests -# from any host on the Internet! - -import sys -from socket import * -import io -import traceback - -PORT = 4127 -BUFSIZE = 1024 - -def main(): - if len(sys.argv) > 1: - port = int(eval(sys.argv[1])) - else: - port = PORT - s = socket(AF_INET, SOCK_STREAM) - s.bind(('', port)) - s.listen(1) - while 1: - conn, (remotehost, remoteport) = s.accept() - print('connected by', remotehost, remoteport) - request = '' - while 1: - data = conn.recv(BUFSIZE) - if not data: - break - request = request + data - reply = execute(request) - conn.send(reply) - conn.close() - -def execute(request): - stdout = sys.stdout - stderr = sys.stderr - sys.stdout = sys.stderr = fakefile = io.StringIO() - try: - try: - exec(request, {}, {}) - except: - print() - traceback.print_exc(100) - finally: - sys.stderr = stderr - sys.stdout = stdout - return fakefile.getvalue() - -main() diff --git a/Demo/sockets/telnet.py b/Demo/sockets/telnet.py deleted file mode 100755 index fb36faf..0000000 --- a/Demo/sockets/telnet.py +++ /dev/null @@ -1,109 +0,0 @@ -#! /usr/bin/env python3 - -# Minimal interface to the Internet telnet protocol. -# -# It refuses all telnet options and does not recognize any of the other -# telnet commands, but can still be used to connect in line-by-line mode. -# It's also useful to play with a number of other services, -# like time, finger, smtp and even ftp. -# -# Usage: telnet host [port] -# -# The port may be a service name or a decimal port number; -# it defaults to 'telnet'. - - -import sys, posix, time -from socket import * - -BUFSIZE = 1024 - -# Telnet protocol characters - -IAC = chr(255) # Interpret as command -DONT = chr(254) -DO = chr(253) -WONT = chr(252) -WILL = chr(251) - -def main(): - host = sys.argv[1] - try: - hostaddr = gethostbyname(host) - except error: - sys.stderr.write(sys.argv[1] + ': bad host name\n') - sys.exit(2) - # - if len(sys.argv) > 2: - servname = sys.argv[2] - else: - servname = 'telnet' - # - if '0' <= servname[:1] <= '9': - port = eval(servname) - else: - try: - port = getservbyname(servname, 'tcp') - except error: - sys.stderr.write(servname + ': bad tcp service name\n') - sys.exit(2) - # - s = socket(AF_INET, SOCK_STREAM) - # - try: - s.connect((host, port)) - except error as msg: - sys.stderr.write('connect failed: ' + repr(msg) + '\n') - sys.exit(1) - # - pid = posix.fork() - # - if pid == 0: - # child -- read stdin, write socket - while 1: - line = sys.stdin.readline() - s.send(line) - else: - # parent -- read socket, write stdout - iac = 0 # Interpret next char as command - opt = '' # Interpret next char as option - while 1: - data = s.recv(BUFSIZE) - if not data: - # EOF; kill child and exit - sys.stderr.write( '(Closed by remote host)\n') - posix.kill(pid, 9) - sys.exit(1) - cleandata = '' - for c in data: - if opt: - print(ord(c)) - s.send(opt + c) - opt = '' - elif iac: - iac = 0 - if c == IAC: - cleandata = cleandata + c - elif c in (DO, DONT): - if c == DO: print('(DO)', end=' ') - else: print('(DONT)', end=' ') - opt = IAC + WONT - elif c in (WILL, WONT): - if c == WILL: print('(WILL)', end=' ') - else: print('(WONT)', end=' ') - opt = IAC + DONT - else: - print('(command)', ord(c)) - elif c == IAC: - iac = 1 - print('(IAC)', end=' ') - else: - cleandata = cleandata + c - sys.stdout.write(cleandata) - sys.stdout.flush() - - -try: - main() -except KeyboardInterrupt: - pass diff --git a/Demo/sockets/throughput.py b/Demo/sockets/throughput.py deleted file mode 100755 index 5954316..0000000 --- a/Demo/sockets/throughput.py +++ /dev/null @@ -1,93 +0,0 @@ -#! /usr/bin/env python3 - -# Test network throughput. -# -# Usage: -# 1) on host_A: throughput -s [port] # start a server -# 2) on host_B: throughput -c count host_A [port] # start a client -# -# The server will service multiple clients until it is killed. -# -# The client performs one transfer of count*BUFSIZE bytes and -# measures the time it takes (roundtrip!). - - -import sys, time -from socket import * - -MY_PORT = 50000 + 42 - -BUFSIZE = 1024 - - -def main(): - if len(sys.argv) < 2: - usage() - if sys.argv[1] == '-s': - server() - elif sys.argv[1] == '-c': - client() - else: - usage() - - -def usage(): - sys.stdout = sys.stderr - print('Usage: (on host_A) throughput -s [port]') - print('and then: (on host_B) throughput -c count host_A [port]') - sys.exit(2) - - -def server(): - if len(sys.argv) > 2: - port = eval(sys.argv[2]) - else: - port = MY_PORT - s = socket(AF_INET, SOCK_STREAM) - s.bind(('', port)) - s.listen(1) - print('Server ready...') - while 1: - conn, (host, remoteport) = s.accept() - while 1: - data = conn.recv(BUFSIZE) - if not data: - break - del data - conn.send('OK\n') - conn.close() - print('Done with', host, 'port', remoteport) - - -def client(): - if len(sys.argv) < 4: - usage() - count = int(eval(sys.argv[2])) - host = sys.argv[3] - if len(sys.argv) > 4: - port = eval(sys.argv[4]) - else: - port = MY_PORT - testdata = 'x' * (BUFSIZE-1) + '\n' - t1 = time.time() - s = socket(AF_INET, SOCK_STREAM) - t2 = time.time() - s.connect((host, port)) - t3 = time.time() - i = 0 - while i < count: - i = i+1 - s.send(testdata) - s.shutdown(1) # Send EOF - t4 = time.time() - data = s.recv(BUFSIZE) - t5 = time.time() - print(data) - print('Raw timers:', t1, t2, t3, t4, t5) - print('Intervals:', t2-t1, t3-t2, t4-t3, t5-t4) - print('Total:', t5-t1) - print('Throughput:', round((BUFSIZE*count*0.001) / (t5-t1), 3), end=' ') - print('K/sec.') - - -main() diff --git a/Demo/sockets/udpecho.py b/Demo/sockets/udpecho.py deleted file mode 100755 index 6983a1f..0000000 --- a/Demo/sockets/udpecho.py +++ /dev/null @@ -1,64 +0,0 @@ -#! /usr/bin/env python3 - -# Client and server for udp (datagram) echo. -# -# Usage: udpecho -s [port] (to start a server) -# or: udpecho -c host [port] 2: - port = eval(sys.argv[2]) - else: - port = ECHO_PORT - s = socket(AF_INET, SOCK_DGRAM) - s.bind(('', port)) - print('udp echo server ready') - while 1: - data, addr = s.recvfrom(BUFSIZE) - print('server received %r from %r' % (data, addr)) - s.sendto(data, addr) - -def client(): - if len(sys.argv) < 3: - usage() - host = sys.argv[2] - if len(sys.argv) > 3: - port = eval(sys.argv[3]) - else: - port = ECHO_PORT - addr = host, port - s = socket(AF_INET, SOCK_DGRAM) - s.bind(('', 0)) - print('udp echo client ready, reading stdin') - while 1: - line = sys.stdin.readline() - if not line: - break - print('addr = ', addr) - s.sendto(bytes(line, 'ascii'), addr) - data, fromaddr = s.recvfrom(BUFSIZE) - print('client received %r from %r' % (data, fromaddr)) - -main() diff --git a/Demo/sockets/unicast.py b/Demo/sockets/unicast.py deleted file mode 100644 index dd15e3c..0000000 --- a/Demo/sockets/unicast.py +++ /dev/null @@ -1,14 +0,0 @@ -# Send UDP broadcast packets - -MYPORT = 50000 - -import sys, time -from socket import * - -s = socket(AF_INET, SOCK_DGRAM) -s.bind(('', 0)) - -while 1: - data = repr(time.time()) + '\n' - s.sendto(data, ('', MYPORT)) - time.sleep(2) diff --git a/Demo/sockets/unixclient.py b/Demo/sockets/unixclient.py deleted file mode 100644 index 5e87eed..0000000 --- a/Demo/sockets/unixclient.py +++ /dev/null @@ -1,12 +0,0 @@ -# Echo client demo using Unix sockets -# Piet van Oostrum - -from socket import * - -FILE = 'unix-socket' -s = socket(AF_UNIX, SOCK_STREAM) -s.connect(FILE) -s.send(b'Hello, world') -data = s.recv(1024) -s.close() -print('Received', repr(data)) diff --git a/Demo/sockets/unixserver.py b/Demo/sockets/unixserver.py deleted file mode 100644 index c3c9c4f..0000000 --- a/Demo/sockets/unixserver.py +++ /dev/null @@ -1,24 +0,0 @@ -# Echo server demo using Unix sockets (handles one connection only) -# Piet van Oostrum - -import os -from socket import * - -FILE = 'unix-socket' -s = socket(AF_UNIX, SOCK_STREAM) -s.bind(FILE) - -print('Sock name is: ['+s.getsockname()+']') - -# Wait for a connection -s.listen(1) -conn, addr = s.accept() - -while True: - data = conn.recv(1024) - if not data: - break - conn.send(data) - -conn.close() -os.unlink(FILE) diff --git a/Demo/tix/INSTALL.txt b/Demo/tix/INSTALL.txt deleted file mode 100644 index ac70b68..0000000 --- a/Demo/tix/INSTALL.txt +++ /dev/null @@ -1,89 +0,0 @@ -$Id$ - -Installing Tix.py ----------------- - -0) To use Tix.py, you need Tcl/Tk (V8.3.3), Tix (V8.1.1) and Python (V2.1.1). - Tix.py has been written and tested on a Intel Pentium running RH Linux 5.2 - and Mandrake Linux 7.0 and Windows with the above mentioned packages. - - Older versions, e.g. Tix 4.1 and Tk 8.0, might also work. - - There is nothing OS-specific in Tix.py itself so it should work on - any machine with Tix and Python installed. You can get Tcl and Tk - from http://dev.scriptics.com and Tix from http://tix.sourceforge.net. - -1) Build and install Tcl/Tk 8.3. Build and install Tix 8.1. - Ensure that Tix is properly installed by running tixwish and executing - the demo programs. Under Unix, use the --enable-shared configure option - for all three. We recommend tcl8.3.3 for this release of Tix.py. - -2a) If you have a distribution like ActiveState with a tcl subdirectory - of $PYTHONHOME, which contains the directories tcl8.3 and tk8.3, - make a directory tix8.1 as well. Recursively copy the files from - /library to $PYTHONHOME/lib/tix8.1, and copy the dynamic library - (tix8183.dll or libtix8.1.8.3.so) to the same place as the tcl dynamic - libraries ($PYTHONHOME/Dlls or lib/python-2.1/lib-dynload). In this - case you are all installed, and you can skip to the end. - -2b) Modify Modules/Setup.dist and setup.py to change the version of the - tix library from tix4.1.8.0 to tix8.1.8.3 - These modified files can be used for Tkinter with or without Tix. - -3) The default is to build dynamically, and use the Tcl 'package require'. - To build statically, modify the Modules/Setup file to link in the Tix - library according to the comments in the file. On Linux this looks like: - -# *** Always uncomment this (leave the leading underscore in!): -_tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \ -# *** Uncomment and edit to reflect where your Tcl/Tk libraries are: - -L/usr/local/lib \ -# *** Uncomment and edit to reflect where your Tcl/Tk headers are: - -I/usr/local/include \ -# *** Uncomment and edit to reflect where your X11 header files are: - -I/usr/X11R6/include \ -# *** Or uncomment this for Solaris: -# -I/usr/openwin/include \ -# *** Uncomment and edit for BLT extension only: -# -DWITH_BLT -I/usr/local/blt/blt8.0-unoff/include -lBLT8.0 \ -# *** Uncomment and edit for PIL (TkImaging) extension only: -# (See http://www.pythonware.com/products/pil/ for more info) -# -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \ -# *** Uncomment and edit for TOGL extension only: -# -DWITH_TOGL togl.c \ -# *** Uncomment and edit for Tix extension only: - -DWITH_TIX -ltix8.1.8.3 \ -# *** Uncomment and edit to reflect your Tcl/Tk versions: - -ltk8.3 -ltcl8.3 \ -# *** Uncomment and edit to reflect where your X11 libraries are: - -L/usr/X11R6/lib \ -# *** Or uncomment this for Solaris: -# -L/usr/openwin/lib \ -# *** Uncomment these for TOGL extension only: -# -lGL -lGLU -lXext -lXmu \ -# *** Uncomment for AIX: -# -lld \ -# *** Always uncomment this; X11 libraries to link with: - -lX11 - -4) Rebuild Python and reinstall. - -You should now have a working Tix implementation in Python. To see if all -is as it should be, run the 'tixwidgets.py' script in the Demo/tix directory. -Under X windows, do - /usr/local/bin/python Demo/tix/tixwidgets.py - -If this does not work, you may need to tell python where to find -the Tcl, Tk and Tix library files. This is done by setting the -TCL_LIBRARY, TK_LIBRARY and TIX_LIBRARY environment variables. Try this: - - env TCL_LIBRARY=/usr/local/lib/tcl8.3 \ - TK_LIBRARY=/usr/local/lib/tk8.3 \ - TIX_LIBRARY=/usr/local/lib/tix8.1 \ - /usr/local/bin/python Demo/tix/tixwidgets.py - - -If you find any bugs or have suggestions for improvement, please report them -via http://tix.sourceforge.net - - diff --git a/Demo/tix/README.txt b/Demo/tix/README.txt deleted file mode 100644 index e0196ac..0000000 --- a/Demo/tix/README.txt +++ /dev/null @@ -1,19 +0,0 @@ -About Tix.py ------------ - -Tix.py is based on an idea of Jean-Marc Lugrin (lugrin@ms.com) who wrote -pytix (another Python-Tix marriage). Tix widgets are an attractive and -useful extension to Tk. See http://tix.sourceforge.net -for more details about Tix and how to get it. - -Features: - 1) It is almost complete. - 2) Tix widgets are represented by classes in Python. Sub-widgets - are members of the mega-widget class. For example, if a - particular TixWidget (e.g. ScrolledText) has an embedded widget - (Text in this case), it is possible to call the methods of the - child directly. - 3) The members of the class are created automatically. In the case - of widgets like ButtonBox, the members are added dynamically. - - diff --git a/Demo/tix/bitmaps/about.xpm b/Demo/tix/bitmaps/about.xpm deleted file mode 100755 index 33ffcc0..0000000 --- a/Demo/tix/bitmaps/about.xpm +++ /dev/null @@ -1,50 +0,0 @@ -/* XPM */ -static char * about_xpm[] = { -"50 40 7 1", -" s None c None", -". c black", -"X c white", -"o c gray70", -"O c navy", -"+ c red", -"@ c yellow", -" ", -" ", -" ", -" ................................. ", -" ..XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXoo. ", -" .XooooooooooooooooooooooooooooooXo. ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXooXo. ", -" ..oooooooooooooooooooooooooooooooXo. ", -" ...............................XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo.++++ ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo+++ ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo+++++ ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo++++++ ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo+++ + ", -" .OOOOO@@@@@OOOOOOOOOOOOOOOOOOO.Xo++. ", -" .OOOOOOO@OOOOO@OOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOO@OOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOO@OOOO@@OOO@OOO@OOOOOOO.XoXo. ", -" .OOOOOOO@OOOOO@OOOO@O@OOOOOOOO.XoXo. ", -" .OOOOOOO@OOOOO@OOOOO@OOOOOOOOO.XoXo. ", -" .OOOOOOO@OOOOO@OOOOO@OOOOOOOOO.XoXo. ", -" .OOOOOOO@OOOOO@OOOO@O@OOOOOOOO.XoXo. ", -" .OOOOOOO@OOOO@@@OO@OOO@OOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XoXo. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo.. ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo ", -" OOOOOOOOOOOOOOOOOOOOOOOOOOOOO.X. ", -" ............................. ", -" ", -" ", -" "}; diff --git a/Demo/tix/bitmaps/bold.xbm b/Demo/tix/bitmaps/bold.xbm deleted file mode 100755 index ebff8d1..0000000 --- a/Demo/tix/bitmaps/bold.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define bold_width 16 -#define bold_height 16 -static unsigned char bold_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x0f, 0x18, 0x1c, 0x18, 0x18, - 0x18, 0x18, 0x18, 0x1c, 0xf8, 0x0f, 0xf8, 0x0f, 0x18, 0x18, 0x18, 0x30, - 0x18, 0x30, 0x18, 0x38, 0xfc, 0x3f, 0xfc, 0x1f}; diff --git a/Demo/tix/bitmaps/capital.xbm b/Demo/tix/bitmaps/capital.xbm deleted file mode 100755 index fb4e070..0000000 --- a/Demo/tix/bitmaps/capital.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define capital_width 16 -#define capital_height 16 -static unsigned char capital_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x08, 0x30, 0x0c, 0x30, 0x06, - 0x30, 0x03, 0xb0, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x01, 0xb0, 0x03, - 0x30, 0x07, 0x30, 0x0e, 0x30, 0x1c, 0x00, 0x00}; diff --git a/Demo/tix/bitmaps/centerj.xbm b/Demo/tix/bitmaps/centerj.xbm deleted file mode 100755 index 9d2c064..0000000 --- a/Demo/tix/bitmaps/centerj.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define centerj_width 16 -#define centerj_height 16 -static unsigned char centerj_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3e, 0x00, 0x00, 0xc0, 0x0d, - 0x00, 0x00, 0x58, 0x77, 0x00, 0x00, 0xb0, 0x3b, 0x00, 0x00, 0xdc, 0xf7, - 0x00, 0x00, 0xf0, 0x3e, 0x00, 0x00, 0xd8, 0x7e}; diff --git a/Demo/tix/bitmaps/combobox.xbm b/Demo/tix/bitmaps/combobox.xbm deleted file mode 100755 index f5947f5..0000000 --- a/Demo/tix/bitmaps/combobox.xbm +++ /dev/null @@ -1,14 +0,0 @@ -#define combobox_width 32 -#define combobox_height 32 -static unsigned char combobox_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xfc, 0xff, 0xff, 0x3e, 0x04, 0x00, 0x80, 0x2a, 0x04, 0x00, 0x80, 0x2a, - 0x04, 0x00, 0x80, 0x2a, 0x04, 0x00, 0x80, 0x2b, 0xfc, 0xff, 0xff, 0x3e, - 0x08, 0x00, 0x00, 0x20, 0x08, 0x00, 0x00, 0x3e, 0x08, 0x00, 0x00, 0x2a, - 0x28, 0x49, 0x00, 0x2a, 0x08, 0x00, 0x00, 0x3e, 0x08, 0x00, 0x00, 0x22, - 0x08, 0x00, 0x00, 0x22, 0x28, 0x49, 0x12, 0x22, 0x08, 0x00, 0x00, 0x22, - 0x08, 0x00, 0x00, 0x22, 0x08, 0x00, 0x00, 0x22, 0x28, 0x49, 0x02, 0x22, - 0x08, 0x00, 0x00, 0x3e, 0x08, 0x00, 0x00, 0x2a, 0x08, 0x00, 0x00, 0x2a, - 0xf8, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/Demo/tix/bitmaps/combobox.xpm b/Demo/tix/bitmaps/combobox.xpm deleted file mode 100755 index d0234ab..0000000 --- a/Demo/tix/bitmaps/combobox.xpm +++ /dev/null @@ -1,49 +0,0 @@ -/* XPM */ -static char * combobox_xpm[] = { -"50 40 6 1", -" s None c None", -". c black", -"X c white", -"o c #FFFF80808080", -"O c gray70", -"+ c #808000008080", -" ", -" ", -" ", -" .................................... XXXXXXX ", -" .ooooooooooooooooooooooooooooooooooX X . . ", -" .ooooooooooooooooooooooooooooooooooX X . . ", -" .oooo.oooooooooooooooooooooooooooooX X . . ", -" .oo.o..oo.o.oo.o.ooooooooooooooooooX X . . ", -" .o..o.o.o.oo.oo.oo.ooooooooooooooooX X ... . ", -" .oo.oo.oo.o.oo.ooo.ooooooooooooooooX X . . ", -" .ooooooooooooooooooooooooooooooooooX X . ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X...... ", -" ", -" ", -" ", -" XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ", -" X............................................ ", -" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.OOOOX. ", -" X.O+OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.OX OX. ", -" X.O++OOO+OO+++OOOOOOOOOOOOOOOOOOOOOOOX.X ..X. ", -" X.O+O+O+OOO+O+OOOOOOOOOOOOOOOOOOOOOOOX.OOOOX. ", -" X.O++OOO+OO+++OOOOOOOOOOOOOOOOOOOOOOOX.OOOOX. ", -" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.XXXXX. ", -" X.O.....X..........................OOX.X .X. ", -" X.OX...XXX.X.XX.XX.................OOX.X .X. ", -" X.OX.X..X..X.XX..XX.X..............OOX.X .X. ", -" X.O.X...X..X.X...X..X..............OOX.X .X. ", -" X.OOOOOOOOOOOOOOOOOOOOOOOO+OOOOOOOOOOX.X .X. ", -" X.OOOOOOOOO+OOO+OOOOO+OOOO+OOOOOOOOOOX.X .X. ", -" X.O+++OO+OO+O+OO++O++OO+OO+OOOOOOOOOOX.X...X. ", -" X.OO+OO++OO+O+OO+OOO+OO+O++OOOOOOOOOOX.OOOOX. ", -" X.OOOOOOOO+OOOOO++OO+OOOOOOOOOOOOOOOOX.OOOOX. ", -" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.X .X. ", -" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.O .OX. ", -" X.OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOX.OOOOX. ", -" X.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.XXXXX. ", -" X............................................ ", -" ", -" ", -" "}; diff --git a/Demo/tix/bitmaps/combobox.xpm.1 b/Demo/tix/bitmaps/combobox.xpm.1 deleted file mode 100755 index 63792a4..0000000 --- a/Demo/tix/bitmaps/combobox.xpm.1 +++ /dev/null @@ -1,47 +0,0 @@ -/* XPM */ -static char * combobox_xpm[] = { -"50 40 4 1", -" s None c None", -". c black", -"X c #FFFF80808080", -"o c gray70", -" ", -" ", -" ", -" .................................... ....... ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . ... . ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . . ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. . . ", -" .................................... ....... ", -" ", -" ............................................. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .o...................................o.ooooo. ", -" .o...................................o.ooooo. ", -" .o...................................o.ooooo. ", -" .o...................................o.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" .ooooooooooooooooooooooooooooooooooooo.ooooo. ", -" ............................................. ", -" ", -" ", -" ", -" ", -" "}; diff --git a/Demo/tix/bitmaps/drivea.xbm b/Demo/tix/bitmaps/drivea.xbm deleted file mode 100755 index 83c636c..0000000 --- a/Demo/tix/bitmaps/drivea.xbm +++ /dev/null @@ -1,14 +0,0 @@ -#define drivea_width 32 -#define drivea_height 32 -static unsigned char drivea_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf8, 0xff, 0xff, 0x1f, 0x08, 0x00, 0x00, 0x18, 0xa8, 0xaa, 0xaa, 0x1a, - 0x48, 0x55, 0xd5, 0x1d, 0xa8, 0xaa, 0xaa, 0x1b, 0x48, 0x55, 0x55, 0x1d, - 0xa8, 0xfa, 0xaf, 0x1a, 0xc8, 0xff, 0xff, 0x1d, 0xa8, 0xfa, 0xaf, 0x1a, - 0x48, 0x55, 0x55, 0x1d, 0xa8, 0xaa, 0xaa, 0x1a, 0x48, 0x55, 0x55, 0x1d, - 0xa8, 0xaa, 0xaa, 0x1a, 0xf8, 0xff, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/Demo/tix/bitmaps/drivea.xpm b/Demo/tix/bitmaps/drivea.xpm deleted file mode 100755 index 4d274b9..0000000 --- a/Demo/tix/bitmaps/drivea.xpm +++ /dev/null @@ -1,43 +0,0 @@ -/* XPM */ -static char * drivea_xpm[] = { -/* width height ncolors chars_per_pixel */ -"32 32 5 1", -/* colors */ -" s None c None", -". c #000000000000", -"X c white", -"o c #c000c000c000", -"O c #800080008000", -/* pixels */ -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" .......................... ", -" .XXXXXXXXXXXXXXXXXXXXXXXo. ", -" .XooooooooooooooooooooooO. ", -" .Xooooooooooooooooo..oooO. ", -" .Xooooooooooooooooo..oooO. ", -" .XooooooooooooooooooooooO. ", -" .Xoooooooo.......oooooooO. ", -" .Xoo...................oO. ", -" .Xoooooooo.......oooooooO. ", -" .XooooooooooooooooooooooO. ", -" .XooooooooooooooooooooooO. ", -" .XooooooooooooooooooooooO. ", -" .XooooooooooooooooooooooO. ", -" .oOOOOOOOOOOOOOOOOOOOOOOO. ", -" .......................... ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" "}; diff --git a/Demo/tix/bitmaps/exit.xpm b/Demo/tix/bitmaps/exit.xpm deleted file mode 100755 index 505a07b..0000000 --- a/Demo/tix/bitmaps/exit.xpm +++ /dev/null @@ -1,48 +0,0 @@ -/* XPM */ -static char * exit_xpm[] = { -"50 40 5 1", -" s None c None", -". c black", -"X c white", -"o c #000080800000", -"O c yellow", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ....................................... ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. ", -" .XoooooooooooooooooooooooooooooooooooX. ", -" .XoooooooooooooooooooooooooooooooooooX. ", -" .XoooooooooooooooooooooooOoooooooooooX. ", -" .XoooooooooooooooooooooooOOooooooooooX. ", -" .XoooooooooooooooooooooooOOOoooooooooX. ", -" .XoooooOOOOOOOOOOOOOOOOOOOOOOooooooooX. ", -" .XoooooOOOOOOOOOOOOOOOOOOOOOOOoooooooX. ", -" .XoooooOOOOOOOOOOOOOOOOOOOOOOOOooooooX. ", -" .XoooooOOOOOOOOOOOOOOOOOOOOOOOOOoooooX. ", -" .XoooooOOOOOOOOOOOOOOOOOOOOOOOOooooooX. ", -" .XoooooOOOOOOOOOOOOOOOOOOOOOOOoooooooX. ", -" .XoooooOOOOOOOOOOOOOOOOOOOOOOooooooooX. ", -" .XoooooooooooooooooooooooOOOoooooooooX. ", -" .XoooooooooooooooooooooooOOooooooooooX. ", -" .XoooooooooooooooooooooooOoooooooooooX. ", -" .XoooooooooooooooooooooooooooooooooooX. ", -" .XoooooooooooooooooooooooooooooooooooX. ", -" .XoooooooooooooooooooooooooooooooooooX. ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX. ", -" ....................................... ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" "}; diff --git a/Demo/tix/bitmaps/filebox.xbm b/Demo/tix/bitmaps/filebox.xbm deleted file mode 100755 index c8f7ac2..0000000 --- a/Demo/tix/bitmaps/filebox.xbm +++ /dev/null @@ -1,14 +0,0 @@ -#define filebox_width 32 -#define filebox_height 32 -static unsigned char filebox_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x3f, 0x04, 0x00, 0x00, 0x20, - 0xe4, 0xff, 0xff, 0x27, 0x24, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x24, - 0xe4, 0xff, 0xff, 0x27, 0x04, 0x00, 0x00, 0x20, 0xe4, 0x7f, 0xfe, 0x27, - 0x24, 0x50, 0x02, 0x25, 0x24, 0x40, 0x02, 0x24, 0x24, 0x50, 0x02, 0x25, - 0x24, 0x40, 0x02, 0x24, 0x24, 0x50, 0x02, 0x25, 0x24, 0x40, 0x02, 0x24, - 0x24, 0x50, 0x02, 0x25, 0xe4, 0x7f, 0xfe, 0x27, 0x04, 0x00, 0x00, 0x20, - 0xe4, 0xff, 0xff, 0x27, 0x24, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x24, - 0xe4, 0xff, 0xff, 0x27, 0x04, 0x00, 0x00, 0x20, 0xfc, 0xff, 0xff, 0x3f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/Demo/tix/bitmaps/filebox.xpm b/Demo/tix/bitmaps/filebox.xpm deleted file mode 100755 index 7377ee6..0000000 --- a/Demo/tix/bitmaps/filebox.xpm +++ /dev/null @@ -1,49 +0,0 @@ -/* XPM */ -static char * filebox_xpm[] = { -"50 40 6 1", -" s None c None", -". c white", -"X c gray80", -"o c black", -"O c #FFFF80808080", -"+ c gray70", -" ", -" ", -" ", -" ............................................ ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXooXooXoXooXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXooXooXoXooXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXooooooooooooooooooooooooooooooooooooo.XXo ", -" .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XXo ", -" .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.XXo ", -" .XX......................................XXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXoooooooooooooooo.XXXXoooooooooooooooo.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XXo+++++++++++++++.XXXXo+++++++++++++++.XXo ", -" .XX.................XXXX.................XXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXooXooXoXooXoXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXooXooXoXooXoXooXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXoooooooooooooooooooooooooooooooooooooo.Xo ", -" .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo ", -" .XXoOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO.Xo ", -" .XX.......................................Xo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .ooooooooooooooooooooooooooooooooooooooooooo ", -" ", -" ", -" "}; diff --git a/Demo/tix/bitmaps/italic.xbm b/Demo/tix/bitmaps/italic.xbm deleted file mode 100755 index 169c3cb..0000000 --- a/Demo/tix/bitmaps/italic.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define italic_width 16 -#define italic_height 16 -static unsigned char italic_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x80, 0x3f, 0x00, 0x06, 0x00, 0x06, - 0x00, 0x03, 0x00, 0x03, 0x80, 0x01, 0x80, 0x01, 0xc0, 0x00, 0xc0, 0x00, - 0x60, 0x00, 0x60, 0x00, 0xfc, 0x01, 0xfc, 0x01}; diff --git a/Demo/tix/bitmaps/justify.xbm b/Demo/tix/bitmaps/justify.xbm deleted file mode 100755 index bba660a..0000000 --- a/Demo/tix/bitmaps/justify.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define justify_width 16 -#define justify_height 16 -static unsigned char justify_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xdb, 0x00, 0x00, 0x7c, 0xdb, - 0x00, 0x00, 0xbc, 0xf7, 0x00, 0x00, 0xdc, 0xde, 0x00, 0x00, 0x6c, 0xdf, - 0x00, 0x00, 0x6c, 0xef, 0x00, 0x00, 0xdc, 0xdf}; diff --git a/Demo/tix/bitmaps/leftj.xbm b/Demo/tix/bitmaps/leftj.xbm deleted file mode 100755 index 5f8e006..0000000 --- a/Demo/tix/bitmaps/leftj.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define leftj_width 16 -#define leftj_height 16 -static unsigned char leftj_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x6d, 0x00, 0x00, 0xdc, 0x01, - 0x00, 0x00, 0xec, 0x0e, 0x00, 0x00, 0xfc, 0x7e, 0x00, 0x00, 0xdc, 0x03, - 0x00, 0x00, 0x6c, 0x3b, 0x00, 0x00, 0x6c, 0x1f}; diff --git a/Demo/tix/bitmaps/netw.xbm b/Demo/tix/bitmaps/netw.xbm deleted file mode 100755 index a684d65..0000000 --- a/Demo/tix/bitmaps/netw.xbm +++ /dev/null @@ -1,14 +0,0 @@ -#define netw_width 32 -#define netw_height 32 -static unsigned char netw_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x02, 0x40, - 0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x52, - 0x00, 0x00, 0x0a, 0x52, 0x00, 0x00, 0x8a, 0x51, 0x00, 0x00, 0x0a, 0x50, - 0x00, 0x00, 0x4a, 0x50, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x50, - 0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x02, 0x40, 0xfe, 0x7f, 0x52, 0x55, - 0x02, 0x40, 0xaa, 0x6a, 0xfa, 0x5f, 0xfe, 0x7f, 0x0a, 0x50, 0xfe, 0x7f, - 0x0a, 0x52, 0x80, 0x00, 0x0a, 0x52, 0x80, 0x00, 0x8a, 0x51, 0x80, 0x00, - 0x0a, 0x50, 0x80, 0x00, 0x4a, 0x50, 0x80, 0x00, 0x0a, 0x50, 0xe0, 0x03, - 0x0a, 0x50, 0x20, 0x02, 0xfa, 0xdf, 0x3f, 0x03, 0x02, 0x40, 0xa0, 0x02, - 0x52, 0x55, 0xe0, 0x03, 0xaa, 0x6a, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, - 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/Demo/tix/bitmaps/netw.xpm b/Demo/tix/bitmaps/netw.xpm deleted file mode 100755 index fff6593..0000000 --- a/Demo/tix/bitmaps/netw.xpm +++ /dev/null @@ -1,45 +0,0 @@ -/* XPM */ -static char * netw_xpm[] = { -/* width height ncolors chars_per_pixel */ -"32 32 7 1", -/* colors */ -" s None c None", -". c #000000000000", -"X c white", -"o c #c000c000c000", -"O c #404040", -"+ c blue", -"@ c red", -/* pixels */ -" ", -" .............. ", -" .XXXXXXXXXXXX. ", -" .XooooooooooO. ", -" .Xo.......XoO. ", -" .Xo.++++o+XoO. ", -" .Xo.++++o+XoO. ", -" .Xo.++oo++XoO. ", -" .Xo.++++++XoO. ", -" .Xo.+o++++XoO. ", -" .Xo.++++++XoO. ", -" .Xo.XXXXXXXoO. ", -" .XooooooooooO. ", -" .Xo@ooo....oO. ", -" .............. .XooooooooooO. ", -" .XXXXXXXXXXXX. .XooooooooooO. ", -" .XooooooooooO. .OOOOOOOOOOOO. ", -" .Xo.......XoO. .............. ", -" .Xo.++++o+XoO. @ ", -" .Xo.++++o+XoO. @ ", -" .Xo.++oo++XoO. @ ", -" .Xo.++++++XoO. @ ", -" .Xo.+o++++XoO. @ ", -" .Xo.++++++XoO. ..... ", -" .Xo.XXXXXXXoO. .XXX. ", -" .XooooooooooO.@@@@@@.X O. ", -" .Xo@ooo....oO. .OOO. ", -" .XooooooooooO. ..... ", -" .XooooooooooO. ", -" .OOOOOOOOOOOO. ", -" .............. ", -" "}; diff --git a/Demo/tix/bitmaps/optmenu.xpm b/Demo/tix/bitmaps/optmenu.xpm deleted file mode 100755 index 63bab81..0000000 --- a/Demo/tix/bitmaps/optmenu.xpm +++ /dev/null @@ -1,48 +0,0 @@ -/* XPM */ -static char * optmenu_xpm[] = { -"50 40 5 1", -" s None c None", -". c white", -"X c gray80", -"o c gray50", -"O c black", -" ", -" ", -" .............................. ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXOXOXXOXXOXXXXOOXXXXXXXXXXo ", -" .XXXOXOXXOXOXXXOXXOXXXXXXXXXXo ", -" .XXXXOXXOXXOXXXOXXXOXXXXXXXXXo ", -" .XXXXOXXXOXXOOXXOXOXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo.............o ", -" .............................o o ", -" ..XXXOXXXXXOXXXXXXXXOXXXXXXXOo o ", -" ..XXOXOXOXXOXOXXXOXXOXXXXXXXOo ...... o ", -" ..XXXOXXXOXXOXXXOXXXOXXXXXXXOo . o o ", -" ..XXOXXXOXXXOXOXXOXXOXXXXXXXOo . o o ", -" ..XXXXXXXXXXXXXXXXXXXXXXXXXXOo .ooooo o ", -" .OOOOOOOOOOOOOOOOOOOOOOOOOOOOo o ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo o ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXooooooooooooooo ", -" .XXXXOXXXXXOXXXXXXXXXXXXXXXXXo ", -" .XXXOXXXXXXXXXOXXXXXXXXXXXXXXo ", -" .XXXXOXXOXXOXOXOXXXXXXXXXXXXXo ", -" .XXXXXOXXOXOXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXOXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXOXOXXXXXXXOXOXXXXXOXXXXXXo ", -" .XXXXXOXOXOXXOXXXXXOXXOXXXXXXo ", -" .XXXXOXXOXOXOXXXOXOXOXXOXXXXXo ", -" .XXXOXXXXOXXOXXXOXXOXXXXOXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" .XXXXXXXXXXXXXXXXXXXXXXXXXXXXo ", -" oooooooooooooooooooooooooooooo ", -" ", -" ", -" ", -" "}; diff --git a/Demo/tix/bitmaps/rightj.xbm b/Demo/tix/bitmaps/rightj.xbm deleted file mode 100755 index 1d438e0..0000000 --- a/Demo/tix/bitmaps/rightj.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define rightj_width 16 -#define rightj_height 16 -static unsigned char rightj_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xdb, 0x00, 0x00, 0x70, 0xdb, - 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0xd8, 0xde, 0x00, 0x00, 0xc0, 0xdd, - 0x00, 0x00, 0xa0, 0xef, 0x00, 0x00, 0xd8, 0xde}; diff --git a/Demo/tix/bitmaps/select.xpm b/Demo/tix/bitmaps/select.xpm deleted file mode 100755 index 392e5a0..0000000 --- a/Demo/tix/bitmaps/select.xpm +++ /dev/null @@ -1,52 +0,0 @@ -/* XPM */ -static char * select_xpm[] = { -"50 40 9 1", -" s None c None", -". c black", -"X c gray95", -"o c gray50", -"O c gray70", -"+ c navy", -"@ c #000080800000", -"# c #808000000000", -"$ c white", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" .............................................. ", -" .XXXXXXXXXXooooooooooooXXXXXXXXXXXoXXXXXXXXXX. ", -" .X ooOOOOOOOOOOXX oX o. ", -" .X ooOOOOOOOOOOXX oX o. ", -" .X ++++ ooOOOOOOOOOOXX ... oX @ o. ", -" .X +++++ ooOOOOOOOOOOXX . . oX @@@ o. ", -" .X +++ + ooOOOOOOOOOOXX . . oX @ @ o. ", -" .X + + ooOO#####OOOXX . . oX @ @ o. ", -" .X + + ooOO#OOO##OOXX . oX @ @ o. ", -" .X + + ooO##OOOO##OXX . oX @ @ o. ", -" .X ++ ++ ooO###OOO#OOXX . oX @ @ o. ", -" .X +++++++ ooO#######OOXX . oX @ @ o. ", -" .X + + ooO##O#OO#OOXX . oX @ @ o. ", -" .X + ++ ooO##OOOOO#OXX . . oX @ @ o. ", -" .X + + ooOO#OOOOO#OXX . . oX @ @@ o. ", -" .X + ++ ooOO#OOOOO#OXX .... oX @@@@@ o. ", -" .X ooOO######OOXX oX o. ", -" .X ooOOOOOOOOOOXX $oX o. ", -" .XoooooooooooXXXXXXXXXXXoooooooooooXooooooooo. ", -" .............................................. ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" "}; diff --git a/Demo/tix/bitmaps/tix.gif b/Demo/tix/bitmaps/tix.gif deleted file mode 100755 index e7d51a0..0000000 Binary files a/Demo/tix/bitmaps/tix.gif and /dev/null differ diff --git a/Demo/tix/bitmaps/underline.xbm b/Demo/tix/bitmaps/underline.xbm deleted file mode 100755 index f07bb46..0000000 --- a/Demo/tix/bitmaps/underline.xbm +++ /dev/null @@ -1,6 +0,0 @@ -#define underline_width 16 -#define underline_height 16 -static unsigned char underline_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1c, 0x38, 0x1c, - 0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x30, 0x0c, 0x70, 0x0e, - 0xf0, 0x0f, 0xe0, 0x07, 0x00, 0x00, 0xf8, 0x1f}; diff --git a/Demo/tix/grid.py b/Demo/tix/grid.py deleted file mode 100644 index 4268f07..0000000 --- a/Demo/tix/grid.py +++ /dev/null @@ -1,28 +0,0 @@ -### -import tkinter.tix as tk -from pprint import pprint - -r= tk.Tk() -r.title("test") - -l=tk.Label(r, name="a_label") -l.pack() - -class MyGrid(tk.Grid): - def __init__(self, *args, **kwargs): - kwargs['editnotify']= self.editnotify - tk.Grid.__init__(self, *args, **kwargs) - def editnotify(self, x, y): - return True - -g = MyGrid(r, name="a_grid", -selectunit="cell") -g.pack(fill=tk.BOTH) -for x in range(5): - for y in range(5): - g.set(x,y,text=str((x,y))) - -c = tk.Button(r, text="Close", command=r.destroy) -c.pack() - -tk.mainloop() diff --git a/Demo/tix/samples/Balloon.py b/Demo/tix/samples/Balloon.py deleted file mode 100644 index bc25a2e..0000000 --- a/Demo/tix/samples/Balloon.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates the use of the tixBalloon widget, which provides -# a interesting way to give help tips about elements in your user interface. -# Your can display the help message in a "balloon" and a status bar widget. -# - -import tkinter.tix - -TCL_ALL_EVENTS = 0 - -def RunSample (root): - balloon = DemoBalloon(root) - balloon.mainloop() - balloon.destroy() - -class DemoBalloon: - def __init__(self, w): - self.root = w - self.exit = -1 - - z = w.winfo_toplevel() - z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd()) - - status = tkinter.tix.Label(w, width=40, relief=tkinter.tix.SUNKEN, bd=1) - status.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.Y, padx=2, pady=1) - - # Create two mysterious widgets that need balloon help - button1 = tkinter.tix.Button(w, text='Something Unexpected', - command=self.quitcmd) - button2 = tkinter.tix.Button(w, text='Something Else Unexpected') - button2['command'] = lambda w=button2: w.destroy() - button1.pack(side=tkinter.tix.TOP, expand=1) - button2.pack(side=tkinter.tix.TOP, expand=1) - - # Create the balloon widget and associate it with the widgets that we want - # to provide tips for: - b = tkinter.tix.Balloon(w, statusbar=status) - - b.bind_widget(button1, balloonmsg='Close Window', - statusmsg='Press this button to close this window') - b.bind_widget(button2, balloonmsg='Self-destruct button', - statusmsg='Press this button and it will destroy itself') - - def quitcmd (self): - self.exit = 0 - - def mainloop(self): - foundEvent = 1 - while self.exit < 0 and foundEvent > 0: - foundEvent = self.root.tk.dooneevent(TCL_ALL_EVENTS) - - def destroy (self): - self.root.destroy() - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) diff --git a/Demo/tix/samples/BtnBox.py b/Demo/tix/samples/BtnBox.py deleted file mode 100644 index 3b9ee4b..0000000 --- a/Demo/tix/samples/BtnBox.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates the use of the tixButtonBox widget, which is a -# group of TK buttons. You can use it to manage the buttons in a dialog box, -# for example. -# - -import tkinter.tix - -def RunSample(w): - # Create the label on the top of the dialog box - # - top = tkinter.tix.Label(w, padx=20, pady=10, bd=1, relief=tkinter.tix.RAISED, - anchor=tkinter.tix.CENTER, text='This dialog box is\n a demonstration of the\n tixButtonBox widget') - - # Create the button box and add a few buttons in it. Set the - # -width of all the buttons to the same value so that they - # appear in the same size. - # - # Note that the -text, -underline, -command and -width options are all - # standard options of the button widgets. - # - box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL) - box.add('ok', text='OK', underline=0, width=5, - command=lambda w=w: w.destroy()) - box.add('close', text='Cancel', underline=0, width=5, - command=lambda w=w: w.destroy()) - box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1) - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) - root.mainloop() diff --git a/Demo/tix/samples/CmpImg.py b/Demo/tix/samples/CmpImg.py deleted file mode 100644 index ad49181..0000000 --- a/Demo/tix/samples/CmpImg.py +++ /dev/null @@ -1,196 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates the use of the compound images: it uses compound -# images to display a text string together with a pixmap inside -# buttons -# - -import tkinter.tix - -network_pixmap = """/* XPM */ -static char * netw_xpm[] = { -/* width height ncolors chars_per_pixel */ -"32 32 7 1", -/* colors */ -" s None c None", -". c #000000000000", -"X c white", -"o c #c000c000c000", -"O c #404040", -"+ c blue", -"@ c red", -/* pixels */ -" ", -" .............. ", -" .XXXXXXXXXXXX. ", -" .XooooooooooO. ", -" .Xo.......XoO. ", -" .Xo.++++o+XoO. ", -" .Xo.++++o+XoO. ", -" .Xo.++oo++XoO. ", -" .Xo.++++++XoO. ", -" .Xo.+o++++XoO. ", -" .Xo.++++++XoO. ", -" .Xo.XXXXXXXoO. ", -" .XooooooooooO. ", -" .Xo@ooo....oO. ", -" .............. .XooooooooooO. ", -" .XXXXXXXXXXXX. .XooooooooooO. ", -" .XooooooooooO. .OOOOOOOOOOOO. ", -" .Xo.......XoO. .............. ", -" .Xo.++++o+XoO. @ ", -" .Xo.++++o+XoO. @ ", -" .Xo.++oo++XoO. @ ", -" .Xo.++++++XoO. @ ", -" .Xo.+o++++XoO. @ ", -" .Xo.++++++XoO. ..... ", -" .Xo.XXXXXXXoO. .XXX. ", -" .XooooooooooO.@@@@@@.X O. ", -" .Xo@ooo....oO. .OOO. ", -" .XooooooooooO. ..... ", -" .XooooooooooO. ", -" .OOOOOOOOOOOO. ", -" .............. ", -" "}; -""" - -hard_disk_pixmap = """/* XPM */ -static char * drivea_xpm[] = { -/* width height ncolors chars_per_pixel */ -"32 32 5 1", -/* colors */ -" s None c None", -". c #000000000000", -"X c white", -"o c #c000c000c000", -"O c #800080008000", -/* pixels */ -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" .......................... ", -" .XXXXXXXXXXXXXXXXXXXXXXXo. ", -" .XooooooooooooooooooooooO. ", -" .Xooooooooooooooooo..oooO. ", -" .Xooooooooooooooooo..oooO. ", -" .XooooooooooooooooooooooO. ", -" .Xoooooooo.......oooooooO. ", -" .Xoo...................oO. ", -" .Xoooooooo.......oooooooO. ", -" .XooooooooooooooooooooooO. ", -" .XooooooooooooooooooooooO. ", -" .XooooooooooooooooooooooO. ", -" .XooooooooooooooooooooooO. ", -" .oOOOOOOOOOOOOOOOOOOOOOOO. ", -" .......................... ", -" ", -" ", -" ", -" ", -" ", -" ", -" ", -" "}; -""" - -network_bitmap = """ -#define netw_width 32 -#define netw_height 32 -static unsigned char netw_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x02, 0x40, - 0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x52, - 0x00, 0x00, 0x0a, 0x52, 0x00, 0x00, 0x8a, 0x51, 0x00, 0x00, 0x0a, 0x50, - 0x00, 0x00, 0x4a, 0x50, 0x00, 0x00, 0x0a, 0x50, 0x00, 0x00, 0x0a, 0x50, - 0x00, 0x00, 0xfa, 0x5f, 0x00, 0x00, 0x02, 0x40, 0xfe, 0x7f, 0x52, 0x55, - 0x02, 0x40, 0xaa, 0x6a, 0xfa, 0x5f, 0xfe, 0x7f, 0x0a, 0x50, 0xfe, 0x7f, - 0x0a, 0x52, 0x80, 0x00, 0x0a, 0x52, 0x80, 0x00, 0x8a, 0x51, 0x80, 0x00, - 0x0a, 0x50, 0x80, 0x00, 0x4a, 0x50, 0x80, 0x00, 0x0a, 0x50, 0xe0, 0x03, - 0x0a, 0x50, 0x20, 0x02, 0xfa, 0xdf, 0x3f, 0x03, 0x02, 0x40, 0xa0, 0x02, - 0x52, 0x55, 0xe0, 0x03, 0xaa, 0x6a, 0x00, 0x00, 0xfe, 0x7f, 0x00, 0x00, - 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -""" - -hard_disk_bitmap = """ -#define drivea_width 32 -#define drivea_height 32 -static unsigned char drivea_bits[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf8, 0xff, 0xff, 0x1f, 0x08, 0x00, 0x00, 0x18, 0xa8, 0xaa, 0xaa, 0x1a, - 0x48, 0x55, 0xd5, 0x1d, 0xa8, 0xaa, 0xaa, 0x1b, 0x48, 0x55, 0x55, 0x1d, - 0xa8, 0xfa, 0xaf, 0x1a, 0xc8, 0xff, 0xff, 0x1d, 0xa8, 0xfa, 0xaf, 0x1a, - 0x48, 0x55, 0x55, 0x1d, 0xa8, 0xaa, 0xaa, 0x1a, 0x48, 0x55, 0x55, 0x1d, - 0xa8, 0xaa, 0xaa, 0x1a, 0xf8, 0xff, 0xff, 0x1f, 0xf8, 0xff, 0xff, 0x1f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; -""" - -def RunSample(w): - w.img0 = tkinter.tix.Image('pixmap', data=network_pixmap) - if not w.img0: - w.img0 = tkinter.tix.Image('bitmap', data=network_bitmap) - w.img1 = tkinter.tix.Image('pixmap', data=hard_disk_pixmap) - if not w.img0: - w.img1 = tkinter.tix.Image('bitmap', data=hard_disk_bitmap) - - hdd = tkinter.tix.Button(w, padx=4, pady=1, width=120) - net = tkinter.tix.Button(w, padx=4, pady=1, width=120) - - # Create the first image: we create a line, then put a string, - # a space and a image into this line, from left to right. - # The result: we have a one-line image that consists of three - # individual items - # - # The tk.calls should be methods in Tix ... - w.hdd_img = tkinter.tix.Image('compound', window=hdd) - w.hdd_img.tk.call(str(w.hdd_img), 'add', 'line') - w.hdd_img.tk.call(str(w.hdd_img), 'add', 'text', '-text', 'Hard Disk', - '-underline', '0') - w.hdd_img.tk.call(str(w.hdd_img), 'add', 'space', '-width', '7') - w.hdd_img.tk.call(str(w.hdd_img), 'add', 'image', '-image', w.img1) - - # Put this image into the first button - # - hdd['image'] = w.hdd_img - - # Next button - w.net_img = tkinter.tix.Image('compound', window=net) - w.net_img.tk.call(str(w.net_img), 'add', 'line') - w.net_img.tk.call(str(w.net_img), 'add', 'text', '-text', 'Network', - '-underline', '0') - w.net_img.tk.call(str(w.net_img), 'add', 'space', '-width', '7') - w.net_img.tk.call(str(w.net_img), 'add', 'image', '-image', w.img0) - - # Put this image into the first button - # - net['image'] = w.net_img - - close = tkinter.tix.Button(w, pady=1, text='Close', - command=lambda w=w: w.destroy()) - - hdd.pack(side=tkinter.tix.LEFT, padx=10, pady=10, fill=tkinter.tix.Y, expand=1) - net.pack(side=tkinter.tix.LEFT, padx=10, pady=10, fill=tkinter.tix.Y, expand=1) - close.pack(side=tkinter.tix.LEFT, padx=10, pady=10, fill=tkinter.tix.Y, expand=1) - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) - root.mainloop() diff --git a/Demo/tix/samples/ComboBox.py b/Demo/tix/samples/ComboBox.py deleted file mode 100644 index 80d78f2..0000000 --- a/Demo/tix/samples/ComboBox.py +++ /dev/null @@ -1,102 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates the use of the tixComboBox widget, which is close -# to the MS Window Combo Box control. -# -import tkinter.tix - -def RunSample(w): - global demo_month, demo_year - - top = tkinter.tix.Frame(w, bd=1, relief=tkinter.tix.RAISED) - - demo_month = tkinter.tix.StringVar() - demo_year = tkinter.tix.StringVar() - - # $w.top.a is a drop-down combo box. It is not editable -- who wants - # to invent new months? - # - # [Hint] The -options switch sets the options of the subwidgets. - # [Hint] We set the label.width subwidget option of both comboboxes to - # be 10 so that their labels appear to be aligned. - # - a = tkinter.tix.ComboBox(top, label="Month: ", dropdown=1, - command=select_month, editable=0, variable=demo_month, - options='listbox.height 6 label.width 10 label.anchor e') - - # $w.top.b is a non-drop-down combo box. It is not editable: we provide - # four choices for the user, but he can enter an alternative year if he - # wants to. - # - # [Hint] Use the padY and anchor options of the label subwidget to - # align the label with the entry subwidget. - # [Hint] Notice that you should use padY (the NAME of the option) and not - # pady (the SWITCH of the option). - # - b = tkinter.tix.ComboBox(top, label="Year: ", dropdown=0, - command=select_year, editable=1, variable=demo_year, - options='listbox.height 4 label.padY 5 label.width 10 label.anchor ne') - - a.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W) - b.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W) - - a.insert(tkinter.tix.END, 'January') - a.insert(tkinter.tix.END, 'February') - a.insert(tkinter.tix.END, 'March') - a.insert(tkinter.tix.END, 'April') - a.insert(tkinter.tix.END, 'May') - a.insert(tkinter.tix.END, 'June') - a.insert(tkinter.tix.END, 'July') - a.insert(tkinter.tix.END, 'August') - a.insert(tkinter.tix.END, 'September') - a.insert(tkinter.tix.END, 'October') - a.insert(tkinter.tix.END, 'November') - a.insert(tkinter.tix.END, 'December') - - b.insert(tkinter.tix.END, '1992') - b.insert(tkinter.tix.END, '1993') - b.insert(tkinter.tix.END, '1994') - b.insert(tkinter.tix.END, '1995') - b.insert(tkinter.tix.END, '1996') - - # Use "tixSetSilent" to set the values of the combo box if you - # don't want your -command procedures (cbx:select_month and - # cbx:select_year) to be called. - # - a.set_silent('January') - b.set_silent('1995') - - box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL) - box.add('ok', text='Ok', underline=0, width=6, - command=lambda w=w: ok_command(w)) - box.add('cancel', text='Cancel', underline=0, width=6, - command=lambda w=w: w.destroy()) - box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1) - -def select_month(event=None): - # tixDemo:Status "Month = %s" % demo_month.get() - pass - -def select_year(event=None): - # tixDemo:Status "Year = %s" % demo_year.get() - pass - -def ok_command(w): - # tixDemo:Status "Month = %s, Year= %s" % (demo_month.get(), demo_year.get()) - w.destroy() - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) - root.mainloop() diff --git a/Demo/tix/samples/Control.py b/Demo/tix/samples/Control.py deleted file mode 100644 index fbc5e64..0000000 --- a/Demo/tix/samples/Control.py +++ /dev/null @@ -1,122 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates the use of the tixControl widget -- it is an -# entry widget with up/down arrow buttons. You can use the arrow buttons -# to adjust the value inside the entry widget. -# -# This example program uses three Control widgets. One lets you select -# integer values; one lets you select floating point values and the last -# one lets you select a few names. - -import tkinter.tix - -TCL_ALL_EVENTS = 0 - -def RunSample (root): - control = DemoControl(root) - control.mainloop() - control.destroy() - -class DemoControl: - def __init__(self, w): - self.root = w - self.exit = -1 - - global demo_maker, demo_thrust, demo_num_engines - - demo_maker = tkinter.tix.StringVar() - demo_thrust = tkinter.tix.DoubleVar() - demo_num_engines = tkinter.tix.IntVar() - demo_maker.set('P&W') - demo_thrust.set(20000.0) - demo_num_engines.set(2) - - top = tkinter.tix.Frame(w, bd=1, relief=tkinter.tix.RAISED) - - # $w.top.a allows only integer values - # - # [Hint] The -options switch sets the options of the subwidgets. - # [Hint] We set the label.width subwidget option of the Controls to - # be 16 so that their labels appear to be aligned. - # - a = tkinter.tix.Control(top, label='Number of Engines: ', integer=1, - variable=demo_num_engines, min=1, max=4, - options='entry.width 10 label.width 20 label.anchor e') - - b = tkinter.tix.Control(top, label='Thrust: ', integer=0, - min='10000.0', max='60000.0', step=500, - variable=demo_thrust, - options='entry.width 10 label.width 20 label.anchor e') - - c = tkinter.tix.Control(top, label='Engine Maker: ', value='P&W', - variable=demo_maker, - options='entry.width 10 label.width 20 label.anchor e') - - # We can't define these in the init because the widget 'c' doesn't - # exist yet and we need to reference it - c['incrcmd'] = lambda w=c: adjust_maker(w, 1) - c['decrcmd'] = lambda w=c: adjust_maker(w, -1) - c['validatecmd'] = lambda w=c: validate_maker(w) - - a.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W) - b.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W) - c.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W) - - box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL) - box.add('ok', text='Ok', underline=0, width=6, - command=self.okcmd) - box.add('cancel', text='Cancel', underline=0, width=6, - command=self.quitcmd) - box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1) - - def okcmd (self): - # tixDemo:Status "Selected %d of %s engines each of thrust %d", (demo_num_engines.get(), demo_maker.get(), demo_thrust.get()) - self.quitcmd() - - def quitcmd (self): - self.exit = 0 - - def mainloop(self): - while self.exit < 0: - self.root.tk.dooneevent(TCL_ALL_EVENTS) - - def destroy (self): - self.root.destroy() - -maker_list = ['P&W', 'GE', 'Rolls Royce'] - -def adjust_maker(w, inc): - i = maker_list.index(demo_maker.get()) - i = i + inc - if i >= len(maker_list): - i = 0 - elif i < 0: - i = len(maker_list) - 1 - - # In Tcl/Tix we should return the string maker_list[i]. We can't - # do that in Tkinter so we set the global variable. (This works). - demo_maker.set(maker_list[i]) - -def validate_maker(w): - try: - i = maker_list.index(demo_maker.get()) - except ValueError: - # Works here though. Why ? Beats me. - return maker_list[0] - # Works here though. Why ? Beats me. - return maker_list[i] - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) diff --git a/Demo/tix/samples/DirList.py b/Demo/tix/samples/DirList.py deleted file mode 100644 index 6d28ca3..0000000 --- a/Demo/tix/samples/DirList.py +++ /dev/null @@ -1,131 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program using tixwish. - -# This file demonstrates the use of the tixDirList widget -- you can -# use it for the user to select a directory. For example, an installation -# program can use the tixDirList widget to ask the user to select the -# installation directory for an application. -# - -import tkinter.tix, os, copy -from tkinter.constants import * - -TCL_ALL_EVENTS = 0 - -def RunSample (root): - dirlist = DemoDirList(root) - dirlist.mainloop() - dirlist.destroy() - -class DemoDirList: - def __init__(self, w): - self.root = w - self.exit = -1 - - z = w.winfo_toplevel() - z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd()) - - # Create the tixDirList and the tixLabelEntry widgets on the on the top - # of the dialog box - - # bg = root.tk.eval('tix option get bg') - # adding bg=bg crashes Windows pythonw tk8.3.3 Python 2.1.0 - - top = tkinter.tix.Frame( w, relief=RAISED, bd=1) - - # Create the DirList widget. By default it will show the current - # directory - # - # - top.dir = tkinter.tix.DirList(top) - top.dir.hlist['width'] = 40 - - # When the user presses the ".." button, the selected directory - # is "transferred" into the entry widget - # - top.btn = tkinter.tix.Button(top, text = " >> ", pady = 0) - - # We use a LabelEntry to hold the installation directory. The user - # can choose from the DirList widget, or he can type in the directory - # manually - # - top.ent = tkinter.tix.LabelEntry(top, label="Installation Directory:", - labelside = 'top', - options = ''' - entry.width 40 - label.anchor w - ''') - - font = self.root.tk.eval('tix option get fixed_font') - # font = self.root.master.tix_option_get('fixed_font') - top.ent.entry['font'] = font - - self.dlist_dir = copy.copy(os.curdir) - # This should work setting the entry's textvariable - top.ent.entry['textvariable'] = self.dlist_dir - top.btn['command'] = lambda dir=top.dir, ent=top.ent, self=self: \ - self.copy_name(dir,ent) - - # top.ent.entry.insert(0,'tix'+repr(self)) - top.ent.entry.bind('', lambda self=self: self.okcmd () ) - - top.pack( expand='yes', fill='both', side=TOP) - top.dir.pack( expand=1, fill=BOTH, padx=4, pady=4, side=LEFT) - top.btn.pack( anchor='s', padx=4, pady=4, side=LEFT) - top.ent.pack( expand=1, fill=X, anchor='s', padx=4, pady=4, side=LEFT) - - # Use a ButtonBox to hold the buttons. - # - box = tkinter.tix.ButtonBox (w, orientation='horizontal') - box.add ('ok', text='Ok', underline=0, width=6, - command = lambda self=self: self.okcmd () ) - box.add ('cancel', text='Cancel', underline=0, width=6, - command = lambda self=self: self.quitcmd () ) - - box.pack( anchor='s', fill='x', side=BOTTOM) - - def copy_name (self, dir, ent): - # This should work as it is the entry's textvariable - self.dlist_dir = dir.cget('value') - # but it isn't so I'll do it manually - ent.entry.delete(0,'end') - ent.entry.insert(0, self.dlist_dir) - - def okcmd (self): - # tixDemo:Status "You have selected the directory" + self.dlist_dir - self.quitcmd() - - def quitcmd (self): - self.exit = 0 - - def mainloop(self): - while self.exit < 0: - self.root.tk.dooneevent(TCL_ALL_EVENTS) - - def destroy (self): - self.root.destroy() - -# This "if" statement makes it possible to run this script file inside or -# outside of the main demo program "tixwidgets.py". -# -if __name__== '__main__' : - import tkinter.messagebox, traceback - - try: - root=tkinter.tix.Tk() - RunSample(root) - except: - t, v, tb = sys.exc_info() - text = "Error running the demo script:\n" - for line in traceback.format_exception(t,v,tb): - text = text + line + '\n' - d = tkinter.messagebox.showerror ( 'Tix Demo Error', text) diff --git a/Demo/tix/samples/DirTree.py b/Demo/tix/samples/DirTree.py deleted file mode 100644 index 5411ded..0000000 --- a/Demo/tix/samples/DirTree.py +++ /dev/null @@ -1,117 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program using tixwish. - -# This file demonstrates the use of the tixDirTree widget -- you can -# use it for the user to select a directory. For example, an installation -# program can use the tixDirTree widget to ask the user to select the -# installation directory for an application. -# - -import tkinter.tix, os, copy -from tkinter.constants import * - -TCL_ALL_EVENTS = 0 - -def RunSample (root): - dirtree = DemoDirTree(root) - dirtree.mainloop() - dirtree.destroy() - -class DemoDirTree: - def __init__(self, w): - self.root = w - self.exit = -1 - - z = w.winfo_toplevel() - z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd()) - - # Create the tixDirTree and the tixLabelEntry widgets on the on the top - # of the dialog box - - # bg = root.tk.eval('tix option get bg') - # adding bg=bg crashes Windows pythonw tk8.3.3 Python 2.1.0 - - top = tkinter.tix.Frame( w, relief=RAISED, bd=1) - - # Create the DirTree widget. By default it will show the current - # directory - # - # - top.dir = tkinter.tix.DirTree(top) - top.dir.hlist['width'] = 40 - - # When the user presses the ".." button, the selected directory - # is "transferred" into the entry widget - # - top.btn = tkinter.tix.Button(top, text = " >> ", pady = 0) - - # We use a LabelEntry to hold the installation directory. The user - # can choose from the DirTree widget, or he can type in the directory - # manually - # - top.ent = tkinter.tix.LabelEntry(top, label="Installation Directory:", - labelside = 'top', - options = ''' - entry.width 40 - label.anchor w - ''') - - self.dlist_dir = copy.copy(os.curdir) - top.ent.entry['textvariable'] = self.dlist_dir - top.btn['command'] = lambda dir=top.dir, ent=top.ent, self=self: \ - self.copy_name(dir,ent) - - top.ent.entry.bind('', lambda self=self: self.okcmd () ) - - top.pack( expand='yes', fill='both', side=TOP) - top.dir.pack( expand=1, fill=BOTH, padx=4, pady=4, side=LEFT) - top.btn.pack( anchor='s', padx=4, pady=4, side=LEFT) - top.ent.pack( expand=1, fill=X, anchor='s', padx=4, pady=4, side=LEFT) - - # Use a ButtonBox to hold the buttons. - # - box = tkinter.tix.ButtonBox (w, orientation='horizontal') - box.add ('ok', text='Ok', underline=0, width=6, - command = lambda self=self: self.okcmd () ) - box.add ('cancel', text='Cancel', underline=0, width=6, - command = lambda self=self: self.quitcmd () ) - - box.pack( anchor='s', fill='x', side=BOTTOM) - - def copy_name (self, dir, ent): - # This should work as it is the entry's textvariable - self.dlist_dir = dir.cget('value') - # but it isn't so I'll do it manually - ent.entry.delete(0,'end') - ent.entry.insert(0, self.dlist_dir) - - def okcmd (self): - # tixDemo:Status "You have selected the directory" + self.dlist_dir - self.quitcmd() - - def quitcmd (self): - # tixDemo:Status "You have selected the directory" + self.dlist_dir - self.exit = 0 - - def mainloop(self): - while self.exit < 0: - self.root.tk.dooneevent(TCL_ALL_EVENTS) - - def destroy (self): - self.root.destroy() - -# This "if" statement makes it possible to run this script file inside or -# outside of the main demo program "tixwidgets.py". -# -if __name__== '__main__' : - root=tkinter.tix.Tk() - RunSample(root) diff --git a/Demo/tix/samples/NoteBook.py b/Demo/tix/samples/NoteBook.py deleted file mode 100644 index d8b5fa8..0000000 --- a/Demo/tix/samples/NoteBook.py +++ /dev/null @@ -1,119 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates the use of the tixNoteBook widget, which allows -# you to lay out your interface using a "notebook" metaphore -# -import tkinter.tix - -def RunSample(w): - global root - root = w - - # We use these options to set the sizes of the subwidgets inside the - # notebook, so that they are well-aligned on the screen. - prefix = tkinter.tix.OptionName(w) - if prefix: - prefix = '*'+prefix - else: - prefix = '' - w.option_add(prefix+'*TixControl*entry.width', 10) - w.option_add(prefix+'*TixControl*label.width', 18) - w.option_add(prefix+'*TixControl*label.anchor', tkinter.tix.E) - w.option_add(prefix+'*TixNoteBook*tagPadX', 8) - - # Create the notebook widget and set its backpagecolor to gray. - # Note that the -backpagecolor option belongs to the "nbframe" - # subwidget. - nb = tkinter.tix.NoteBook(w, name='nb', ipadx=6, ipady=6) - nb['bg'] = 'gray' - nb.nbframe['backpagecolor'] = 'gray' - - # Create the two tabs on the notebook. The -underline option - # puts a underline on the first character of the labels of the tabs. - # Keyboard accelerators will be defined automatically according - # to the underlined character. - nb.add('hard_disk', label="Hard Disk", underline=0) - nb.add('network', label="Network", underline=0) - - nb.pack(expand=1, fill=tkinter.tix.BOTH, padx=5, pady=5 ,side=tkinter.tix.TOP) - - #---------------------------------------- - # Create the first page - #---------------------------------------- - # Create two frames: one for the common buttons, one for the - # other widgets - # - tab=nb.hard_disk - f = tkinter.tix.Frame(tab) - common = tkinter.tix.Frame(tab) - - f.pack(side=tkinter.tix.LEFT, padx=2, pady=2, fill=tkinter.tix.BOTH, expand=1) - common.pack(side=tkinter.tix.RIGHT, padx=2, fill=tkinter.tix.Y) - - a = tkinter.tix.Control(f, value=12, label='Access time: ') - w = tkinter.tix.Control(f, value=400, label='Write Throughput: ') - r = tkinter.tix.Control(f, value=400, label='Read Throughput: ') - c = tkinter.tix.Control(f, value=1021, label='Capacity: ') - - a.pack(side=tkinter.tix.TOP, padx=20, pady=2) - w.pack(side=tkinter.tix.TOP, padx=20, pady=2) - r.pack(side=tkinter.tix.TOP, padx=20, pady=2) - c.pack(side=tkinter.tix.TOP, padx=20, pady=2) - - # Create the common buttons - createCommonButtons(common) - - #---------------------------------------- - # Create the second page - #---------------------------------------- - - tab = nb.network - - f = tkinter.tix.Frame(tab) - common = tkinter.tix.Frame(tab) - - f.pack(side=tkinter.tix.LEFT, padx=2, pady=2, fill=tkinter.tix.BOTH, expand=1) - common.pack(side=tkinter.tix.RIGHT, padx=2, fill=tkinter.tix.Y) - - a = tkinter.tix.Control(f, value=12, label='Access time: ') - w = tkinter.tix.Control(f, value=400, label='Write Throughput: ') - r = tkinter.tix.Control(f, value=400, label='Read Throughput: ') - c = tkinter.tix.Control(f, value=1021, label='Capacity: ') - u = tkinter.tix.Control(f, value=10, label='Users: ') - - a.pack(side=tkinter.tix.TOP, padx=20, pady=2) - w.pack(side=tkinter.tix.TOP, padx=20, pady=2) - r.pack(side=tkinter.tix.TOP, padx=20, pady=2) - c.pack(side=tkinter.tix.TOP, padx=20, pady=2) - u.pack(side=tkinter.tix.TOP, padx=20, pady=2) - - createCommonButtons(common) - -def doDestroy(): - global root - root.destroy() - -def createCommonButtons(master): - ok = tkinter.tix.Button(master, name='ok', text='OK', width=6, - command=doDestroy) - cancel = tkinter.tix.Button(master, name='cancel', - text='Cancel', width=6, - command=doDestroy) - - ok.pack(side=tkinter.tix.TOP, padx=2, pady=2) - cancel.pack(side=tkinter.tix.TOP, padx=2, pady=2) - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) - root.mainloop() diff --git a/Demo/tix/samples/OptMenu.py b/Demo/tix/samples/OptMenu.py deleted file mode 100644 index d1dd46d..0000000 --- a/Demo/tix/samples/OptMenu.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates the use of the tixOptionMenu widget -- you can -# use it for the user to choose from a fixed set of options -# -import tkinter.tix - -options = {'text':'Plain Text', 'post':'PostScript', 'html':'HTML', - 'tex':'LaTeX', 'rtf':'Rich Text Format'} - -def RunSample(w): - global demo_opt_from, demo_opt_to - - demo_opt_from = tkinter.tix.StringVar() - demo_opt_to = tkinter.tix.StringVar() - - top = tkinter.tix.Frame(w, bd=1, relief=tkinter.tix.RAISED) - - from_file = tkinter.tix.OptionMenu(top, label="From File Format : ", - variable=demo_opt_from, - options = 'label.width 19 label.anchor e menubutton.width 15') - - to_file = tkinter.tix.OptionMenu(top, label="To File Format : ", - variable=demo_opt_to, - options='label.width 19 label.anchor e menubutton.width 15') - - # Add the available options to the two OptionMenu widgets - # - # [Hint] You have to add the options first before you set the - # global variables "demo_opt_from" and "demo_opt_to". Otherwise - # the OptionMenu widget will complain about "unknown options"! - # - for opt in options.keys(): - from_file.add_command(opt, label=options[opt]) - to_file.add_command(opt, label=options[opt]) - - demo_opt_from.set('html') - demo_opt_to.set('post') - - from_file.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W, pady=3, padx=6) - to_file.pack(side=tkinter.tix.TOP, anchor=tkinter.tix.W, pady=3, padx=6) - - box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL) - box.add('ok', text='Ok', underline=0, width=6, - command=lambda w=w: ok_command(w)) - box.add('cancel', text='Cancel', underline=0, width=6, - command=lambda w=w: w.destroy()) - box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1) - -def ok_command(w): - # tixDemo:Status "Convert file from %s to %s" % ( demo_opt_from.get(), demo_opt_to.get()) - w.destroy() - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) - root.mainloop() diff --git a/Demo/tix/samples/PanedWin.py b/Demo/tix/samples/PanedWin.py deleted file mode 100644 index 1ffc470..0000000 --- a/Demo/tix/samples/PanedWin.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates the use of the tixPanedWindow widget. This program -# is a dummy news reader: the user can adjust the sizes of the list -# of artical names and the size of the text widget that shows the body -# of the article. - -import tkinter.tix - -TCL_ALL_EVENTS = 0 - -def RunSample (root): - panedwin = DemoPanedwin(root) - panedwin.mainloop() - panedwin.destroy() - -class DemoPanedwin: - def __init__(self, w): - self.root = w - self.exit = -1 - - z = w.winfo_toplevel() - z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd()) - - group = tkinter.tix.LabelEntry(w, label='Newsgroup:', options='entry.width 25') - group.entry.insert(0,'comp.lang.python') - pane = tkinter.tix.PanedWindow(w, orientation='vertical') - - p1 = pane.add('list', min=70, size=100) - p2 = pane.add('text', min=70) - list = tkinter.tix.ScrolledListBox(p1) - list.listbox['width'] = 80 - list.listbox['height'] = 5 - text = tkinter.tix.ScrolledText(p2) - text.text['width'] = 80 - text.text['height'] = 20 - - list.listbox.insert(tkinter.tix.END, " 12324 Re: Tkinter is good for your health") - list.listbox.insert(tkinter.tix.END, "+ 12325 Re: Tkinter is good for your health") - list.listbox.insert(tkinter.tix.END, "+ 12326 Re: Tix is even better for your health (Was: Tkinter is good...)") - list.listbox.insert(tkinter.tix.END, " 12327 Re: Tix is even better for your health (Was: Tkinter is good...)") - list.listbox.insert(tkinter.tix.END, "+ 12328 Re: Tix is even better for your health (Was: Tkinter is good...)") - list.listbox.insert(tkinter.tix.END, " 12329 Re: Tix is even better for your health (Was: Tkinter is good...)") - list.listbox.insert(tkinter.tix.END, "+ 12330 Re: Tix is even better for your health (Was: Tkinter is good...)") - - text.text['bg'] = list.listbox['bg'] - text.text['wrap'] = 'none' - text.text.insert(tkinter.tix.END, """ - Mon, 19 Jun 1995 11:39:52 comp.lang.python Thread 34 of 220 - Lines 353 A new way to put text and bitmaps together iNo responses - ioi@blue.seas.upenn.edu Ioi K. Lam at University of Pennsylvania - - Hi, - - I have implemented a new image type called "compound". It allows you - to glue together a bunch of bitmaps, images and text strings together - to form a bigger image. Then you can use this image with widgets that - support the -image option. For example, you can display a text string string - together with a bitmap, at the same time, inside a TK button widget. - """) - text.text['state'] = 'disabled' - - list.pack(expand=1, fill=tkinter.tix.BOTH, padx=4, pady=6) - text.pack(expand=1, fill=tkinter.tix.BOTH, padx=4, pady=6) - - group.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH) - pane.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH, expand=1) - - box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL) - box.add('ok', text='Ok', underline=0, width=6, - command=self.quitcmd) - box.add('cancel', text='Cancel', underline=0, width=6, - command=self.quitcmd) - box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - - def quitcmd (self): - self.exit = 0 - - def mainloop(self): - while self.exit < 0: - self.root.tk.dooneevent(TCL_ALL_EVENTS) - - def destroy (self): - self.root.destroy() - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) diff --git a/Demo/tix/samples/PopMenu.py b/Demo/tix/samples/PopMenu.py deleted file mode 100644 index cb75d85..0000000 --- a/Demo/tix/samples/PopMenu.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program using tixwish. - -# This file demonstrates the use of the tixPopupMenu widget. -# -import tkinter.tix - -def RunSample(w): - # We create the frame and the button, then we'll bind the PopupMenu - # to both widgets. The result is, when you press the right mouse - # button over $w.top or $w.top.but, the PopupMenu will come up. - # - top = tkinter.tix.Frame(w, relief=tkinter.tix.RAISED, bd=1) - but = tkinter.tix.Button(top, text='Press the right mouse button over this button or its surrounding area') - but.pack(expand=1, fill=tkinter.tix.BOTH, padx=50, pady=50) - - p = tkinter.tix.PopupMenu(top, title='Popup Test') - p.bind_widget(top) - p.bind_widget(but) - - # Set the entries inside the PopupMenu widget. - # [Hint] You have to manipulate the "menu" subwidget. - # $w.top.p itself is NOT a menu widget. - # [Hint] Watch carefully how the sub-menu is created - # - p.menu.add_command(label='Desktop', underline=0) - p.menu.add_command(label='Select', underline=0) - p.menu.add_command(label='Find', underline=0) - p.menu.add_command(label='System', underline=1) - p.menu.add_command(label='Help', underline=0) - m1 = tkinter.tix.Menu(p.menu) - m1.add_command(label='Hello') - p.menu.add_cascade(label='More', menu=m1) - - but.pack(side=tkinter.tix.TOP, padx=40, pady=50) - - box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL) - box.add('ok', text='Ok', underline=0, width=6, - command=lambda w=w: w.destroy()) - box.add('cancel', text='Cancel', underline=0, width=6, - command=lambda w=w: w.destroy()) - box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1) - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) - root.mainloop() diff --git a/Demo/tix/samples/SHList1.py b/Demo/tix/samples/SHList1.py deleted file mode 100644 index bf46020..0000000 --- a/Demo/tix/samples/SHList1.py +++ /dev/null @@ -1,131 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program using tixwish. - -# This file demonstrates the use of the tixScrolledHList widget. -# - -import tkinter.tix - -TCL_ALL_EVENTS = 0 - -def RunSample (root): - shlist = DemoSHList(root) - shlist.mainloop() - shlist.destroy() - -class DemoSHList: - def __init__(self, w): - self.root = w - self.exit = -1 - - z = w.winfo_toplevel() - z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd()) - - # We create the frame and the ScrolledHList widget - # at the top of the dialog box - # - top = tkinter.tix.Frame( w, relief=tkinter.tix.RAISED, bd=1) - - # Put a simple hierachy into the HList (two levels). Use colors and - # separator widgets (frames) to make the list look fancy - # - top.a = tkinter.tix.ScrolledHList(top) - top.a.pack( expand=1, fill=tkinter.tix.BOTH, padx=10, pady=10, side=tkinter.tix.TOP) - - # This is our little relational database - # - bosses = [ - ('jeff', 'Jeff Waxman'), - ('john', 'John Lee'), - ('peter', 'Peter Kenson') - ] - - employees = [ - ('alex', 'john', 'Alex Kellman'), - ('alan', 'john', 'Alan Adams'), - ('andy', 'peter', 'Andreas Crawford'), - ('doug', 'jeff', 'Douglas Bloom'), - ('jon', 'peter', 'Jon Baraki'), - ('chris', 'jeff', 'Chris Geoffrey'), - ('chuck', 'jeff', 'Chuck McLean') - ] - - hlist=top.a.hlist - - # Let configure the appearance of the HList subwidget - # - hlist.config( separator='.', width=25, drawbranch=0, indent=10) - - count=0 - for boss,name in bosses : - if count : - f=tkinter.tix.Frame(hlist, name='sep%d' % count, height=2, width=150, - bd=2, relief=tkinter.tix.SUNKEN ) - - hlist.add_child( itemtype=tkinter.tix.WINDOW, - window=f, state=tkinter.tix.DISABLED ) - - hlist.add(boss, itemtype=tkinter.tix.TEXT, text=name) - count = count+1 - - - for person,boss,name in employees : - # '.' is the separator character we chose above - # - key= boss + '.' + person - # ^^^^ ^^^^^^ - # parent entryPath / child's name - - hlist.add( key, text=name ) - - # [Hint] Make sure the keys (e.g. 'boss.person') you choose - # are unique names. If you cannot be sure of this (because of - # the structure of your database, e.g.) you can use the - # "add_child" command instead: - # - # hlist.addchild( boss, text=name) - # ^^^^ - # parent entryPath - - - # Use a ButtonBox to hold the buttons. - # - box= tkinter.tix.ButtonBox(top, orientation=tkinter.tix.HORIZONTAL ) - box.add( 'ok', text='Ok', underline=0, width=6, - command = self.okcmd) - - box.add( 'cancel', text='Cancel', underline=0, width=6, - command = self.quitcmd) - - box.pack( side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - top.pack( side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1 ) - - def okcmd (self): - self.quitcmd() - - def quitcmd (self): - self.exit = 0 - - def mainloop(self): - while self.exit < 0: - self.root.tk.dooneevent(TCL_ALL_EVENTS) - - def destroy (self): - self.root.destroy() - - -# This "if" statement makes it possible to run this script file inside or -# outside of the main demo program "tixwidgets.py". -# -if __name__== '__main__' : - root=tkinter.tix.Tk() - RunSample(root) diff --git a/Demo/tix/samples/SHList2.py b/Demo/tix/samples/SHList2.py deleted file mode 100644 index 370c765..0000000 --- a/Demo/tix/samples/SHList2.py +++ /dev/null @@ -1,168 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidget": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program using tixwish. - -# This file demonstrates how to use multiple columns and multiple styles -# in the tixHList widget -# -# In a tixHList widget, you can have one ore more columns. -# - -import tkinter.tix - -TCL_ALL_EVENTS = 0 - -def RunSample (root): - shlist = DemoSHList(root) - shlist.mainloop() - shlist.destroy() - -class DemoSHList: - def __init__(self, w): - self.root = w - self.exit = -1 - - z = w.winfo_toplevel() - z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd()) - - # We create the frame and the ScrolledHList widget - # at the top of the dialog box - # - top = tkinter.tix.Frame( w, relief=tkinter.tix.RAISED, bd=1) - - # Put a simple hierachy into the HList (two levels). Use colors and - # separator widgets (frames) to make the list look fancy - # - top.a = tkinter.tix.ScrolledHList(top, options='hlist.columns 3 hlist.header 1' ) - top.a.pack( expand=1, fill=tkinter.tix.BOTH, padx=10, pady=10, side=tkinter.tix.TOP) - - hlist=top.a.hlist - - # Create the title for the HList widget - # >> Notice that we have set the hlist.header subwidget option to true - # so that the header is displayed - # - - boldfont=hlist.tk.call('tix','option','get','bold_font') - - # First some styles for the headers - style={} - style['header'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, refwindow=hlist, - anchor=tkinter.tix.CENTER, padx=8, pady=2, font = boldfont ) - - hlist.header_create(0, itemtype=tkinter.tix.TEXT, text='Name', - style=style['header']) - hlist.header_create(1, itemtype=tkinter.tix.TEXT, text='Position', - style=style['header']) - - # Notice that we use 3 columns in the hlist widget. This way when the user - # expands the windows wide, the right side of the header doesn't look - # chopped off. The following line ensures that the 3 column header is - # not shown unless the hlist window is wider than its contents. - # - hlist.column_width(2,0) - - # This is our little relational database - # - boss = ('doe', 'John Doe', 'Director') - - managers = [ - ('jeff', 'Jeff Waxman', 'Manager'), - ('john', 'John Lee', 'Manager'), - ('peter', 'Peter Kenson', 'Manager') - ] - - employees = [ - ('alex', 'john', 'Alex Kellman', 'Clerk'), - ('alan', 'john', 'Alan Adams', 'Clerk'), - ('andy', 'peter', 'Andreas Crawford', 'Salesman'), - ('doug', 'jeff', 'Douglas Bloom', 'Clerk'), - ('jon', 'peter', 'Jon Baraki', 'Salesman'), - ('chris', 'jeff', 'Chris Geoffrey', 'Clerk'), - ('chuck', 'jeff', 'Chuck McLean', 'Cleaner') - ] - - style['mgr_name'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, refwindow=hlist) - - style['mgr_posn'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, padx=8, refwindow=hlist) - - style['empl_name'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, refwindow=hlist) - - style['empl_posn'] = tkinter.tix.DisplayStyle(tkinter.tix.TEXT, padx=8, refwindow=hlist) - - # Let configure the appearance of the HList subwidget - # - hlist.config(separator='.', width=25, drawbranch=0, indent=10) - hlist.column_width(0, chars=20) - - # Create the boss - # - hlist.add ('.', itemtype=tkinter.tix.TEXT, text=boss[1], - style=style['mgr_name']) - hlist.item_create('.', 1, itemtype=tkinter.tix.TEXT, text=boss[2], - style=style['mgr_posn']) - - # Create the managers - # - - for key,name,posn in managers : - e= '.'+ key - hlist.add(e, itemtype=tkinter.tix.TEXT, text=name, - style=style['mgr_name']) - hlist.item_create(e, 1, itemtype=tkinter.tix.TEXT, text=posn, - style=style['mgr_posn']) - - - for key,mgr,name,posn in employees : - # "." is the separator character we chose above - - entrypath = '.' + mgr + '.' + key - - # ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ - # parent entryPath / child's name - - hlist.add(entrypath, text=name, style=style['empl_name']) - hlist.item_create(entrypath, 1, itemtype=tkinter.tix.TEXT, - text = posn, style = style['empl_posn'] ) - - - # Use a ButtonBox to hold the buttons. - # - box= tkinter.tix.ButtonBox(top, orientation=tkinter.tix.HORIZONTAL ) - box.add( 'ok', text='Ok', underline=0, width=6, - command = self.okcmd ) - - box.add( 'cancel', text='Cancel', underline=0, width=6, - command = self.quitcmd ) - - box.pack( side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - top.pack( side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1 ) - - def okcmd (self): - self.quitcmd() - - def quitcmd (self): - self.exit = 0 - - def mainloop(self): - while self.exit < 0: - self.root.tk.dooneevent(TCL_ALL_EVENTS) - - def destroy (self): - self.root.destroy() - - -# This "if" statement makes it possible to run this script file inside or -# outside of the main demo program "tixwidgets.py". -# -if __name__== '__main__' : - root=tkinter.tix.Tk() - RunSample(root) diff --git a/Demo/tix/samples/Tree.py b/Demo/tix/samples/Tree.py deleted file mode 100644 index e46ff60..0000000 --- a/Demo/tix/samples/Tree.py +++ /dev/null @@ -1,80 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# Tix Demostration Program -# -# This sample program is structured in such a way so that it can be -# executed from the Tix demo program "tixwidgets.py": it must have a -# procedure called "RunSample". It should also have the "if" statment -# at the end of this file so that it can be run as a standalone -# program. - -# This file demonstrates how to use the TixTree widget to display -# dynamic hierachical data (the files in the Unix file system) -# - -import tkinter.tix, os - -def RunSample(w): - top = tkinter.tix.Frame(w, relief=tkinter.tix.RAISED, bd=1) - tree = tkinter.tix.Tree(top, options='separator "/"') - tree.pack(expand=1, fill=tkinter.tix.BOTH, padx=10, pady=10, side=tkinter.tix.LEFT) - tree['opencmd'] = lambda dir=None, w=tree: opendir(w, dir) - - # The / directory is added in the "open" mode. The user can open it - # and then browse its subdirectories ... - adddir(tree, "/") - - box = tkinter.tix.ButtonBox(w, orientation=tkinter.tix.HORIZONTAL) - box.add('ok', text='Ok', underline=0, command=w.destroy, width=6) - box.add('cancel', text='Cancel', underline=0, command=w.destroy, width=6) - box.pack(side=tkinter.tix.BOTTOM, fill=tkinter.tix.X) - top.pack(side=tkinter.tix.TOP, fill=tkinter.tix.BOTH, expand=1) - -def adddir(tree, dir): - if dir == '/': - text = '/' - else: - text = os.path.basename(dir) - tree.hlist.add(dir, itemtype=tkinter.tix.IMAGETEXT, text=text, - image=tree.tk.call('tix', 'getimage', 'folder')) - try: - os.listdir(dir) - tree.setmode(dir, 'open') - except os.error: - # No read permission ? - pass - -# This function is called whenever the user presses the (+) indicator or -# double clicks on a directory whose mode is "open". It loads the files -# inside that directory into the Tree widget. -# -# Note we didn't specify the closecmd option for the Tree widget, so it -# performs the default action when the user presses the (-) indicator or -# double clicks on a directory whose mode is "close": hide all of its child -# entries -def opendir(tree, dir): - entries = tree.hlist.info_children(dir) - if entries: - # We have already loaded this directory. Let's just - # show all the child entries - # - # Note: since we load the directory only once, it will not be - # refreshed if the you add or remove files from this - # directory. - # - for entry in entries: - tree.hlist.show_entry(entry) - files = os.listdir(dir) - for file in files: - if os.path.isdir(dir + '/' + file): - adddir(tree, dir + '/' + file) - else: - tree.hlist.add(dir + '/' + file, itemtype=tkinter.tix.IMAGETEXT, text=file, - image=tree.tk.call('tix', 'getimage', 'file')) - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunSample(root) - root.mainloop() diff --git a/Demo/tix/tixwidgets.py b/Demo/tix/tixwidgets.py deleted file mode 100644 index 42bcedc..0000000 --- a/Demo/tix/tixwidgets.py +++ /dev/null @@ -1,1002 +0,0 @@ -# -*-mode: python; fill-column: 75; tab-width: 8; coding: iso-latin-1-unix -*- -# -# $Id$ -# -# tixwidgets.py -- -# -# For Tix, see http://tix.sourceforge.net -# -# This is a demo program of some of the Tix widgets available in Python. -# If you have installed Python & Tix properly, you can execute this as -# -# % python tixwidgets.py -# - -import os, os.path, sys, tkinter.tix -from tkinter.constants import * -import traceback, tkinter.messagebox - -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 - -class Demo: - def __init__(self, top): - self.root = top - self.exit = -1 - - self.dir = None # script directory - self.balloon = None # balloon widget - self.useBalloons = tkinter.tix.StringVar() - self.useBalloons.set('0') - self.statusbar = None # status bar widget - self.welmsg = None # Msg widget - self.welfont = '' # font name - self.welsize = '' # font size - - progname = sys.argv[0] - dirname = os.path.dirname(progname) - if dirname and dirname != os.curdir: - self.dir = dirname - index = -1 - for i in range(len(sys.path)): - p = sys.path[i] - if p in ("", os.curdir): - index = i - if index >= 0: - sys.path[index] = dirname - else: - sys.path.insert(0, dirname) - else: - self.dir = os.getcwd() - sys.path.insert(0, self.dir+'/samples') - - def MkMainMenu(self): - top = self.root - w = tkinter.tix.Frame(top, bd=2, relief=RAISED) - file = tkinter.tix.Menubutton(w, text='File', underline=0, takefocus=0) - help = tkinter.tix.Menubutton(w, text='Help', underline=0, takefocus=0) - file.pack(side=LEFT) - help.pack(side=RIGHT) - fm = tkinter.tix.Menu(file, tearoff=0) - file['menu'] = fm - hm = tkinter.tix.Menu(help, tearoff=0) - help['menu'] = hm - - fm.add_command(label='Exit', underline=1, - command = lambda self=self: self.quitcmd () ) - hm.add_checkbutton(label='BalloonHelp', underline=0, command=ToggleHelp, - variable=self.useBalloons) - # The trace variable option doesn't seem to work, instead I use 'command' - #w.tk.call('trace', 'variable', self.useBalloons, 'w', ToggleHelp)) - - return w - - def MkMainNotebook(self): - top = self.root - w = tkinter.tix.NoteBook(top, ipadx=5, ipady=5, options=""" - tagPadX 6 - tagPadY 4 - borderWidth 2 - """) - # This may be required if there is no *Background option - top['bg'] = w['bg'] - - w.add('wel', label='Welcome', underline=0, - createcmd=lambda w=w, name='wel': MkWelcome(w, name)) - w.add('cho', label='Choosers', underline=0, - createcmd=lambda w=w, name='cho': MkChoosers(w, name)) - w.add('scr', label='Scrolled Widgets', underline=0, - createcmd=lambda w=w, name='scr': MkScroll(w, name)) - w.add('mgr', label='Manager Widgets', underline=0, - createcmd=lambda w=w, name='mgr': MkManager(w, name)) - w.add('dir', label='Directory List', underline=0, - createcmd=lambda w=w, name='dir': MkDirList(w, name)) - w.add('exp', label='Run Sample Programs', underline=0, - createcmd=lambda w=w, name='exp': MkSample(w, name)) - return w - - def MkMainStatus(self): - global demo - top = self.root - - w = tkinter.tix.Frame(top, relief=tkinter.tix.RAISED, bd=1) - demo.statusbar = tkinter.tix.Label(w, relief=tkinter.tix.SUNKEN, bd=1) - demo.statusbar.form(padx=3, pady=3, left=0, right='%70') - return w - - def build(self): - root = self.root - z = root.winfo_toplevel() - z.wm_title('Tix Widget Demonstration') - if z.winfo_screenwidth() <= 800: - z.geometry('790x590+10+10') - else: - z.geometry('890x640+10+10') - demo.balloon = tkinter.tix.Balloon(root) - frame1 = self.MkMainMenu() - frame2 = self.MkMainNotebook() - frame3 = self.MkMainStatus() - frame1.pack(side=TOP, fill=X) - frame3.pack(side=BOTTOM, fill=X) - frame2.pack(side=TOP, expand=1, fill=BOTH, padx=4, pady=4) - demo.balloon['statusbar'] = demo.statusbar - z.wm_protocol("WM_DELETE_WINDOW", lambda self=self: self.quitcmd()) - - # To show Tcl errors - uncomment this to see the listbox bug. - # Tkinter defines a Tcl tkerror procedure that in effect - # silences all background Tcl error reporting. - # root.tk.eval('if {[info commands tkerror] != ""} {rename tkerror pytkerror}') - def quitcmd (self): - """Quit our mainloop. It is up to you to call root.destroy() after.""" - self.exit = 0 - - def loop(self): - """This is an explict replacement for _tkinter mainloop() - It lets you catch keyboard interrupts easier, and avoids - the 20 msec. dead sleep() which burns a constant CPU.""" - while self.exit < 0: - # There are 2 whiles here. The outer one lets you continue - # after a ^C interrupt. - try: - # This is the replacement for _tkinter mainloop() - # It blocks waiting for the next Tcl event using select. - while self.exit < 0: - self.root.tk.dooneevent(TCL_ALL_EVENTS) - except SystemExit: - # Tkinter uses SystemExit to exit - #print 'Exit' - self.exit = 1 - return - except KeyboardInterrupt: - if tkinter.messagebox.askquestion ('Interrupt', 'Really Quit?') == 'yes': - # self.tk.eval('exit') - self.exit = 1 - return - continue - except: - # Otherwise it's some other error - be nice and say why - t, v, tb = sys.exc_info() - text = "" - for line in traceback.format_exception(t,v,tb): - text += line + '\n' - try: tkinter.messagebox.showerror ('Error', text) - except: pass - self.exit = 1 - raise SystemExit(1) - - def destroy (self): - self.root.destroy() - -def RunMain(root): - global demo - - demo = Demo(root) - - demo.build() - demo.loop() - demo.destroy() - -# Tabs -def MkWelcome(nb, name): - w = nb.page(name) - bar = MkWelcomeBar(w) - text = MkWelcomeText(w) - bar.pack(side=TOP, fill=X, padx=2, pady=2) - text.pack(side=TOP, fill=BOTH, expand=1) - -def MkWelcomeBar(top): - global demo - - w = tkinter.tix.Frame(top, bd=2, relief=tkinter.tix.GROOVE) - b1 = tkinter.tix.ComboBox(w, command=lambda w=top: MainTextFont(w)) - b2 = tkinter.tix.ComboBox(w, command=lambda w=top: MainTextFont(w)) - b1.entry['width'] = 15 - b1.slistbox.listbox['height'] = 3 - b2.entry['width'] = 4 - b2.slistbox.listbox['height'] = 3 - - demo.welfont = b1 - demo.welsize = b2 - - b1.insert(tkinter.tix.END, 'Courier') - b1.insert(tkinter.tix.END, 'Helvetica') - b1.insert(tkinter.tix.END, 'Lucida') - b1.insert(tkinter.tix.END, 'Times Roman') - - b2.insert(tkinter.tix.END, '8') - b2.insert(tkinter.tix.END, '10') - b2.insert(tkinter.tix.END, '12') - b2.insert(tkinter.tix.END, '14') - b2.insert(tkinter.tix.END, '18') - - b1.pick(1) - b2.pick(3) - - b1.pack(side=tkinter.tix.LEFT, padx=4, pady=4) - b2.pack(side=tkinter.tix.LEFT, padx=4, pady=4) - - demo.balloon.bind_widget(b1, msg='Choose\na font', - statusmsg='Choose a font for this page') - demo.balloon.bind_widget(b2, msg='Point size', - statusmsg='Choose the font size for this page') - return w - -def MkWelcomeText(top): - global demo - - w = tkinter.tix.ScrolledWindow(top, scrollbar='auto') - win = w.window - text = 'Welcome to TIX in Python' - title = tkinter.tix.Label(win, - bd=0, width=30, anchor=tkinter.tix.N, text=text) - msg = tkinter.tix.Message(win, - bd=0, width=400, anchor=tkinter.tix.N, - text='Tix is a set of mega-widgets based on TK. This program \ -demonstrates the widgets in the Tix widget set. You can choose the pages \ -in this window to look at the corresponding widgets. \n\n\ -To quit this program, choose the "File | Exit" command.\n\n\ -For more information, see http://tix.sourceforge.net.') - title.pack(expand=1, fill=tkinter.tix.BOTH, padx=10, pady=10) - msg.pack(expand=1, fill=tkinter.tix.BOTH, padx=10, pady=10) - demo.welmsg = msg - return w - -def MainTextFont(w): - global demo - - if not demo.welmsg: - return - font = demo.welfont['value'] - point = demo.welsize['value'] - if font == 'Times Roman': - font = 'times' - fontstr = '%s %s' % (font, point) - demo.welmsg['font'] = fontstr - -def ToggleHelp(): - if demo.useBalloons.get() == '1': - demo.balloon['state'] = 'both' - else: - demo.balloon['state'] = 'none' - -def MkChoosers(nb, name): - w = nb.page(name) - options = "label.padX 4" - - til = tkinter.tix.LabelFrame(w, label='Chooser Widgets', options=options) - cbx = tkinter.tix.LabelFrame(w, label='tixComboBox', options=options) - ctl = tkinter.tix.LabelFrame(w, label='tixControl', options=options) - sel = tkinter.tix.LabelFrame(w, label='tixSelect', options=options) - opt = tkinter.tix.LabelFrame(w, label='tixOptionMenu', options=options) - fil = tkinter.tix.LabelFrame(w, label='tixFileEntry', options=options) - fbx = tkinter.tix.LabelFrame(w, label='tixFileSelectBox', options=options) - tbr = tkinter.tix.LabelFrame(w, label='Tool Bar', options=options) - - MkTitle(til.frame) - MkCombo(cbx.frame) - MkControl(ctl.frame) - MkSelect(sel.frame) - MkOptMenu(opt.frame) - MkFileEnt(fil.frame) - MkFileBox(fbx.frame) - MkToolBar(tbr.frame) - - # First column: comBox and selector - cbx.form(top=0, left=0, right='%33') - sel.form(left=0, right='&'+str(cbx), top=cbx) - opt.form(left=0, right='&'+str(cbx), top=sel, bottom=-1) - - # Second column: title .. etc - til.form(left=cbx, top=0,right='%66') - ctl.form(left=cbx, right='&'+str(til), top=til) - fil.form(left=cbx, right='&'+str(til), top=ctl) - tbr.form(left=cbx, right='&'+str(til), top=fil, bottom=-1) - - # - # Third column: file selection - fbx.form(right=-1, top=0, left='%66') - -def MkCombo(w): - options="label.width %d label.anchor %s entry.width %d" % (10, tkinter.tix.E, 14) - - static = tkinter.tix.ComboBox(w, label='Static', editable=0, options=options) - editable = tkinter.tix.ComboBox(w, label='Editable', editable=1, options=options) - history = tkinter.tix.ComboBox(w, label='History', editable=1, history=1, - anchor=tkinter.tix.E, options=options) - static.insert(tkinter.tix.END, 'January') - static.insert(tkinter.tix.END, 'February') - static.insert(tkinter.tix.END, 'March') - static.insert(tkinter.tix.END, 'April') - static.insert(tkinter.tix.END, 'May') - static.insert(tkinter.tix.END, 'June') - static.insert(tkinter.tix.END, 'July') - static.insert(tkinter.tix.END, 'August') - static.insert(tkinter.tix.END, 'September') - static.insert(tkinter.tix.END, 'October') - static.insert(tkinter.tix.END, 'November') - static.insert(tkinter.tix.END, 'December') - - editable.insert(tkinter.tix.END, 'Angola') - editable.insert(tkinter.tix.END, 'Bangladesh') - editable.insert(tkinter.tix.END, 'China') - editable.insert(tkinter.tix.END, 'Denmark') - editable.insert(tkinter.tix.END, 'Ecuador') - - history.insert(tkinter.tix.END, '/usr/bin/ksh') - history.insert(tkinter.tix.END, '/usr/local/lib/python') - history.insert(tkinter.tix.END, '/var/adm') - - static.pack(side=tkinter.tix.TOP, padx=5, pady=3) - editable.pack(side=tkinter.tix.TOP, padx=5, pady=3) - history.pack(side=tkinter.tix.TOP, padx=5, pady=3) - -states = ['Bengal', 'Delhi', 'Karnataka', 'Tamil Nadu'] - -def spin_cmd(w, inc): - idx = states.index(demo_spintxt.get()) + inc - if idx < 0: - idx = len(states) - 1 - elif idx >= len(states): - idx = 0 -# following doesn't work. -# return states[idx] - demo_spintxt.set(states[idx]) # this works - -def spin_validate(w): - global states, demo_spintxt - - try: - i = states.index(demo_spintxt.get()) - except ValueError: - return states[0] - return states[i] - # why this procedure works as opposed to the previous one beats me. - -def MkControl(w): - global demo_spintxt - - options="label.width %d label.anchor %s entry.width %d" % (10, tkinter.tix.E, 13) - - demo_spintxt = tkinter.tix.StringVar() - demo_spintxt.set(states[0]) - simple = tkinter.tix.Control(w, label='Numbers', options=options) - spintxt = tkinter.tix.Control(w, label='States', variable=demo_spintxt, - options=options) - spintxt['incrcmd'] = lambda w=spintxt: spin_cmd(w, 1) - spintxt['decrcmd'] = lambda w=spintxt: spin_cmd(w, -1) - spintxt['validatecmd'] = lambda w=spintxt: spin_validate(w) - - simple.pack(side=tkinter.tix.TOP, padx=5, pady=3) - spintxt.pack(side=tkinter.tix.TOP, padx=5, pady=3) - -def MkSelect(w): - options = "label.anchor %s" % tkinter.tix.CENTER - - sel1 = tkinter.tix.Select(w, label='Mere Mortals', allowzero=1, radio=1, - orientation=tkinter.tix.VERTICAL, - labelside=tkinter.tix.TOP, - options=options) - sel2 = tkinter.tix.Select(w, label='Geeks', allowzero=1, radio=0, - orientation=tkinter.tix.VERTICAL, - labelside= tkinter.tix.TOP, - options=options) - - sel1.add('eat', text='Eat') - sel1.add('work', text='Work') - sel1.add('play', text='Play') - sel1.add('party', text='Party') - sel1.add('sleep', text='Sleep') - - sel2.add('eat', text='Eat') - sel2.add('prog1', text='Program') - sel2.add('prog2', text='Program') - sel2.add('prog3', text='Program') - sel2.add('sleep', text='Sleep') - - sel1.pack(side=tkinter.tix.LEFT, padx=5, pady=3, fill=tkinter.tix.X) - sel2.pack(side=tkinter.tix.LEFT, padx=5, pady=3, fill=tkinter.tix.X) - -def MkOptMenu(w): - options='menubutton.width 15 label.anchor %s' % tkinter.tix.E - - m = tkinter.tix.OptionMenu(w, label='File Format : ', options=options) - m.add_command('text', label='Plain Text') - m.add_command('post', label='PostScript') - m.add_command('format', label='Formatted Text') - m.add_command('html', label='HTML') - m.add_command('sep') - m.add_command('tex', label='LaTeX') - m.add_command('rtf', label='Rich Text Format') - - m.pack(fill=tkinter.tix.X, padx=5, pady=3) - -def MkFileEnt(w): - msg = tkinter.tix.Message(w, - relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N, - text='Press the "open file" icon button and a TixFileSelectDialog will popup.') - ent = tkinter.tix.FileEntry(w, label='Select a file : ') - msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3) - ent.pack(side=tkinter.tix.TOP, fill=tkinter.tix.X, padx=3, pady=3) - -def MkFileBox(w): - """The FileSelectBox is a Motif-style box with various enhancements. - For example, you can adjust the size of the two listboxes - and your past selections are recorded. - """ - msg = tkinter.tix.Message(w, - relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N, - text='The Tix FileSelectBox is a Motif-style box with various enhancements. For example, you can adjust the size of the two listboxes and your past selections are recorded.') - box = tkinter.tix.FileSelectBox(w) - msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3) - box.pack(side=tkinter.tix.TOP, fill=tkinter.tix.X, padx=3, pady=3) - -def MkToolBar(w): - """The Select widget is also good for arranging buttons in a tool bar. - """ - global demo - - options='frame.borderWidth 1' - - msg = tkinter.tix.Message(w, - relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N, - text='The Select widget is also good for arranging buttons in a tool bar.') - bar = tkinter.tix.Frame(w, bd=2, relief=tkinter.tix.RAISED) - font = tkinter.tix.Select(w, allowzero=1, radio=0, label='', options=options) - para = tkinter.tix.Select(w, allowzero=0, radio=1, label='', options=options) - - font.add('bold', bitmap='@' + demo.dir + '/bitmaps/bold.xbm') - font.add('italic', bitmap='@' + demo.dir + '/bitmaps/italic.xbm') - font.add('underline', bitmap='@' + demo.dir + '/bitmaps/underline.xbm') - font.add('capital', bitmap='@' + demo.dir + '/bitmaps/capital.xbm') - - para.add('left', bitmap='@' + demo.dir + '/bitmaps/leftj.xbm') - para.add('right', bitmap='@' + demo.dir + '/bitmaps/rightj.xbm') - para.add('center', bitmap='@' + demo.dir + '/bitmaps/centerj.xbm') - para.add('justify', bitmap='@' + demo.dir + '/bitmaps/justify.xbm') - - msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3) - bar.pack(side=tkinter.tix.TOP, fill=tkinter.tix.X, padx=3, pady=3) - font.pack({'in':bar}, side=tkinter.tix.LEFT, padx=3, pady=3) - para.pack({'in':bar}, side=tkinter.tix.LEFT, padx=3, pady=3) - -def MkTitle(w): - msg = tkinter.tix.Message(w, - relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N, - text='There are many types of "chooser" widgets that allow the user to input different types of information') - msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3) - -def MkScroll(nb, name): - w = nb.page(name) - options='label.padX 4' - - sls = tkinter.tix.LabelFrame(w, label='Tix.ScrolledListBox', options=options) - swn = tkinter.tix.LabelFrame(w, label='Tix.ScrolledWindow', options=options) - stx = tkinter.tix.LabelFrame(w, label='Tix.ScrolledText', options=options) - - MkSList(sls.frame) - MkSWindow(swn.frame) - MkSText(stx.frame) - - sls.form(top=0, left=0, right='%33', bottom=-1) - swn.form(top=0, left=sls, right='%66', bottom=-1) - stx.form(top=0, left=swn, right=-1, bottom=-1) - - -def MkSList(w): - """This TixScrolledListBox is configured so that it uses scrollbars - only when it is necessary. Use the handles to resize the listbox and - watch the scrollbars automatically appear and disappear. """ - top = tkinter.tix.Frame(w, width=300, height=330) - bot = tkinter.tix.Frame(w) - msg = tkinter.tix.Message(top, - relief=tkinter.tix.FLAT, width=200, anchor=tkinter.tix.N, - text='This TixScrolledListBox is configured so that it uses scrollbars only when it is necessary. Use the handles to resize the listbox and watch the scrollbars automatically appear and disappear.') - - list = tkinter.tix.ScrolledListBox(top, scrollbar='auto') - list.place(x=50, y=150, width=120, height=80) - list.listbox.insert(tkinter.tix.END, 'Alabama') - list.listbox.insert(tkinter.tix.END, 'California') - list.listbox.insert(tkinter.tix.END, 'Montana') - list.listbox.insert(tkinter.tix.END, 'New Jersey') - list.listbox.insert(tkinter.tix.END, 'New York') - list.listbox.insert(tkinter.tix.END, 'Pennsylvania') - list.listbox.insert(tkinter.tix.END, 'Washington') - - rh = tkinter.tix.ResizeHandle(top, bg='black', - relief=tkinter.tix.RAISED, - handlesize=8, gridded=1, minwidth=50, minheight=30) - btn = tkinter.tix.Button(bot, text='Reset', command=lambda w=rh, x=list: SList_reset(w,x)) - top.propagate(0) - msg.pack(fill=tkinter.tix.X) - btn.pack(anchor=tkinter.tix.CENTER) - top.pack(expand=1, fill=tkinter.tix.BOTH) - bot.pack(fill=tkinter.tix.BOTH) - list.bind('', func=lambda arg=0, rh=rh, list=list: - list.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(list))) - -def SList_reset(rh, list): - list.place(x=50, y=150, width=120, height=80) - list.update() - rh.attach_widget(list) - -def MkSWindow(w): - """The ScrolledWindow widget allows you to scroll any kind of Tk - widget. It is more versatile than a scrolled canvas widget. - """ - global demo - - text = 'The Tix ScrolledWindow widget allows you to scroll any kind of Tk widget. It is more versatile than a scrolled canvas widget.' - - file = os.path.join(demo.dir, 'bitmaps', 'tix.gif') - if not os.path.isfile(file): - text += ' (Image missing)' - - top = tkinter.tix.Frame(w, width=330, height=330) - bot = tkinter.tix.Frame(w) - msg = tkinter.tix.Message(top, - relief=tkinter.tix.FLAT, width=200, anchor=tkinter.tix.N, - text=text) - - win = tkinter.tix.ScrolledWindow(top, scrollbar='auto') - - image1 = win.window.image_create('photo', file=file) - lbl = tkinter.tix.Label(win.window, image=image1) - lbl.pack(expand=1, fill=tkinter.tix.BOTH) - - win.place(x=30, y=150, width=190, height=120) - - rh = tkinter.tix.ResizeHandle(top, bg='black', - relief=tkinter.tix.RAISED, - handlesize=8, gridded=1, minwidth=50, minheight=30) - btn = tkinter.tix.Button(bot, text='Reset', command=lambda w=rh, x=win: SWindow_reset(w,x)) - top.propagate(0) - msg.pack(fill=tkinter.tix.X) - btn.pack(anchor=tkinter.tix.CENTER) - top.pack(expand=1, fill=tkinter.tix.BOTH) - bot.pack(fill=tkinter.tix.BOTH) - - win.bind('', func=lambda arg=0, rh=rh, win=win: - win.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(win))) - -def SWindow_reset(rh, win): - win.place(x=30, y=150, width=190, height=120) - win.update() - rh.attach_widget(win) - -def MkSText(w): - """The TixScrolledWindow widget allows you to scroll any kind of Tk - widget. It is more versatile than a scrolled canvas widget.""" - top = tkinter.tix.Frame(w, width=330, height=330) - bot = tkinter.tix.Frame(w) - msg = tkinter.tix.Message(top, - relief=tkinter.tix.FLAT, width=200, anchor=tkinter.tix.N, - text='The Tix ScrolledWindow widget allows you to scroll any kind of Tk widget. It is more versatile than a scrolled canvas widget.') - - win = tkinter.tix.ScrolledText(top, scrollbar='auto') - win.text['wrap'] = 'none' - win.text.insert(tkinter.tix.END, '''When -scrollbar is set to "auto", the -scrollbars are shown only when needed. -Additional modifiers can be used to force a -scrollbar to be shown or hidden. For example, -"auto -y" means the horizontal scrollbar -should be shown when needed but the vertical -scrollbar should always be hidden; -"auto +x" means the vertical scrollbar -should be shown when needed but the horizontal -scrollbar should always be shown, and so on.''' -) - win.place(x=30, y=150, width=190, height=100) - - rh = tkinter.tix.ResizeHandle(top, bg='black', - relief=tkinter.tix.RAISED, - handlesize=8, gridded=1, minwidth=50, minheight=30) - btn = tkinter.tix.Button(bot, text='Reset', command=lambda w=rh, x=win: SText_reset(w,x)) - top.propagate(0) - msg.pack(fill=tkinter.tix.X) - btn.pack(anchor=tkinter.tix.CENTER) - top.pack(expand=1, fill=tkinter.tix.BOTH) - bot.pack(fill=tkinter.tix.BOTH) - win.bind('', func=lambda arg=0, rh=rh, win=win: - win.tk.call('tixDoWhenIdle', str(rh), 'attachwidget', str(win))) - -def SText_reset(rh, win): - win.place(x=30, y=150, width=190, height=120) - win.update() - rh.attach_widget(win) - -def MkManager(nb, name): - w = nb.page(name) - options='label.padX 4' - - pane = tkinter.tix.LabelFrame(w, label='Tix.PanedWindow', options=options) - note = tkinter.tix.LabelFrame(w, label='Tix.NoteBook', options=options) - - MkPanedWindow(pane.frame) - MkNoteBook(note.frame) - - pane.form(top=0, left=0, right=note, bottom=-1) - note.form(top=0, right=-1, bottom=-1) - -def MkPanedWindow(w): - """The PanedWindow widget allows the user to interactively manipulate - the sizes of several panes. The panes can be arranged either vertically - or horizontally. - """ - msg = tkinter.tix.Message(w, - relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N, - text='The PanedWindow widget allows the user to interactively manipulate the sizes of several panes. The panes can be arranged either vertically or horizontally.') - group = tkinter.tix.LabelEntry(w, label='Newsgroup:', options='entry.width 25') - group.entry.insert(0,'comp.lang.python') - pane = tkinter.tix.PanedWindow(w, orientation='vertical') - - p1 = pane.add('list', min=70, size=100) - p2 = pane.add('text', min=70) - list = tkinter.tix.ScrolledListBox(p1) - text = tkinter.tix.ScrolledText(p2) - - list.listbox.insert(tkinter.tix.END, " 12324 Re: Tkinter is good for your health") - list.listbox.insert(tkinter.tix.END, "+ 12325 Re: Tkinter is good for your health") - list.listbox.insert(tkinter.tix.END, "+ 12326 Re: Tix is even better for your health (Was: Tkinter is good...)") - list.listbox.insert(tkinter.tix.END, " 12327 Re: Tix is even better for your health (Was: Tkinter is good...)") - list.listbox.insert(tkinter.tix.END, "+ 12328 Re: Tix is even better for your health (Was: Tkinter is good...)") - list.listbox.insert(tkinter.tix.END, " 12329 Re: Tix is even better for your health (Was: Tkinter is good...)") - list.listbox.insert(tkinter.tix.END, "+ 12330 Re: Tix is even better for your health (Was: Tkinter is good...)") - - text.text['bg'] = list.listbox['bg'] - text.text['wrap'] = 'none' - text.text.insert(tkinter.tix.END, """ -Mon, 19 Jun 1995 11:39:52 comp.lang.python Thread 34 of 220 -Lines 353 A new way to put text and bitmaps together iNo responses -ioi@blue.seas.upenn.edu Ioi K. Lam at University of Pennsylvania - -Hi, - -I have implemented a new image type called "compound". It allows you -to glue together a bunch of bitmaps, images and text strings together -to form a bigger image. Then you can use this image with widgets that -support the -image option. For example, you can display a text string string -together with a bitmap, at the same time, inside a TK button widget. -""") - list.pack(expand=1, fill=tkinter.tix.BOTH, padx=4, pady=6) - text.pack(expand=1, fill=tkinter.tix.BOTH, padx=4, pady=6) - - msg.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH) - group.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH) - pane.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH, expand=1) - -def MkNoteBook(w): - msg = tkinter.tix.Message(w, - relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N, - text='The NoteBook widget allows you to layout a complex interface into individual pages.') - # prefix = Tix.OptionName(w) - # if not prefix: prefix = '' - # w.option_add('*' + prefix + '*TixNoteBook*tagPadX', 8) - options = "entry.width %d label.width %d label.anchor %s" % (10, 18, tkinter.tix.E) - - nb = tkinter.tix.NoteBook(w, ipadx=6, ipady=6, options=options) - nb.add('hard_disk', label="Hard Disk", underline=0) - nb.add('network', label="Network", underline=0) - - # Frame for the buttons that are present on all pages - common = tkinter.tix.Frame(nb.hard_disk) - common.pack(side=tkinter.tix.RIGHT, padx=2, pady=2, fill=tkinter.tix.Y) - CreateCommonButtons(common) - - # Widgets belonging only to this page - a = tkinter.tix.Control(nb.hard_disk, value=12, label='Access Time: ') - w = tkinter.tix.Control(nb.hard_disk, value=400, label='Write Throughput: ') - r = tkinter.tix.Control(nb.hard_disk, value=400, label='Read Throughput: ') - c = tkinter.tix.Control(nb.hard_disk, value=1021, label='Capacity: ') - a.pack(side=tkinter.tix.TOP, padx=20, pady=2) - w.pack(side=tkinter.tix.TOP, padx=20, pady=2) - r.pack(side=tkinter.tix.TOP, padx=20, pady=2) - c.pack(side=tkinter.tix.TOP, padx=20, pady=2) - - common = tkinter.tix.Frame(nb.network) - common.pack(side=tkinter.tix.RIGHT, padx=2, pady=2, fill=tkinter.tix.Y) - CreateCommonButtons(common) - - a = tkinter.tix.Control(nb.network, value=12, label='Access Time: ') - w = tkinter.tix.Control(nb.network, value=400, label='Write Throughput: ') - r = tkinter.tix.Control(nb.network, value=400, label='Read Throughput: ') - c = tkinter.tix.Control(nb.network, value=1021, label='Capacity: ') - u = tkinter.tix.Control(nb.network, value=10, label='Users: ') - a.pack(side=tkinter.tix.TOP, padx=20, pady=2) - w.pack(side=tkinter.tix.TOP, padx=20, pady=2) - r.pack(side=tkinter.tix.TOP, padx=20, pady=2) - c.pack(side=tkinter.tix.TOP, padx=20, pady=2) - u.pack(side=tkinter.tix.TOP, padx=20, pady=2) - - msg.pack(side=tkinter.tix.TOP, padx=3, pady=3, fill=tkinter.tix.BOTH) - nb.pack(side=tkinter.tix.TOP, padx=5, pady=5, fill=tkinter.tix.BOTH, expand=1) - -def CreateCommonButtons(f): - ok = tkinter.tix.Button(f, text='OK', width = 6) - cancel = tkinter.tix.Button(f, text='Cancel', width = 6) - ok.pack(side=tkinter.tix.TOP, padx=2, pady=2) - cancel.pack(side=tkinter.tix.TOP, padx=2, pady=2) - -def MkDirList(nb, name): - w = nb.page(name) - options = "label.padX 4" - - dir = tkinter.tix.LabelFrame(w, label='Tix.DirList', options=options) - fsbox = tkinter.tix.LabelFrame(w, label='Tix.ExFileSelectBox', options=options) - MkDirListWidget(dir.frame) - MkExFileWidget(fsbox.frame) - dir.form(top=0, left=0, right='%40', bottom=-1) - fsbox.form(top=0, left='%40', right=-1, bottom=-1) - -def MkDirListWidget(w): - """The TixDirList widget gives a graphical representation of the file - system directory and makes it easy for the user to choose and access - directories. - """ - msg = tkinter.tix.Message(w, - relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N, - text='The Tix DirList widget gives a graphical representation of the file system directory and makes it easy for the user to choose and access directories.') - dirlist = tkinter.tix.DirList(w, options='hlist.padY 1 hlist.width 25 hlist.height 16') - msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3) - dirlist.pack(side=tkinter.tix.TOP, padx=3, pady=3) - -def MkExFileWidget(w): - """The TixExFileSelectBox widget is more user friendly than the Motif - style FileSelectBox. """ - msg = tkinter.tix.Message(w, - relief=tkinter.tix.FLAT, width=240, anchor=tkinter.tix.N, - text='The Tix ExFileSelectBox widget is more user friendly than the Motif style FileSelectBox.') - # There's a bug in the ComboBoxes - the scrolledlistbox is destroyed - box = tkinter.tix.ExFileSelectBox(w, bd=2, relief=tkinter.tix.RAISED) - msg.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=3, pady=3) - box.pack(side=tkinter.tix.TOP, padx=3, pady=3) - -### -### List of all the demos we want to show off -comments = {'widget' : 'Widget Demos', 'image' : 'Image Demos'} -samples = {'Balloon' : 'Balloon', - 'Button Box' : 'BtnBox', - 'Combo Box' : 'ComboBox', - 'Compound Image' : 'CmpImg', - 'Directory List' : 'DirList', - 'Directory Tree' : 'DirTree', - 'Control' : 'Control', - 'Notebook' : 'NoteBook', - 'Option Menu' : 'OptMenu', - 'Paned Window' : 'PanedWin', - 'Popup Menu' : 'PopMenu', - 'ScrolledHList (1)' : 'SHList1', - 'ScrolledHList (2)' : 'SHList2', - 'Tree (dynamic)' : 'Tree' -} - -# There are still a lot of demos to be translated: -## set root { -## {d "File Selectors" file } -## {d "Hierachical ListBox" hlist } -## {d "Tabular ListBox" tlist {c tixTList}} -## {d "Grid Widget" grid {c tixGrid}} -## {d "Manager Widgets" manager } -## {d "Scrolled Widgets" scroll } -## {d "Miscellaneous Widgets" misc } -## {d "Image Types" image } -## } -## -## set image { -## {d "Compound Image" cmpimg } -## {d "XPM Image" xpm {i pixmap}} -## } -## -## set cmpimg { -##done {f "In Buttons" CmpImg.tcl } -## {f "In NoteBook" CmpImg2.tcl } -## {f "Notebook Color Tabs" CmpImg4.tcl } -## {f "Icons" CmpImg3.tcl } -## } -## -## set xpm { -## {f "In Button" Xpm.tcl {i pixmap}} -## {f "In Menu" Xpm1.tcl {i pixmap}} -## } -## -## set file { -##added {f DirList DirList.tcl } -##added {f DirTree DirTree.tcl } -## {f DirSelectDialog DirDlg.tcl } -## {f ExFileSelectDialog EFileDlg.tcl } -## {f FileSelectDialog FileDlg.tcl } -## {f FileEntry FileEnt.tcl } -## } -## -## set hlist { -## {f HList HList1.tcl } -## {f CheckList ChkList.tcl {c tixCheckList}} -##done {f "ScrolledHList (1)" SHList.tcl } -##done {f "ScrolledHList (2)" SHList2.tcl } -##done {f Tree Tree.tcl } -##done {f "Tree (Dynamic)" DynTree.tcl {v win}} -## } -## -## set tlist { -## {f "ScrolledTList (1)" STList1.tcl {c tixTList}} -## {f "ScrolledTList (2)" STList2.tcl {c tixTList}} -## } -## global tcl_platform -## # This demo hangs windows -## if {$tcl_platform(platform) != "windows"} { -##na lappend tlist {f "TList File Viewer" STList3.tcl {c tixTList}} -## } -## -## set grid { -##na {f "Simple Grid" SGrid0.tcl {c tixGrid}} -##na {f "ScrolledGrid" SGrid1.tcl {c tixGrid}} -##na {f "Editable Grid" EditGrid.tcl {c tixGrid}} -## } -## -## set scroll { -## {f ScrolledListBox SListBox.tcl } -## {f ScrolledText SText.tcl } -## {f ScrolledWindow SWindow.tcl } -##na {f "Canvas Object View" CObjView.tcl {c tixCObjView}} -## } -## -## set manager { -## {f ListNoteBook ListNBK.tcl } -##done {f NoteBook NoteBook.tcl } -##done {f PanedWindow PanedWin.tcl } -## } -## -## set misc { -##done {f Balloon Balloon.tcl } -##done {f ButtonBox BtnBox.tcl } -##done {f ComboBox ComboBox.tcl } -##done {f Control Control.tcl } -## {f LabelEntry LabEntry.tcl } -## {f LabelFrame LabFrame.tcl } -## {f Meter Meter.tcl {c tixMeter}} -##done {f OptionMenu OptMenu.tcl } -##done {f PopupMenu PopMenu.tcl } -## {f Select Select.tcl } -## {f StdButtonBox StdBBox.tcl } -## } -## - -stypes = {} -stypes['widget'] = ['Balloon', 'Button Box', 'Combo Box', 'Control', - 'Directory List', 'Directory Tree', - 'Notebook', 'Option Menu', 'Popup Menu', 'Paned Window', - 'ScrolledHList (1)', 'ScrolledHList (2)', 'Tree (dynamic)'] -stypes['image'] = ['Compound Image'] - -def MkSample(nb, name): - w = nb.page(name) - options = "label.padX 4" - - pane = tkinter.tix.PanedWindow(w, orientation='horizontal') - pane.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH) - f1 = pane.add('list', expand='1') - f2 = pane.add('text', expand='5') - f1['relief'] = 'flat' - f2['relief'] = 'flat' - - lab = tkinter.tix.LabelFrame(f1, label='Select a sample program:') - lab.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=5, pady=5) - lab1 = tkinter.tix.LabelFrame(f2, label='Source:') - lab1.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=5, pady=5) - - slb = tkinter.tix.Tree(lab.frame, options='hlist.width 20') - slb.pack(side=tkinter.tix.TOP, expand=1, fill=tkinter.tix.BOTH, padx=5) - - stext = tkinter.tix.ScrolledText(lab1.frame, name='stext') - font = root.tk.eval('tix option get fixed_font') - stext.text.config(font=font) - - frame = tkinter.tix.Frame(lab1.frame, name='frame') - - run = tkinter.tix.Button(frame, text='Run ...', name='run') - view = tkinter.tix.Button(frame, text='View Source ...', name='view') - run.pack(side=tkinter.tix.LEFT, expand=0, fill=tkinter.tix.NONE) - view.pack(side=tkinter.tix.LEFT, expand=0, fill=tkinter.tix.NONE) - - stext.text['bg'] = slb.hlist['bg'] - stext.text['state'] = 'disabled' - stext.text['wrap'] = 'none' - stext.text['width'] = 80 - - frame.pack(side=tkinter.tix.BOTTOM, expand=0, fill=tkinter.tix.X, padx=7) - stext.pack(side=tkinter.tix.TOP, expand=0, fill=tkinter.tix.BOTH, padx=7) - - slb.hlist['separator'] = '.' - slb.hlist['width'] = 25 - slb.hlist['drawbranch'] = 0 - slb.hlist['indent'] = 10 - slb.hlist['wideselect'] = 1 - slb.hlist['command'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'run') - slb.hlist['browsecmd'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'browse') - - run['command'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'run') - view['command'] = lambda args=0, w=w,slb=slb,stext=stext,run=run,view=view: Sample_Action(w, slb, stext, run, view, 'view') - - for type in ['widget', 'image']: - if type != 'widget': - x = tkinter.tix.Frame(slb.hlist, bd=2, height=2, width=150, - relief=tkinter.tix.SUNKEN, bg=slb.hlist['bg']) - slb.hlist.add_child(itemtype=tkinter.tix.WINDOW, window=x, state='disabled') - x = slb.hlist.add_child(itemtype=tkinter.tix.TEXT, state='disabled', - text=comments[type]) - for key in stypes[type]: - slb.hlist.add_child(x, itemtype=tkinter.tix.TEXT, data=key, - text=key) - slb.hlist.selection_clear() - - run['state'] = 'disabled' - view['state'] = 'disabled' - -def Sample_Action(w, slb, stext, run, view, action): - global demo - - hlist = slb.hlist - anchor = hlist.info_anchor() - if not anchor: - run['state'] = 'disabled' - view['state'] = 'disabled' - elif not hlist.info_parent(anchor): - # a comment - return - - run['state'] = 'normal' - view['state'] = 'normal' - key = hlist.info_data(anchor) - title = key - prog = samples[key] - - if action == 'run': - exec('import ' + prog) - w = tkinter.tix.Toplevel() - w.title(title) - rtn = eval(prog + '.RunSample') - rtn(w) - elif action == 'view': - w = tkinter.tix.Toplevel() - w.title('Source view: ' + title) - LoadFile(w, demo.dir + '/samples/' + prog + '.py') - elif action == 'browse': - ReadFile(stext.text, demo.dir + '/samples/' + prog + '.py') - -def LoadFile(w, fname): - global root - b = tkinter.tix.Button(w, text='Close', command=w.destroy) - t = tkinter.tix.ScrolledText(w) - # b.form(left=0, bottom=0, padx=4, pady=4) - # t.form(left=0, bottom=b, right='-0', top=0) - t.pack() - b.pack() - - font = root.tk.eval('tix option get fixed_font') - t.text.config(font=font) - t.text['bd'] = 2 - t.text['wrap'] = 'none' - - ReadFile(t.text, fname) - -def ReadFile(w, fname): - old_state = w['state'] - w['state'] = 'normal' - w.delete('0.0', tkinter.tix.END) - - try: - f = open(fname) - lines = f.readlines() - for s in lines: - w.insert(tkinter.tix.END, s) - f.close() - finally: -# w.see('1.0') - w['state'] = old_state - -if __name__ == '__main__': - root = tkinter.tix.Tk() - RunMain(root) diff --git a/Demo/tkinter/README b/Demo/tkinter/README deleted file mode 100644 index c9f18df..0000000 --- a/Demo/tkinter/README +++ /dev/null @@ -1,11 +0,0 @@ -Several collections of example code for Tkinter. - -See the toplevel README for an explanation of the difference between -Tkinter and _tkinter, how to enable the Python Tk interface, and where -to get Matt Conway's lifesaver document. - -Subdirectories: - -guido my original example set (fairly random collection) -matt Matt Conway's examples, to go with his lifesaver document -ttk Examples using the ttk module diff --git a/Demo/tkinter/guido/attr_dialog.py b/Demo/tkinter/guido/attr_dialog.py deleted file mode 100644 index 229a558..0000000 --- a/Demo/tkinter/guido/attr_dialog.py +++ /dev/null @@ -1,460 +0,0 @@ - -# The options of a widget are described by the following attributes -# of the Pack and Widget dialogs: -# -# Dialog.current: {name: value} -# -- changes during Widget's lifetime -# -# Dialog.options: {name: (default, klass)} -# -- depends on widget class only -# -# Dialog.classes: {klass: (v0, v1, v2, ...) | 'boolean' | 'other'} -# -- totally static, though different between PackDialog and WidgetDialog -# (but even that could be unified) - -from tkinter import * - - -class Option: - - varclass = StringVar # May be overridden - - def __init__(self, dialog, option): - self.dialog = dialog - self.option = option - self.master = dialog.top - self.default, self.klass = dialog.options[option] - self.var = self.varclass(self.master) - self.frame = Frame(self.master) - self.frame.pack(fill=X) - self.label = Label(self.frame, text=(option + ":")) - self.label.pack(side=LEFT) - self.update() - self.addoption() - - def refresh(self): - self.dialog.refresh() - self.update() - - def update(self): - try: - self.current = self.dialog.current[self.option] - except KeyError: - self.current = self.default - self.var.set(self.current) - - def set(self, e=None): # Should be overridden - pass - - -class BooleanOption(Option): - - varclass = BooleanVar - - def addoption(self): - self.button = Checkbutton(self.frame, - text='on/off', - onvalue=1, - offvalue=0, - variable=self.var, - relief=RAISED, - borderwidth=2, - command=self.set) - self.button.pack(side=RIGHT) - - -class EnumOption(Option): - - def addoption(self): - self.button = Menubutton(self.frame, - textvariable=self.var, - relief=RAISED, borderwidth=2) - self.button.pack(side=RIGHT) - self.menu = Menu(self.button) - self.button['menu'] = self.menu - for v in self.dialog.classes[self.klass]: - self.menu.add_radiobutton( - label=v, - variable=self.var, - value=v, - command=self.set) - - -class StringOption(Option): - - def addoption(self): - self.entry = Entry(self.frame, - textvariable=self.var, - width=10, - relief=SUNKEN, - borderwidth=2) - self.entry.pack(side=RIGHT, fill=X, expand=1) - self.entry.bind('', self.set) - - -class ReadonlyOption(Option): - - def addoption(self): - self.label = Label(self.frame, textvariable=self.var, - anchor=E) - self.label.pack(side=RIGHT) - - -class Dialog: - - def __init__(self, master): - self.master = master - self.fixclasses() - self.refresh() - self.top = Toplevel(self.master) - self.top.title(self.__class__.__name__) - self.top.minsize(1, 1) - self.addchoices() - - def refresh(self): pass # Must override - - def fixclasses(self): pass # May override - - def addchoices(self): - self.choices = {} - list = [] - for k, dc in self.options.items(): - list.append((k, dc)) - list.sort() - for k, (d, c) in list: - try: - cl = self.classes[c] - except KeyError: - cl = 'unknown' - if type(cl) is tuple: - cl = self.enumoption - elif cl == 'boolean': - cl = self.booleanoption - elif cl == 'readonly': - cl = self.readonlyoption - else: - cl = self.stringoption - self.choices[k] = cl(self, k) - - # Must override: - options = {} - classes = {} - - # May override: - booleanoption = BooleanOption - stringoption = StringOption - enumoption = EnumOption - readonlyoption = ReadonlyOption - - -class PackDialog(Dialog): - - def __init__(self, widget): - self.widget = widget - Dialog.__init__(self, widget) - - def refresh(self): - self.current = self.widget.info() - self.current['.class'] = self.widget.winfo_class() - self.current['.name'] = self.widget._w - - class packoption: # Mix-in class - def set(self, e=None): - self.current = self.var.get() - try: - self.dialog.widget.pack(**{self.option: self.current}) - except TclError as msg: - print(msg) - self.refresh() - - class booleanoption(packoption, BooleanOption): pass - class enumoption(packoption, EnumOption): pass - class stringoption(packoption, StringOption): pass - class readonlyoption(packoption, ReadonlyOption): pass - - options = { - '.class': (None, 'Class'), - '.name': (None, 'Name'), - 'after': (None, 'Widget'), - 'anchor': ('center', 'Anchor'), - 'before': (None, 'Widget'), - 'expand': ('no', 'Boolean'), - 'fill': ('none', 'Fill'), - 'in': (None, 'Widget'), - 'ipadx': (0, 'Pad'), - 'ipady': (0, 'Pad'), - 'padx': (0, 'Pad'), - 'pady': (0, 'Pad'), - 'side': ('top', 'Side'), - } - - classes = { - 'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER), - 'Boolean': 'boolean', - 'Class': 'readonly', - 'Expand': 'boolean', - 'Fill': (NONE, X, Y, BOTH), - 'Name': 'readonly', - 'Pad': 'pixel', - 'Side': (TOP, RIGHT, BOTTOM, LEFT), - 'Widget': 'readonly', - } - -class RemotePackDialog(PackDialog): - - def __init__(self, master, app, widget): - self.master = master - self.app = app - self.widget = widget - self.refresh() - self.top = Toplevel(self.master) - self.top.title(self.app + ' PackDialog') - self.top.minsize(1, 1) - self.addchoices() - - def refresh(self): - try: - words = self.master.tk.splitlist( - self.master.send(self.app, - 'pack', - 'info', - self.widget)) - except TclError as msg: - print(msg) - return - dict = {} - for i in range(0, len(words), 2): - key = words[i][1:] - value = words[i+1] - dict[key] = value - dict['.class'] = self.master.send(self.app, - 'winfo', - 'class', - self.widget) - dict['.name'] = self.widget - self.current = dict - - class remotepackoption: # Mix-in class - def set(self, e=None): - self.current = self.var.get() - try: - self.dialog.master.send( - self.dialog.app, - 'pack', - 'config', - self.dialog.widget, - '-'+self.option, - self.dialog.master.tk.merge( - self.current)) - except TclError as msg: - print(msg) - self.refresh() - - class booleanoption(remotepackoption, BooleanOption): pass - class enumoption(remotepackoption, EnumOption): pass - class stringoption(remotepackoption, StringOption): pass - class readonlyoption(remotepackoption, ReadonlyOption): pass - - -class WidgetDialog(Dialog): - - def __init__(self, widget): - self.widget = widget - self.klass = widget.winfo_class() - Dialog.__init__(self, widget) - - def fixclasses(self): - if self.klass in self.addclasses: - classes = {} - for c in (self.classes, - self.addclasses[self.klass]): - for k in c.keys(): - classes[k] = c[k] - self.classes = classes - - def refresh(self): - self.configuration = self.widget.config() - self.update() - self.current['.class'] = self.widget.winfo_class() - self.current['.name'] = self.widget._w - - def update(self): - self.current = {} - self.options = {} - for k, v in self.configuration.items(): - if len(v) > 4: - self.current[k] = v[4] - self.options[k] = v[3], v[2] # default, klass - self.options['.class'] = (None, 'Class') - self.options['.name'] = (None, 'Name') - - class widgetoption: # Mix-in class - def set(self, e=None): - self.current = self.var.get() - try: - self.dialog.widget[self.option] = self.current - except TclError as msg: - print(msg) - self.refresh() - - class booleanoption(widgetoption, BooleanOption): pass - class enumoption(widgetoption, EnumOption): pass - class stringoption(widgetoption, StringOption): pass - class readonlyoption(widgetoption, ReadonlyOption): pass - - # Universal classes - classes = { - 'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER), - 'Aspect': 'integer', - 'Background': 'color', - 'Bitmap': 'bitmap', - 'BorderWidth': 'pixel', - 'Class': 'readonly', - 'CloseEnough': 'double', - 'Command': 'command', - 'Confine': 'boolean', - 'Cursor': 'cursor', - 'CursorWidth': 'pixel', - 'DisabledForeground': 'color', - 'ExportSelection': 'boolean', - 'Font': 'font', - 'Foreground': 'color', - 'From': 'integer', - 'Geometry': 'geometry', - 'Height': 'pixel', - 'InsertWidth': 'time', - 'Justify': (LEFT, CENTER, RIGHT), - 'Label': 'string', - 'Length': 'pixel', - 'MenuName': 'widget', - 'Name': 'readonly', - 'OffTime': 'time', - 'OnTime': 'time', - 'Orient': (HORIZONTAL, VERTICAL), - 'Pad': 'pixel', - 'Relief': (RAISED, SUNKEN, FLAT, RIDGE, GROOVE), - 'RepeatDelay': 'time', - 'RepeatInterval': 'time', - 'ScrollCommand': 'command', - 'ScrollIncrement': 'pixel', - 'ScrollRegion': 'rectangle', - 'ShowValue': 'boolean', - 'SetGrid': 'boolean', - 'Sliderforeground': 'color', - 'SliderLength': 'pixel', - 'Text': 'string', - 'TickInterval': 'integer', - 'To': 'integer', - 'Underline': 'index', - 'Variable': 'variable', - 'Value': 'string', - 'Width': 'pixel', - 'Wrap': (NONE, CHAR, WORD), - } - - # Classes that (may) differ per widget type - _tristate = {'State': (NORMAL, ACTIVE, DISABLED)} - _bistate = {'State': (NORMAL, DISABLED)} - addclasses = { - 'Button': _tristate, - 'Radiobutton': _tristate, - 'Checkbutton': _tristate, - 'Entry': _bistate, - 'Text': _bistate, - 'Menubutton': _tristate, - 'Slider': _bistate, - } - - -class RemoteWidgetDialog(WidgetDialog): - - def __init__(self, master, app, widget): - self.app = app - self.widget = widget - self.klass = master.send(self.app, - 'winfo', - 'class', - self.widget) - Dialog.__init__(self, master) - - def refresh(self): - try: - items = self.master.tk.splitlist( - self.master.send(self.app, - self.widget, - 'config')) - except TclError as msg: - print(msg) - return - dict = {} - for item in items: - words = self.master.tk.splitlist(item) - key = words[0][1:] - value = (key,) + words[1:] - dict[key] = value - self.configuration = dict - self.update() - self.current['.class'] = self.klass - self.current['.name'] = self.widget - - class remotewidgetoption: # Mix-in class - def set(self, e=None): - self.current = self.var.get() - try: - self.dialog.master.send( - self.dialog.app, - self.dialog.widget, - 'config', - '-'+self.option, - self.current) - except TclError as msg: - print(msg) - self.refresh() - - class booleanoption(remotewidgetoption, BooleanOption): pass - class enumoption(remotewidgetoption, EnumOption): pass - class stringoption(remotewidgetoption, StringOption): pass - class readonlyoption(remotewidgetoption, ReadonlyOption): pass - - -def test(): - import sys - root = Tk() - root.minsize(1, 1) - if sys.argv[1:]: - remotetest(root, sys.argv[1]) - else: - frame = Frame(root, name='frame') - frame.pack(expand=1, fill=BOTH) - button = Button(frame, name='button', text='button') - button.pack(expand=1) - canvas = Canvas(frame, name='canvas') - canvas.pack() - fpd = PackDialog(frame) - fwd = WidgetDialog(frame) - bpd = PackDialog(button) - bwd = WidgetDialog(button) - cpd = PackDialog(canvas) - cwd = WidgetDialog(canvas) - root.mainloop() - -def remotetest(root, app): - from listtree import listtree - list = listtree(root, app) - list.bind('', opendialogs) - list.app = app # Pass it on to handler - -def opendialogs(e): - list = e.widget - sel = list.curselection() - for i in sel: - item = list.get(i) - widget = item.split()[0] - RemoteWidgetDialog(list, list.app, widget) - if widget == '.': continue - try: - RemotePackDialog(list, list.app, widget) - except TclError as msg: - print(msg) - -test() diff --git a/Demo/tkinter/guido/brownian.py b/Demo/tkinter/guido/brownian.py deleted file mode 100644 index 7ab3e67..0000000 --- a/Demo/tkinter/guido/brownian.py +++ /dev/null @@ -1,50 +0,0 @@ -# Brownian motion -- an example of a multi-threaded Tkinter program. - -from tkinter import * -import random -import threading -import time -import sys - -WIDTH = 400 -HEIGHT = 300 -SIGMA = 10 -BUZZ = 2 -RADIUS = 2 -LAMBDA = 10 -FILL = 'red' - -stop = 0 # Set when main loop exits - -def particle(canvas): - r = RADIUS - x = random.gauss(WIDTH/2.0, SIGMA) - y = random.gauss(HEIGHT/2.0, SIGMA) - p = canvas.create_oval(x-r, y-r, x+r, y+r, fill=FILL) - while not stop: - dx = random.gauss(0, BUZZ) - dy = random.gauss(0, BUZZ) - dt = random.expovariate(LAMBDA) - try: - canvas.move(p, dx, dy) - except TclError: - break - time.sleep(dt) - -def main(): - global stop - root = Tk() - canvas = Canvas(root, width=WIDTH, height=HEIGHT) - canvas.pack(fill='both', expand=1) - np = 30 - if sys.argv[1:]: - np = int(sys.argv[1]) - for i in range(np): - t = threading.Thread(target=particle, args=(canvas,)) - t.start() - try: - root.mainloop() - finally: - stop = 1 - -main() diff --git a/Demo/tkinter/guido/brownian2.py b/Demo/tkinter/guido/brownian2.py deleted file mode 100644 index 3adcd68..0000000 --- a/Demo/tkinter/guido/brownian2.py +++ /dev/null @@ -1,55 +0,0 @@ -# Brownian motion -- an example of a NON multi-threaded Tkinter program ;) -# By Michele Simoniato, inspired by brownian.py - -from tkinter import * -import random -import sys - -WIDTH = 400 -HEIGHT = 300 -SIGMA = 10 -BUZZ = 2 -RADIUS = 2 -LAMBDA = 10 -FILL = 'red' - -stop = 0 # Set when main loop exits -root = None # main window - -def particle(canvas): # particle = iterator over the moves - r = RADIUS - x = random.gauss(WIDTH/2.0, SIGMA) - y = random.gauss(HEIGHT/2.0, SIGMA) - p = canvas.create_oval(x-r, y-r, x+r, y+r, fill=FILL) - while not stop: - dx = random.gauss(0, BUZZ) - dy = random.gauss(0, BUZZ) - try: - canvas.move(p, dx, dy) - except TclError: - break - else: - yield None - -def move(particle): # move the particle at random time - next(particle) - dt = random.expovariate(LAMBDA) - root.after(int(dt*1000), move, particle) - -def main(): - global root, stop - root = Tk() - canvas = Canvas(root, width=WIDTH, height=HEIGHT) - canvas.pack(fill='both', expand=1) - np = 30 - if sys.argv[1:]: - np = int(sys.argv[1]) - for i in range(np): # start the dance - move(particle(canvas)) - try: - root.mainloop() - finally: - stop = 1 - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/canvasevents.py b/Demo/tkinter/guido/canvasevents.py deleted file mode 100644 index 16312b5..0000000 --- a/Demo/tkinter/guido/canvasevents.py +++ /dev/null @@ -1,264 +0,0 @@ -#! /usr/bin/env python3 - -from tkinter import * - - -# Since Canvas.Group is no longer present, the following class reproduces -# a subset of the old Group class that is used by this app. - -class Group: - def __init__(self, canvas, tag=None): - if tag is None: - tag = 'Group%d' % id(self) - - self.tag = self.id = tag - self.canvas = canvas - self.canvas.dtag(self.tag) - - def __str__(self): - return self.tag - - def _do(self, cmd, *args): - return self.canvas.tk.call(self.canvas._w, cmd, self.tag, *args) - - def addtag_withtag(self, tagOrId): - self._do('addtag', 'withtag', tagOrId) - - def bind(self, sequence=None, command=None, add=None): - return self.canvas.tag_bind(self.id, sequence, command, add) - - def move(self, x_amount, y_amount): - self._do('move', x_amount, y_amount) - - def dtag(self, tagToDelete=None): - self._do('dtag', tagToDelete) - - def tkraise(self, aboveThis=None): - self._do('raise', aboveThis) - - -class Object: - - """Base class for composite graphical objects. - - Objects belong to a canvas, and can be moved around on the canvas. - They also belong to at most one ``pile'' of objects, and can be - transferred between piles (or removed from their pile). - - Objects have a canonical ``x, y'' position which is moved when the - object is moved. Where the object is relative to this position - depends on the object; for simple objects, it may be their center. - - Objects have mouse sensitivity. They can be clicked, dragged and - double-clicked. The behavior may actually determined by the pile - they are in. - - All instance attributes are public since the derived class may - need them. - """ - - def __init__(self, canvas, x=0, y=0, fill='red', text='object'): - self.canvas = canvas - self.x = x - self.y = y - self.pile = None - self.group = Group(self.canvas) - self.createitems(fill, text) - - def __str__(self): - return str(self.group) - - def createitems(self, fill, text): - self.__oval = self.canvas.create_oval(self.x - 20, self.y - 10, - self.x + 20, self.y + 20, fill=fill, width=3) - self.group.addtag_withtag(self.__oval) - self.__text = self.canvas.create_text(self.x, self.y, text=text) - self.group.addtag_withtag(self.__text) - - def moveby(self, dx, dy): - if dx == dy == 0: - return - self.group.move(dx, dy) - self.x = self.x + dx - self.y = self.y + dy - - def moveto(self, x, y): - self.moveby(x - self.x, y - self.y) - - def transfer(self, pile): - if self.pile: - self.pile.delete(self) - self.pile = None - self.pile = pile - if self.pile: - self.pile.add(self) - - def tkraise(self): - self.group.tkraise() - - -class Bottom(Object): - """An object to serve as the bottom of a pile.""" - - def createitems(self, *args): - self.__oval = self.canvas.create_oval(self.x - 20, self.y - 10, - self.x + 20, self.y + 10, fill='gray', outline='') - self.group.addtag_withtag(self.__oval) - - -class Pile: - """A group of graphical objects.""" - - def __init__(self, canvas, x, y, tag=None): - self.canvas = canvas - self.x = x - self.y = y - self.objects = [] - self.bottom = Bottom(self.canvas, self.x, self.y) - self.group = Group(self.canvas, tag=tag) - self.group.addtag_withtag(self.bottom.group) - self.bindhandlers() - - def bindhandlers(self): - self.group.bind('<1>', self.clickhandler) - self.group.bind('', self.doubleclickhandler) - - def add(self, object): - self.objects.append(object) - self.group.addtag_withtag(object.group) - self.position(object) - - def delete(self, object): - object.group.dtag(self.group) - self.objects.remove(object) - - def position(self, object): - object.tkraise() - i = self.objects.index(object) - object.moveto(self.x + i*4, self.y + i*8) - - def clickhandler(self, event): - pass - - def doubleclickhandler(self, event): - pass - - -class MovingPile(Pile): - - def bindhandlers(self): - Pile.bindhandlers(self) - self.group.bind('', self.motionhandler) - self.group.bind('', self.releasehandler) - - movethis = None - - def clickhandler(self, event): - tags = self.canvas.gettags('current') - for i in range(len(self.objects)): - o = self.objects[i] - if o.group.tag in tags: - break - else: - self.movethis = None - return - self.movethis = self.objects[i:] - for o in self.movethis: - o.tkraise() - self.lastx = event.x - self.lasty = event.y - - doubleclickhandler = clickhandler - - def motionhandler(self, event): - if not self.movethis: - return - dx = event.x - self.lastx - dy = event.y - self.lasty - self.lastx = event.x - self.lasty = event.y - for o in self.movethis: - o.moveby(dx, dy) - - def releasehandler(self, event): - objects = self.movethis - if not objects: - return - self.movethis = None - self.finishmove(objects) - - def finishmove(self, objects): - for o in objects: - self.position(o) - - -class Pile1(MovingPile): - - x = 50 - y = 50 - tag = 'p1' - - def __init__(self, demo): - self.demo = demo - MovingPile.__init__(self, self.demo.canvas, self.x, self.y, self.tag) - - def doubleclickhandler(self, event): - try: - o = self.objects[-1] - except IndexError: - return - o.transfer(self.other()) - MovingPile.doubleclickhandler(self, event) - - def other(self): - return self.demo.p2 - - def finishmove(self, objects): - o = objects[0] - p = self.other() - x, y = o.x, o.y - if (x-p.x)**2 + (y-p.y)**2 < (x-self.x)**2 + (y-self.y)**2: - for o in objects: - o.transfer(p) - else: - MovingPile.finishmove(self, objects) - -class Pile2(Pile1): - - x = 150 - y = 50 - tag = 'p2' - - def other(self): - return self.demo.p1 - - -class Demo: - - def __init__(self, master): - self.master = master - self.canvas = Canvas(master, - width=200, height=200, - background='yellow', - relief=SUNKEN, borderwidth=2) - self.canvas.pack(expand=1, fill=BOTH) - self.p1 = Pile1(self) - self.p2 = Pile2(self) - o1 = Object(self.canvas, fill='red', text='o1') - o2 = Object(self.canvas, fill='green', text='o2') - o3 = Object(self.canvas, fill='light blue', text='o3') - o1.transfer(self.p1) - o2.transfer(self.p1) - o3.transfer(self.p2) - - -# Main function, run when invoked as a stand-alone Python program. - -def main(): - root = Tk() - demo = Demo(root) - root.protocol('WM_DELETE_WINDOW', root.quit) - root.mainloop() - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/dialog.py b/Demo/tkinter/guido/dialog.py deleted file mode 100755 index eae9c7e..0000000 --- a/Demo/tkinter/guido/dialog.py +++ /dev/null @@ -1,108 +0,0 @@ -#! /usr/bin/env python3 - -# A Python function that generates dialog boxes with a text message, -# optional bitmap, and any number of buttons. -# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.2-3, pp. 269-270. - -from tkinter import * -import sys - - -def dialog(master, title, text, bitmap, default, *args): - - # 1. Create the top-level window and divide it into top - # and bottom parts. - - w = Toplevel(master, class_='Dialog') - w.title(title) - w.iconname('Dialog') - - top = Frame(w, relief=RAISED, borderwidth=1) - top.pack(side=TOP, fill=BOTH) - bot = Frame(w, relief=RAISED, borderwidth=1) - bot.pack(side=BOTTOM, fill=BOTH) - - # 2. Fill the top part with the bitmap and message. - - msg = Message(top, width='3i', text=text) - msg.pack(side=RIGHT, expand=1, fill=BOTH, padx='3m', pady='3m') - if bitmap: - bm = Label(top, bitmap=bitmap) - bm.pack(side=LEFT, padx='3m', pady='3m') - - # 3. Create a row of buttons at the bottom of the dialog. - - var = IntVar() - buttons = [] - i = 0 - for but in args: - b = Button(bot, text=but, command=lambda v=var,i=i: v.set(i)) - buttons.append(b) - if i == default: - bd = Frame(bot, relief=SUNKEN, borderwidth=1) - bd.pack(side=LEFT, expand=1, padx='3m', pady='2m') - b.lift() - b.pack (in_=bd, side=LEFT, - padx='2m', pady='2m', ipadx='2m', ipady='1m') - else: - b.pack (side=LEFT, expand=1, - padx='3m', pady='3m', ipadx='2m', ipady='1m') - i = i+1 - - # 4. Set up a binding for , if there's a default, - # set a grab, and claim the focus too. - - if default >= 0: - w.bind('', - lambda e, b=buttons[default], v=var, i=default: - (b.flash(), - v.set(i))) - - oldFocus = w.focus_get() - w.grab_set() - w.focus_set() - - # 5. Wait for the user to respond, then restore the focus - # and return the index of the selected button. - - w.waitvar(var) - w.destroy() - if oldFocus: oldFocus.focus_set() - return var.get() - -# The rest is the test program. - -def go(): - i = dialog(mainWidget, - 'Not Responding', - "The file server isn't responding right now; " - "I'll keep trying.", - '', - -1, - 'OK') - print('pressed button', i) - i = dialog(mainWidget, - 'File Modified', - 'File "tcl.h" has been modified since ' - 'the last time it was saved. ' - 'Do you want to save it before exiting the application?', - 'warning', - 0, - 'Save File', - 'Discard Changes', - 'Return To Editor') - print('pressed button', i) - -def test(): - import sys - global mainWidget - mainWidget = Frame() - Pack.config(mainWidget) - start = Button(mainWidget, text='Press Here To Start', command=go) - start.pack() - endit = Button(mainWidget, text="Exit", command=sys.exit) - endit.pack(fill=BOTH) - mainWidget.mainloop() - -if __name__ == '__main__': - test() diff --git a/Demo/tkinter/guido/electrons.py b/Demo/tkinter/guido/electrons.py deleted file mode 100755 index 896e079..0000000 --- a/Demo/tkinter/guido/electrons.py +++ /dev/null @@ -1,91 +0,0 @@ -#! /usr/bin/env python3 - -# Simulate "electrons" migrating across the screen. -# An optional bitmap file in can be in the background. -# -# Usage: electrons [n [bitmapfile]] -# -# n is the number of electrons to animate; default is 30. -# -# The bitmap file can be any X11 bitmap file (look in -# /usr/include/X11/bitmaps for samples); it is displayed as the -# background of the animation. Default is no bitmap. - -from tkinter import * -import random - - -# The graphical interface -class Electrons: - - # Create our objects - def __init__(self, n, bitmap = None): - self.n = n - self.tk = tk = Tk() - self.canvas = c = Canvas(tk) - c.pack() - width, height = tk.getint(c['width']), tk.getint(c['height']) - - # Add background bitmap - if bitmap: - self.bitmap = c.create_bitmap(width/2, height/2, - bitmap=bitmap, - foreground='blue') - - self.pieces = [] - x1, y1, x2, y2 = 10,70,14,74 - for i in range(n): - p = c.create_oval(x1, y1, x2, y2, fill='red') - self.pieces.append(p) - y1, y2 = y1 +2, y2 + 2 - self.tk.update() - - def random_move(self, n): - c = self.canvas - for p in self.pieces: - x = random.choice(range(-2,4)) - y = random.choice(range(-3,4)) - c.move(p, x, y) - self.tk.update() - - # Run -- allow 500 movemens - def run(self): - try: - for i in range(500): - self.random_move(self.n) - except TclError: - try: - self.tk.destroy() - except TclError: - pass - - -# Main program -def main(): - import sys - - # First argument is number of electrons, default 30 - if sys.argv[1:]: - n = int(sys.argv[1]) - else: - n = 30 - - # Second argument is bitmap file, default none - if sys.argv[2:]: - bitmap = sys.argv[2] - # Reverse meaning of leading '@' compared to Tk - if bitmap[0] == '@': bitmap = bitmap[1:] - else: bitmap = '@' + bitmap - else: - bitmap = None - - # Create the graphical objects... - h = Electrons(n, bitmap) - - # ...and run! - h.run() - - -# Call main when run as script -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/hanoi.py b/Demo/tkinter/guido/hanoi.py deleted file mode 100644 index 34a0bba..0000000 --- a/Demo/tkinter/guido/hanoi.py +++ /dev/null @@ -1,154 +0,0 @@ -# Animated Towers of Hanoi using Tk with optional bitmap file in -# background. -# -# Usage: tkhanoi [n [bitmapfile]] -# -# n is the number of pieces to animate; default is 4, maximum 15. -# -# The bitmap file can be any X11 bitmap file (look in -# /usr/include/X11/bitmaps for samples); it is displayed as the -# background of the animation. Default is no bitmap. - -# This uses Steen Lumholt's Tk interface -from tkinter import * - - -# Basic Towers-of-Hanoi algorithm: move n pieces from a to b, using c -# as temporary. For each move, call report() -def hanoi(n, a, b, c, report): - if n <= 0: return - hanoi(n-1, a, c, b, report) - report(n, a, b) - hanoi(n-1, c, b, a, report) - - -# The graphical interface -class Tkhanoi: - - # Create our objects - def __init__(self, n, bitmap = None): - self.n = n - self.tk = tk = Tk() - self.canvas = c = Canvas(tk) - c.pack() - width, height = tk.getint(c['width']), tk.getint(c['height']) - - # Add background bitmap - if bitmap: - self.bitmap = c.create_bitmap(width//2, height//2, - bitmap=bitmap, - foreground='blue') - - # Generate pegs - pegwidth = 10 - pegheight = height//2 - pegdist = width//3 - x1, y1 = (pegdist-pegwidth)//2, height*1//3 - x2, y2 = x1+pegwidth, y1+pegheight - self.pegs = [] - p = c.create_rectangle(x1, y1, x2, y2, fill='black') - self.pegs.append(p) - x1, x2 = x1+pegdist, x2+pegdist - p = c.create_rectangle(x1, y1, x2, y2, fill='black') - self.pegs.append(p) - x1, x2 = x1+pegdist, x2+pegdist - p = c.create_rectangle(x1, y1, x2, y2, fill='black') - self.pegs.append(p) - self.tk.update() - - # Generate pieces - pieceheight = pegheight//16 - maxpiecewidth = pegdist*2//3 - minpiecewidth = 2*pegwidth - self.pegstate = [[], [], []] - self.pieces = {} - x1, y1 = (pegdist-maxpiecewidth)//2, y2-pieceheight-2 - x2, y2 = x1+maxpiecewidth, y1+pieceheight - dx = (maxpiecewidth-minpiecewidth) // (2*max(1, n-1)) - for i in range(n, 0, -1): - p = c.create_rectangle(x1, y1, x2, y2, fill='red') - self.pieces[i] = p - self.pegstate[0].append(i) - x1, x2 = x1 + dx, x2-dx - y1, y2 = y1 - pieceheight-2, y2-pieceheight-2 - self.tk.update() - self.tk.after(25) - - # Run -- never returns - def run(self): - while 1: - hanoi(self.n, 0, 1, 2, self.report) - hanoi(self.n, 1, 2, 0, self.report) - hanoi(self.n, 2, 0, 1, self.report) - hanoi(self.n, 0, 2, 1, self.report) - hanoi(self.n, 2, 1, 0, self.report) - hanoi(self.n, 1, 0, 2, self.report) - - # Reporting callback for the actual hanoi function - def report(self, i, a, b): - if self.pegstate[a][-1] != i: raise RuntimeError # Assertion - del self.pegstate[a][-1] - p = self.pieces[i] - c = self.canvas - - # Lift the piece above peg a - ax1, ay1, ax2, ay2 = c.bbox(self.pegs[a]) - while 1: - x1, y1, x2, y2 = c.bbox(p) - if y2 < ay1: break - c.move(p, 0, -1) - self.tk.update() - - # Move it towards peg b - bx1, by1, bx2, by2 = c.bbox(self.pegs[b]) - newcenter = (bx1+bx2)//2 - while 1: - x1, y1, x2, y2 = c.bbox(p) - center = (x1+x2)//2 - if center == newcenter: break - if center > newcenter: c.move(p, -1, 0) - else: c.move(p, 1, 0) - self.tk.update() - - # Move it down on top of the previous piece - pieceheight = y2-y1 - newbottom = by2 - pieceheight*len(self.pegstate[b]) - 2 - while 1: - x1, y1, x2, y2 = c.bbox(p) - if y2 >= newbottom: break - c.move(p, 0, 1) - self.tk.update() - - # Update peg state - self.pegstate[b].append(i) - - -# Main program -def main(): - import sys - - # First argument is number of pegs, default 4 - if sys.argv[1:]: - n = int(sys.argv[1]) - else: - n = 4 - - # Second argument is bitmap file, default none - if sys.argv[2:]: - bitmap = sys.argv[2] - # Reverse meaning of leading '@' compared to Tk - if bitmap[0] == '@': bitmap = bitmap[1:] - else: bitmap = '@' + bitmap - else: - bitmap = None - - # Create the graphical objects... - h = Tkhanoi(n, bitmap) - - # ...and run! - h.run() - - -# Call main when run as script -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/hello.py b/Demo/tkinter/guido/hello.py deleted file mode 100644 index f10fb7a..0000000 --- a/Demo/tkinter/guido/hello.py +++ /dev/null @@ -1,17 +0,0 @@ -# Display hello, world in a button; clicking it quits the program - -import sys -from tkinter import * - -def main(): - root = Tk() - button = Button(root) - button['text'] = 'Hello, world' - button['command'] = quit_callback # See below - button.pack() - root.mainloop() - -def quit_callback(): - sys.exit(0) - -main() diff --git a/Demo/tkinter/guido/imagedraw.py b/Demo/tkinter/guido/imagedraw.py deleted file mode 100644 index a168831..0000000 --- a/Demo/tkinter/guido/imagedraw.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Draw on top of an image""" - -from tkinter import * -import sys - -def main(): - filename = sys.argv[1] - root = Tk() - img = PhotoImage(file=filename) - w, h = img.width(), img.height() - canv = Canvas(root, width=w, height=h) - canv.create_image(0, 0, anchor=NW, image=img) - canv.pack() - canv.bind('', blob) - root.mainloop() - -def blob(event): - x, y = event.x, event.y - canv = event.widget - r = 5 - canv.create_oval(x-r, y-r, x+r, y+r, fill='red', outline="") - -main() diff --git a/Demo/tkinter/guido/imageview.py b/Demo/tkinter/guido/imageview.py deleted file mode 100644 index 276858a..0000000 --- a/Demo/tkinter/guido/imageview.py +++ /dev/null @@ -1,12 +0,0 @@ -from tkinter import * -import sys - -def main(): - filename = sys.argv[1] - root = Tk() - img = PhotoImage(file=filename) - label = Label(root, image=img) - label.pack() - root.mainloop() - -main() diff --git a/Demo/tkinter/guido/kill.py b/Demo/tkinter/guido/kill.py deleted file mode 100755 index 44a6b9b..0000000 --- a/Demo/tkinter/guido/kill.py +++ /dev/null @@ -1,96 +0,0 @@ -#! /usr/bin/env python3 -# Tkinter interface to Linux `kill' command. - -from tkinter import * -import subprocess -import os - -class BarButton(Menubutton): - def __init__(self, master=None, **cnf): - Menubutton.__init__(self, master, **cnf) - self.pack(side=LEFT) - self.menu = Menu(self, name='menu') - self['menu'] = self.menu - -class Kill(Frame): - # List of (name, option, pid_column) - format_list = [('Default', '', 0), - ('Long', '-l', 2), - ('User', '-u', 1), - ('Jobs', '-j', 1), - ('Signal', '-s', 1), - ('Memory', '-m', 0), - ('VM', '-v', 0), - ('Hex', '-X', 0)] - def kill(self, selected): - c = self.format_list[self.format.get()][2] - pid = selected.split()[c] - os.system('kill -9 ' + pid) - self.do_update() - def do_update(self): - name, option, column = self.format_list[self.format.get()] - s = subprocess.getoutput('ps -w ' + option) - list = s.split('\n') - self.header.set(list[0]) - del list[0] - y = self.frame.vscroll.get()[0] - self.frame.list.delete(0, AtEnd()) - for line in list: - self.frame.list.insert(0, line) - self.frame.list.yview(int(y)) - def do_motion(self, e): - e.widget.select_clear(0, END) - e.widget.select_set(e.widget.nearest(e.y)) - def do_leave(self, e): - e.widget.select_clear(0, END) - def do_1(self, e): - self.kill(e.widget.get(e.widget.nearest(e.y))) - def __init__(self, master=None, **cnf): - Frame.__init__(self, master, cnf) - self.pack(expand=1, fill=BOTH) - self.bar = Frame(self, name='bar', relief=RAISED, - borderwidth=2) - self.bar.pack(fill=X) - self.bar.file = BarButton(self.bar, text='File') - self.bar.file.menu.add_command( - label='Quit', command=self.quit) - self.bar.view = BarButton(self.bar, text='View') - self.format = IntVar(self) - self.format.set(2) - for num in range(len(self.format_list)): - self.bar.view.menu.add_radiobutton( - label=self.format_list[num][0], - command=self.do_update, - variable=self.format, - value=num) - #self.bar.view.menu.add_separator() - #XXX ... - self.bar.tk_menuBar(self.bar.file, self.bar.view) - self.frame = Frame(self, relief=RAISED, borderwidth=2) - self.frame.pack(expand=1, fill=BOTH) - self.header = StringVar(self) - self.frame.label = Label(self.frame, relief=FLAT, anchor=NW, - borderwidth=0, - textvariable=self.header) - self.frame.label.pack(fill=X) - self.frame.vscroll = Scrollbar(self.frame, orient=VERTICAL) - self.frame.list = Listbox(self.frame, relief=SUNKEN, - selectbackground='#eed5b7', - selectborderwidth=0, - yscroll=self.frame.vscroll.set) - self.frame.vscroll['command'] = self.frame.list.yview - self.frame.vscroll.pack(side=RIGHT, fill=Y) - self.frame.list.pack(expand=1, fill=BOTH) - self.update = Button(self, text="Update", - command=self.do_update) - self.update.pack(expand=1, fill=X) - self.frame.list.bind('', self.do_motion) - self.frame.list.bind('', self.do_leave) - self.frame.list.bind('<1>', self.do_1) - self.do_update() - -if __name__ == '__main__': - kill = Kill(None, borderwidth=5) - kill.winfo_toplevel().title('Tkinter Process Killer') - kill.winfo_toplevel().minsize(1, 1) - kill.mainloop() diff --git a/Demo/tkinter/guido/listtree.py b/Demo/tkinter/guido/listtree.py deleted file mode 100644 index 8db5b60..0000000 --- a/Demo/tkinter/guido/listtree.py +++ /dev/null @@ -1,34 +0,0 @@ -# List a remote app's widget tree (names and classes only) - -import sys - -from tkinter import * - -def listtree(master, app): - list = Listbox(master, name='list') - list.pack(expand=1, fill=BOTH) - listnodes(list, app, '.', 0) - return list - -def listnodes(list, app, widget, level): - klass = list.send(app, 'winfo', 'class', widget) - list.insert(END, '%s (%s)' % (widget, klass)) - children = list.tk.splitlist( - list.send(app, 'winfo', 'children', widget)) - for c in children: - listnodes(list, app, c, level+1) - -def main(): - if not sys.argv[1:]: - sys.stderr.write('Usage: listtree appname\n') - sys.exit(2) - app = sys.argv[1] - tk = Tk() - tk.minsize(1, 1) - f = Frame(tk, name='f') - f.pack(expand=1, fill=BOTH) - list = listtree(f, app) - tk.mainloop() - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/manpage.py b/Demo/tkinter/guido/manpage.py deleted file mode 100644 index 750c675..0000000 --- a/Demo/tkinter/guido/manpage.py +++ /dev/null @@ -1,215 +0,0 @@ -# Widget to display a man page - -import os -import re -import sys - -from tkinter import * -from tkinter.font import Font -from tkinter.scrolledtext import ScrolledText - -# XXX Recognizing footers is system dependent -# (This one works for IRIX 5.2 and Solaris 2.2) -footerprog = re.compile( - '^ Page [1-9][0-9]*[ \t]+\|^.*Last change:.*[1-9][0-9]*\n') -emptyprog = re.compile('^[ \t]*\n') -ulprog = re.compile('^[ \t]*[Xv!_][Xv!_ \t]*\n') - - -class EditableManPage(ScrolledText): - """Basic Man Page class -- does not disable editing.""" - - def __init__(self, master=None, **cnf): - ScrolledText.__init__(self, master, **cnf) - - bold = Font(font=self['font']).copy() - bold.config(weight='bold') - italic = Font(font=self['font']).copy() - italic.config(slant='italic') - - # Define tags for formatting styles - self.tag_config('X', underline=1) - self.tag_config('!', font=bold) - self.tag_config('_', font=italic) - - # Set state to idle - self.fp = None - self.lineno = 0 - - def busy(self): - """Test whether we are busy parsing a file.""" - return self.fp != None - - def kill(self): - """Ensure we're not busy.""" - if self.busy(): - self._endparser() - - def asyncparsefile(self, fp): - """Parse a file, in the background.""" - self._startparser(fp) - self.tk.createfilehandler(fp, READABLE, - self._filehandler) - - parsefile = asyncparsefile # Alias - - def _filehandler(self, fp, mask): - """I/O handler used by background parsing.""" - nextline = self.fp.readline() - if not nextline: - self._endparser() - return - self._parseline(nextline) - - def syncparsefile(self, fp): - """Parse a file, now (cannot be aborted).""" - self._startparser(fp) - while True: - nextline = fp.readline() - if not nextline: - break - self._parseline(nextline) - self._endparser() - - def _startparser(self, fp): - """Initialize parsing from a particular file -- must not be busy.""" - if self.busy(): - raise RuntimeError('startparser: still busy') - fp.fileno() # Test for file-ness - self.fp = fp - self.lineno = 0 - self.ok = 0 - self.empty = 0 - self.buffer = None - savestate = self['state'] - self['state'] = NORMAL - self.delete('1.0', END) - self['state'] = savestate - - def _endparser(self): - """End parsing -- must be busy, need not be at EOF.""" - if not self.busy(): - raise RuntimeError('endparser: not busy') - if self.buffer: - self._parseline('') - try: - self.tk.deletefilehandler(self.fp) - except TclError: - pass - self.fp.close() - self.fp = None - del self.ok, self.empty, self.buffer - - def _parseline(self, nextline): - """Parse a single line.""" - if not self.buffer: - # Save this line -- we need one line read-ahead - self.buffer = nextline - return - if emptyprog.match(self.buffer): - # Buffered line was empty -- set a flag - self.empty = 1 - self.buffer = nextline - return - textline = self.buffer - if ulprog.match(nextline): - # Next line is properties for buffered line - propline = nextline - self.buffer = None - else: - # Next line is read-ahead - propline = None - self.buffer = nextline - if not self.ok: - # First non blank line after footer must be header - # -- skip that too - self.ok = 1 - self.empty = 0 - return - if footerprog.match(textline): - # Footer -- start skipping until next non-blank line - self.ok = 0 - self.empty = 0 - return - savestate = self['state'] - self['state'] = NORMAL - if TkVersion >= 4.0: - self.mark_set('insert', 'end-1c') - else: - self.mark_set('insert', END) - if self.empty: - # One or more previous lines were empty - # -- insert one blank line in the text - self._insert_prop('\n') - self.lineno = self.lineno + 1 - self.empty = 0 - if not propline: - # No properties - self._insert_prop(textline) - else: - # Search for properties - p = '' - j = 0 - for i in range(min(len(propline), len(textline))): - if propline[i] != p: - if j < i: - self._insert_prop(textline[j:i], p) - j = i - p = propline[i] - self._insert_prop(textline[j:]) - self.lineno = self.lineno + 1 - self['state'] = savestate - - def _insert_prop(self, str, prop = ' '): - """Insert a string at the end, with at most one property (tag).""" - here = self.index(AtInsert()) - self.insert(AtInsert(), str) - if TkVersion <= 4.0: - tags = self.tag_names(here) - for tag in tags: - self.tag_remove(tag, here, AtInsert()) - if prop != ' ': - self.tag_add(prop, here, AtInsert()) - - -class ReadonlyManPage(EditableManPage): - """Readonly Man Page class -- disables editing, otherwise the same.""" - - def __init__(self, master=None, **cnf): - cnf['state'] = DISABLED - EditableManPage.__init__(self, master, **cnf) - -# Alias -ManPage = ReadonlyManPage - -# usage: ManPage [manpage]; or ManPage [-f] file -# -f means that the file is nroff -man output run through ul -i -def main(): - # XXX This directory may be different on your system - MANDIR = '' - DEFAULTPAGE = 'Tcl' - formatted = 0 - if sys.argv[1:] and sys.argv[1] == '-f': - formatted = 1 - del sys.argv[1] - if sys.argv[1:]: - name = sys.argv[1] - else: - name = DEFAULTPAGE - if not formatted: - if name[-2:-1] != '.': - name = name + '.n' - name = os.path.join(MANDIR, name) - root = Tk() - root.minsize(1, 1) - manpage = ManPage(root, relief=SUNKEN, borderwidth=2) - manpage.pack(expand=1, fill=BOTH) - if formatted: - fp = open(name, 'r') - else: - fp = os.popen('nroff -man -c %s | ul -i' % name, 'r') - manpage.parsefile(fp) - root.mainloop() - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/mbox.py b/Demo/tkinter/guido/mbox.py deleted file mode 100755 index 0a421cf..0000000 --- a/Demo/tkinter/guido/mbox.py +++ /dev/null @@ -1,286 +0,0 @@ -#! /usr/bin/env python3 - -# Scan MH folder, display results in window - -import os -import re -import sys -import getopt -import mailbox -from tkinter import * - -from dialog import dialog - -MBOXPATH = os.environ['HOME'] + '/Mail' - -def main(): - global root, tk, top, mid, bot - global folderbox, foldermenu, scanbox, scanmenu, viewer - global folder, seq - global mh, mhf - - # Parse command line options - - folder = 'inbox' - seq = 'all' - try: - opts, args = getopt.getopt(sys.argv[1:], '') - except getopt.error as msg: - print(msg) - sys.exit(2) - for arg in args: - if arg[:1] == '+': - folder = arg[1:] - else: - seq = arg - - # Initialize MH - - mh = mailbox.MH(MBOXPATH) - mhf = mh.get_folder(folder) - - # Build widget hierarchy - - root = Tk() - tk = root.tk - - top = Frame(root) - top.pack({'expand': 1, 'fill': 'both'}) - - # Build right part: folder list - - right = Frame(top) - right.pack({'fill': 'y', 'side': 'right'}) - - folderbar = Scrollbar(right, {'relief': 'sunken', 'bd': 2}) - folderbar.pack({'fill': 'y', 'side': 'right'}) - - folderbox = Listbox(right, {'exportselection': 0}) - folderbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'}) - - foldermenu = Menu(root) - foldermenu.add('command', - {'label': 'Open Folder', - 'command': open_folder}) - foldermenu.add('separator') - foldermenu.add('command', - {'label': 'Quit', - 'command': 'exit'}) - foldermenu.bind('', folder_unpost) - - folderbox['yscrollcommand'] = (folderbar, 'set') - folderbar['command'] = (folderbox, 'yview') - folderbox.bind('', open_folder, 1) - folderbox.bind('<3>', folder_post) - - # Build left part: scan list - - left = Frame(top) - left.pack({'expand': 1, 'fill': 'both', 'side': 'left'}) - - scanbar = Scrollbar(left, {'relief': 'sunken', 'bd': 2}) - scanbar.pack({'fill': 'y', 'side': 'right'}) - - scanbox = Listbox(left, {'font': 'fixed'}) - scanbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'}) - - scanmenu = Menu(root) - scanmenu.add('command', - {'label': 'Open Message', - 'command': open_message}) - scanmenu.add('command', - {'label': 'Remove Message', - 'command': remove_message}) - scanmenu.add('command', - {'label': 'Refile Message', - 'command': refile_message}) - scanmenu.add('separator') - scanmenu.add('command', - {'label': 'Quit', - 'command': 'exit'}) - scanmenu.bind('', scan_unpost) - - scanbox['yscrollcommand'] = (scanbar, 'set') - scanbar['command'] = (scanbox, 'yview') - scanbox.bind('', open_message) - scanbox.bind('<3>', scan_post) - - # Separator between middle and bottom part - - rule2 = Frame(root, {'bg': 'black'}) - rule2.pack({'fill': 'x'}) - - # Build bottom part: current message - - bot = Frame(root) - bot.pack({'expand': 1, 'fill': 'both'}) - # - viewer = None - - # Window manager commands - - root.minsize(800, 1) # Make window resizable - - # Fill folderbox with text - - setfolders() - - # Fill scanbox with text - - rescan() - - # Enter mainloop - - root.mainloop() - -def folder_post(e): - x, y = e.x_root, e.y_root - foldermenu.post(x - 10, y - 10) - foldermenu.grab_set() - -def folder_unpost(e): - tk.call('update', 'idletasks') - foldermenu.grab_release() - foldermenu.unpost() - foldermenu.invoke('active') - -def scan_post(e): - x, y = e.x_root, e.y_root - scanmenu.post(x - 10, y - 10) - scanmenu.grab_set() - -def scan_unpost(e): - tk.call('update', 'idletasks') - scanmenu.grab_release() - scanmenu.unpost() - scanmenu.invoke('active') - -scanparser = re.compile('^ *([0-9]+)') - -def open_folder(e=None): - global folder, mhf - sel = folderbox.curselection() - if len(sel) != 1: - if len(sel) > 1: - msg = "Please open one folder at a time" - else: - msg = "Please select a folder to open" - dialog(root, "Can't Open Folder", msg, "", 0, "OK") - return - i = sel[0] - folder = folderbox.get(i) - mhf = mh.get_folder(folder) - rescan() - -def open_message(e=None): - global viewer - sel = scanbox.curselection() - if len(sel) != 1: - if len(sel) > 1: - msg = "Please open one message at a time" - else: - msg = "Please select a message to open" - dialog(root, "Can't Open Message", msg, "", 0, "OK") - return - cursor = scanbox['cursor'] - scanbox['cursor'] = 'watch' - tk.call('update', 'idletasks') - i = sel[0] - line = scanbox.get(i) - m = scanparser.match(line) - if m: - num = int(m.group(1)) - m = mhf.get_message(num) - if viewer: viewer.destroy() - from mimeviewer import MimeViewer - viewer = MimeViewer(bot, '+%s/%d' % (folder, num), m) - viewer.pack() - viewer.show() - scanbox['cursor'] = cursor - -def interestingheader(header): - return header != 'received' - -def remove_message(e=None): - itop = scanbox.nearest(0) - sel = scanbox.curselection() - if not sel: - dialog(root, "No Message To Remove", - "Please select a message to remove", "", 0, "OK") - return - todo = [] - for i in sel: - line = scanbox.get(i) - m = scanparser.match(line) - if m: - toremove = int(m.group(1)) - todo.append(toremove) - mhf.remove(toremove) - rescan() - fixfocus(min(todo), itop) - -lastrefile = '' -tofolder = None -def refile_message(e=None): - global lastrefile, tofolder - itop = scanbox.nearest(0) - sel = scanbox.curselection() - if not sel: - dialog(root, "No Message To Refile", - "Please select a message to refile", "", 0, "OK") - return - foldersel = folderbox.curselection() - if len(foldersel) != 1: - if not foldersel: - msg = "Please select a folder to refile to" - else: - msg = "Please select exactly one folder to refile to" - dialog(root, "No Folder To Refile", msg, "", 0, "OK") - return - refileto = folderbox.get(foldersel[0]) - todo = [] - for i in sel: - line = scanbox.get(i) - m = scanparser.match(line) - if m: - todo.append(int(m.group(1))) - if lastrefile != refileto or not tofolder: - lastrefile = refileto - tofolder = None - tofolder = mh.get_folder(lastrefile) - mhf.refilemessages(todo, tofolder) - rescan() - fixfocus(min(todo), itop) - -def fixfocus(near, itop): - n = scanbox.size() - for i in range(n): - line = scanbox.get(repr(i)) - m = scanparser.match(line) - if m: - num = int(m.group(1)) - if num >= near: - break - else: - i = 'end' - scanbox.yview(itop) - -def setfolders(): - folderbox.delete(0, 'end') - for fn in mh.list_folders(): - folderbox.insert('end', fn) - -def rescan(): - global viewer - if viewer: - viewer.destroy() - viewer = None - scanbox.delete(0, 'end') - for line in scanfolder(folder, seq): - scanbox.insert('end', line) - -def scanfolder(folder = 'inbox', sequence = 'all'): - return [line[:-1] for line in - os.popen('scan +%s %s' % (folder, sequence), 'r').readlines()] - -main() diff --git a/Demo/tkinter/guido/mimeviewer.py b/Demo/tkinter/guido/mimeviewer.py deleted file mode 100755 index babed8f..0000000 --- a/Demo/tkinter/guido/mimeviewer.py +++ /dev/null @@ -1,159 +0,0 @@ -#! /usr/bin/env python3 - -# View a single MIME multipart message. -# Display each part as a box. - -import os -import sys -import getopt -import mailbox -from tkinter import * -from tkinter.scrolledtext import ScrolledText - -MBOXPATH = os.environ['HOME'] + '/Mail' - -class Error(Exception): - pass - -def getcurrent(self): - """Return the current message. Raise Error when there is none.""" - seqs = self.get_sequences() - try: - return max(seqs['cur']) - except (ValueError, KeyError): - raise Error("no cur message") - - -class MimeViewer: - def __init__(self, parent, title, msg): - self.title = title - self.msg = msg - self.frame = Frame(parent, {'relief': 'raised', 'bd': 2}) - self.frame.packing = {'expand': 0, 'fill': 'both'} - self.button = Checkbutton(self.frame, - {'text': title, - 'command': self.toggle}) - self.button.pack({'anchor': 'w'}) - headertext = [] - for item in msg.items(): - headertext.append("%s: %s" % item) - headertext = '\n'.join(headertext) - height = countlines(headertext, 4) - if height: - self.htext = ScrolledText(self.frame, - {'height': height, - 'width': 80, - 'wrap': 'none', - 'relief': 'raised', - 'bd': 2}) - self.htext.packing = {'expand': 1, 'fill': 'both', - 'after': self.button} - self.htext.insert('end', headertext) - else: - self.htext = Frame(self.frame, - {'relief': 'raised', 'bd': 2}) - self.htext.packing = {'side': 'top', - 'ipady': 2, - 'fill': 'x', - 'after': self.button} - body = msg.get_payload() - if type(body) == str: - self.pad = None - height = countlines(body, 10) - if height: - self.btext = ScrolledText(self.frame, - {'height': height, - 'width': 80, - 'wrap': 'none', - 'relief': 'raised', - 'bd': 2}) - self.btext.packing = {'expand': 1, - 'fill': 'both'} - self.btext.insert('end', body) - else: - self.btext = None - self.parts = None - else: - self.pad = Frame(self.frame, - {'relief': 'flat', 'bd': 2}) - self.pad.packing = {'side': 'left', 'ipadx': 10, - 'fill': 'y', 'after': self.htext} - self.parts = [] - for i in range(len(body)): - p = MimeViewer(self.frame, - '%s.%d' % (title, i+1), - body[i]) - self.parts.append(p) - self.btext = None - self.collapsed = 1 - def pack(self): - self.frame.pack(self.frame.packing) - def destroy(self): - self.frame.destroy() - def show(self): - if self.collapsed: - self.button.invoke() - def toggle(self): - if self.collapsed: - self.explode() - else: - self.collapse() - def collapse(self): - self.collapsed = 1 - for comp in self.htext, self.btext, self.pad: - if comp: - comp.forget() - if self.parts: - for part in self.parts: - part.frame.forget() - self.frame.pack({'expand': 0}) - def explode(self): - self.collapsed = 0 - for comp in self.htext, self.btext, self.pad: - if comp: comp.pack(comp.packing) - if self.parts: - for part in self.parts: - part.pack() - self.frame.pack({'expand': 1}) - -def countlines(str, limit): - i = 0 - n = 0 - while n < limit: - i = str.find('\n', i) - if i < 0: break - n = n+1 - i = i+1 - return n - -def main(): - opts, args = getopt.getopt(sys.argv[1:], '') - for o, a in opts: - pass - message = None - folder = 'inbox' - for arg in args: - if arg[:1] == '+': - folder = arg[1:] - else: - message = int(arg) - - mh = mailbox.MH(MBOXPATH) - f = mh.get_folder(folder) - if message is None: - message = getcurrent(f) - m = mailbox.MHMessage(f.get(message)) - - root = Tk() - tk = root.tk - - top = MimeViewer(root, '+%s/%d' % (folder, message), m) - top.pack() - top.show() - - root.minsize(1, 1) - - tk.mainloop() - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/newmenubardemo.py b/Demo/tkinter/guido/newmenubardemo.py deleted file mode 100644 index 09ac566..0000000 --- a/Demo/tkinter/guido/newmenubardemo.py +++ /dev/null @@ -1,47 +0,0 @@ -#! /usr/bin/env python3 - -"""Play with the new Tk 8.0 toplevel menu option.""" - -from tkinter import * - -class App: - - def __init__(self, master): - self.master = master - - self.menubar = Menu(self.master) - - self.filemenu = Menu(self.menubar) - - self.filemenu.add_command(label="New") - self.filemenu.add_command(label="Open...") - self.filemenu.add_command(label="Close") - self.filemenu.add_separator() - self.filemenu.add_command(label="Quit", command=self.master.quit) - - self.editmenu = Menu(self.menubar) - - self.editmenu.add_command(label="Cut") - self.editmenu.add_command(label="Copy") - self.editmenu.add_command(label="Paste") - - self.helpmenu = Menu(self.menubar, name='help') - - self.helpmenu.add_command(label="About...") - - self.menubar.add_cascade(label="File", menu=self.filemenu) - self.menubar.add_cascade(label="Edit", menu=self.editmenu) - self.menubar.add_cascade(label="Help", menu=self.helpmenu) - - self.top = Toplevel(menu=self.menubar) - - # Rest of app goes here... - -def main(): - root = Tk() - root.withdraw() - app = App(root) - root.mainloop() - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/optionmenu.py b/Demo/tkinter/guido/optionmenu.py deleted file mode 100644 index 1e72aa5..0000000 --- a/Demo/tkinter/guido/optionmenu.py +++ /dev/null @@ -1,27 +0,0 @@ -# option menu sample (Fredrik Lundh, September 1997) - -from tkinter import * - -root = Tk() - -# -# standard usage - -var1 = StringVar() -var1.set("One") # default selection - -menu1 = OptionMenu(root, var1, "One", "Two", "Three") -menu1.pack() - -# -# initialize from a sequence - -CHOICES = "Aah", "Bee", "Cee", "Dee", "Eff" - -var2 = StringVar() -var2.set(CHOICES[0]) - -menu2 = OptionMenu(root, var2, *CHOICES) -menu2.pack() - -root.mainloop() diff --git a/Demo/tkinter/guido/paint.py b/Demo/tkinter/guido/paint.py deleted file mode 100644 index 65f2353..0000000 --- a/Demo/tkinter/guido/paint.py +++ /dev/null @@ -1,60 +0,0 @@ -""""Paint program by Dave Michell. - -Subject: tkinter "paint" example -From: Dave Mitchell -To: python-list@cwi.nl -Date: Fri, 23 Jan 1998 12:18:05 -0500 (EST) - - Not too long ago (last week maybe?) someone posted a request -for an example of a paint program using Tkinter. Try as I might -I can't seem to find it in the archive, so i'll just post mine -here and hope that the person who requested it sees this! - - All this does is put up a canvas and draw a smooth black line -whenever you have the mouse button down, but hopefully it will -be enough to start with.. It would be easy enough to add some -options like other shapes or colors... - - yours, - dave mitchell - davem@magnet.com -""" - -from tkinter import * - -"""paint.py: not exactly a paint program.. just a smooth line drawing demo.""" - -b1 = "up" -xold, yold = None, None - -def main(): - root = Tk() - drawing_area = Canvas(root) - drawing_area.pack() - drawing_area.bind("", motion) - drawing_area.bind("", b1down) - drawing_area.bind("", b1up) - root.mainloop() - -def b1down(event): - global b1 - b1 = "down" # you only want to draw when the button is down - # because "Motion" events happen -all the time- - -def b1up(event): - global b1, xold, yold - b1 = "up" - xold = None # reset the line when you let go of the button - yold = None - -def motion(event): - if b1 == "down": - global xold, yold - if xold is not None and yold is not None: - event.widget.create_line(xold,yold,event.x,event.y,smooth=TRUE) - # here's where you draw it. smooth. neat. - xold = event.x - yold = event.y - -if __name__ == "__main__": - main() diff --git a/Demo/tkinter/guido/rmt.py b/Demo/tkinter/guido/rmt.py deleted file mode 100755 index d11edb0..0000000 --- a/Demo/tkinter/guido/rmt.py +++ /dev/null @@ -1,159 +0,0 @@ -#! /usr/bin/env python3 - -# A Python program implementing rmt, an application for remotely -# controlling other Tk applications. -# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.5-8, pp. 273-276. - -# Note that because of forward references in the original, we -# sometimes delay bindings until after the corresponding procedure is -# defined. We also introduce names for some unnamed code blocks in -# the original because of restrictions on lambda forms in Python. - -# XXX This should be written in a more Python-like style!!! - -from tkinter import * -import sys - -# 1. Create basic application structure: menu bar on top of -# text widget, scrollbar on right. - -root = Tk() -tk = root.tk -mBar = Frame(root, relief=RAISED, borderwidth=2) -mBar.pack(fill=X) - -f = Frame(root) -f.pack(expand=1, fill=BOTH) -s = Scrollbar(f, relief=FLAT) -s.pack(side=RIGHT, fill=Y) -t = Text(f, relief=RAISED, borderwidth=2, yscrollcommand=s.set, setgrid=1) -t.pack(side=LEFT, fill=BOTH, expand=1) -t.tag_config('bold') -s['command'] = t.yview - -root.title('Tk Remote Controller') -root.iconname('Tk Remote') - -# 2. Create menu button and menus. - -file = Menubutton(mBar, text='File', underline=0) -file.pack(side=LEFT) -file_m = Menu(file) -file['menu'] = file_m -file_m_apps = Menu(file_m, tearoff=0) -file_m.add_cascade(label='Select Application', underline=0, - menu=file_m_apps) -file_m.add_command(label='Quit', underline=0, command=sys.exit) - -# 3. Create bindings for text widget to allow commands to be -# entered and information to be selected. New characters -# can only be added at the end of the text (can't ever move -# insertion point). - -def single1(e): - x = e.x - y = e.y - t.setvar('tk_priv(selectMode)', 'char') - t.mark_set('anchor', At(x, y)) - # Should focus W -t.bind('<1>', single1) - -def double1(e): - x = e.x - y = e.y - t.setvar('tk_priv(selectMode)', 'word') - t.tk_textSelectTo(At(x, y)) -t.bind('', double1) - -def triple1(e): - x = e.x - y = e.y - t.setvar('tk_priv(selectMode)', 'line') - t.tk_textSelectTo(At(x, y)) -t.bind('', triple1) - -def returnkey(e): - t.insert(AtInsert(), '\n') - invoke() -t.bind('', returnkey) - -def controlv(e): - t.insert(AtInsert(), t.selection_get()) - t.yview_pickplace(AtInsert()) - if t.index(AtInsert())[-2:] == '.0': - invoke() -t.bind('', controlv) - -# 4. Procedure to backspace over one character, as long as -# the character isn't part of the prompt. - -def backspace(e): - if t.index('promptEnd') != t.index('insert - 1 char'): - t.delete('insert - 1 char', AtInsert()) - t.yview_pickplace(AtInsert()) -t.bind('', backspace) -t.bind('', backspace) -t.bind('', backspace) - - -# 5. Procedure that's invoked when return is typed: if -# there's not yet a complete command (e.g. braces are open) -# then do nothing. Otherwise, execute command (locally or -# remotely), output the result or error message, and issue -# a new prompt. - -def invoke(): - cmd = t.get('promptEnd + 1 char', AtInsert()) - if t.getboolean(tk.call('info', 'complete', cmd)): # XXX - if app == root.winfo_name(): - msg = tk.call('eval', cmd) # XXX - else: - msg = t.send(app, cmd) - if msg: - t.insert(AtInsert(), msg + '\n') - prompt() - t.yview_pickplace(AtInsert()) - -def prompt(): - t.insert(AtInsert(), app + ': ') - t.mark_set('promptEnd', 'insert - 1 char') - t.tag_add('bold', 'insert linestart', 'promptEnd') - -# 6. Procedure to select a new application. Also changes -# the prompt on the current command line to reflect the new -# name. - -def newApp(appName): - global app - app = appName - t.delete('promptEnd linestart', 'promptEnd') - t.insert('promptEnd', appName + ':') - t.tag_add('bold', 'promptEnd linestart', 'promptEnd') - -def fillAppsMenu(): - file_m_apps.add('command') - file_m_apps.delete(0, 'last') - names = root.winfo_interps() - names = list(names) # convert tuple to list - names.sort() - for name in names: - try: - root.send(name, 'winfo name .') - except TclError: - # Inoperative window -- ignore it - pass - else: - file_m_apps.add_command( - label=name, - command=lambda name=name: newApp(name)) - -file_m_apps['postcommand'] = fillAppsMenu -mBar.tk_menuBar(file) - -# 7. Miscellaneous initialization. - -app = root.winfo_name() -prompt() -t.focus() - -root.mainloop() diff --git a/Demo/tkinter/guido/shell_window.py b/Demo/tkinter/guido/shell_window.py deleted file mode 100644 index c5a0401..0000000 --- a/Demo/tkinter/guido/shell_window.py +++ /dev/null @@ -1,146 +0,0 @@ -import os -import sys -from tkinter import * -from tkinter.scrolledtext import ScrolledText -from tkinter.dialog import Dialog -import signal - -BUFSIZE = 512 - -class ShellWindow(ScrolledText): - - def __init__(self, master=None, shell=None, **cnf): - if not shell: - try: - shell = os.environ['SHELL'] - except KeyError: - shell = '/bin/sh' - shell = shell + ' -i' - args = shell.split() - shell = args[0] - - ScrolledText.__init__(self, master, **cnf) - self.pos = '1.0' - self.bind('', self.inputhandler) - self.bind('', self.sigint) - self.bind('', self.sigterm) - self.bind('', self.sigkill) - self.bind('', self.sendeof) - - self.pid, self.fromchild, self.tochild = spawn(shell, args) - self.tk.createfilehandler(self.fromchild, READABLE, - self.outputhandler) - - def outputhandler(self, file, mask): - data = os.read(file, BUFSIZE).decode() - if not data: - self.tk.deletefilehandler(file) - pid, sts = os.waitpid(self.pid, 0) - print('pid', pid, 'status', sts) - self.pid = None - detail = sts>>8 - cause = sts & 0xff - if cause == 0: - msg = "exit status %d" % detail - else: - msg = "killed by signal %d" % (cause & 0x7f) - if cause & 0x80: - msg = msg + " -- core dumped" - Dialog(self.master, - text=msg, - title="Exit status", - bitmap='warning', - default=0, - strings=('OK',)) - return - self.insert(END, data) - self.pos = self.index("end - 1 char") - self.yview_pickplace(END) - - def inputhandler(self, *args): - if not self.pid: - self.no_process() - return "break" - self.insert(END, "\n") - line = self.get(self.pos, "end - 1 char") - self.pos = self.index(END) - os.write(self.tochild, line.encode()) - return "break" - - def sendeof(self, *args): - if not self.pid: - self.no_process() - return "break" - os.close(self.tochild) - return "break" - - def sendsig(self, sig): - if not self.pid: - self.no_process() - return "break" - os.kill(self.pid, sig) - return "break" - - def sigint(self, *args): - return self.sendsig(signal.SIGINT) - - def sigquit(self, *args): - return self.sendsig(signal.SIGQUIT) - - def sigterm(self, *args): - return self.sendsig(signal.SIGTERM) - - def sigkill(self, *args): - return self.sendsig(signal.SIGKILL) - - def no_process(self): - Dialog(self.master, - text="No active process", - title="No process", - bitmap='error', - default=0, - strings=('OK',)) - -MAXFD = 100 # Max number of file descriptors (os.getdtablesize()???) - -def spawn(prog, args): - p2cread, p2cwrite = os.pipe() - c2pread, c2pwrite = os.pipe() - pid = os.fork() - if pid == 0: - # Child - for i in 0, 1, 2: - try: - os.close(i) - except os.error: - pass - if os.dup(p2cread) != 0: - sys.stderr.write('popen2: bad read dup\n') - if os.dup(c2pwrite) != 1: - sys.stderr.write('popen2: bad write dup\n') - if os.dup(c2pwrite) != 2: - sys.stderr.write('popen2: bad write dup\n') - os.closerange(3, MAXFD) - try: - os.execvp(prog, args) - finally: - sys.stderr.write('execvp failed\n') - os._exit(1) - os.close(p2cread) - os.close(c2pwrite) - return pid, c2pread, p2cwrite - -def test(): - shell = ' '.join(sys.argv[1: ]) - root = Tk() - root.minsize(1, 1) - if shell: - w = ShellWindow(root, shell=shell) - else: - w = ShellWindow(root) - w.pack(expand=1, fill=BOTH) - w.focus_set() - w.tk.mainloop() - -if __name__ == '__main__': - test() diff --git a/Demo/tkinter/guido/solitaire.py b/Demo/tkinter/guido/solitaire.py deleted file mode 100755 index d0f5dee..0000000 --- a/Demo/tkinter/guido/solitaire.py +++ /dev/null @@ -1,626 +0,0 @@ -#! /usr/bin/env python3 - -"""Solitaire game, much like the one that comes with MS Windows. - -Limitations: - -- No cute graphical images for the playing cards faces or backs. -- No scoring or timer. -- No undo. -- No option to turn 3 cards at a time. -- No keyboard shortcuts. -- Less fancy animation when you win. -- The determination of which stack you drag to is more relaxed. - -Apology: - -I'm not much of a card player, so my terminology in these comments may -at times be a little unusual. If you have suggestions, please let me -know! - -""" - -# Imports - -import random - -from tkinter import * -from canvasevents import Group - - -# Constants determining the size and lay-out of cards and stacks. We -# work in a "grid" where each card/stack is surrounded by MARGIN -# pixels of space on each side, so adjacent stacks are separated by -# 2*MARGIN pixels. OFFSET is the offset used for displaying the -# face down cards in the row stacks. - -CARDWIDTH = 100 -CARDHEIGHT = 150 -MARGIN = 10 -XSPACING = CARDWIDTH + 2*MARGIN -YSPACING = CARDHEIGHT + 4*MARGIN -OFFSET = 5 - -# The background color, green to look like a playing table. The -# standard green is way too bright, and dark green is way to dark, so -# we use something in between. (There are a few more colors that -# could be customized, but they are less controversial.) - -BACKGROUND = '#070' - - -# Suits and colors. The values of the symbolic suit names are the -# strings used to display them (you change these and VALNAMES to -# internationalize the game). The COLOR dictionary maps suit names to -# colors (red and black) which must be Tk color names. The keys() of -# the COLOR dictionary conveniently provides us with a list of all -# suits (in arbitrary order). - -HEARTS = 'Heart' -DIAMONDS = 'Diamond' -CLUBS = 'Club' -SPADES = 'Spade' - -RED = 'red' -BLACK = 'black' - -COLOR = {} -for s in (HEARTS, DIAMONDS): - COLOR[s] = RED -for s in (CLUBS, SPADES): - COLOR[s] = BLACK - -ALLSUITS = list(COLOR.keys()) -NSUITS = len(ALLSUITS) - - -# Card values are 1-13. We also define symbolic names for the picture -# cards. ALLVALUES is a list of all card values. - -ACE = 1 -JACK = 11 -QUEEN = 12 -KING = 13 -ALLVALUES = range(1, 14) # (one more than the highest value) -NVALUES = len(ALLVALUES) - - -# VALNAMES is a list that maps a card value to string. It contains a -# dummy element at index 0 so it can be indexed directly with the card -# value. - -VALNAMES = ["", "A"] + list(map(str, range(2, 11))) + ["J", "Q", "K"] - - -# Solitaire constants. The only one I can think of is the number of -# row stacks. - -NROWS = 7 - - -# The rest of the program consists of class definitions. These are -# further described in their documentation strings. - - -class Card: - - """A playing card. - - A card doesn't record to which stack it belongs; only the stack - records this (it turns out that we always know this from the - context, and this saves a ``double update'' with potential for - inconsistencies). - - Public methods: - - moveto(x, y) -- move the card to an absolute position - moveby(dx, dy) -- move the card by a relative offset - tkraise() -- raise the card to the top of its stack - showface(), showback() -- turn the card face up or down & raise it - - Public read-only instance variables: - - suit, value, color -- the card's suit, value and color - face_shown -- true when the card is shown face up, else false - - Semi-public read-only instance variables (XXX should be made - private): - - group -- the Canvas.Group representing the card - x, y -- the position of the card's top left corner - - Private instance variables: - - __back, __rect, __text -- the canvas items making up the card - - (To show the card face up, the text item is placed in front of - rect and the back is placed behind it. To show it face down, this - is reversed. The card is created face down.) - - """ - - def __init__(self, suit, value, canvas): - """Card constructor. - - Arguments are the card's suit and value, and the canvas widget. - - The card is created at position (0, 0), with its face down - (adding it to a stack will position it according to that - stack's rules). - - """ - self.suit = suit - self.value = value - self.color = COLOR[suit] - self.face_shown = 0 - - self.x = self.y = 0 - self.canvas = canvas - self.group = Group(canvas) - - text = "%s %s" % (VALNAMES[value], suit) - self.__text = canvas.create_text(CARDWIDTH // 2, 0, anchor=N, - fill=self.color, text=text) - self.group.addtag_withtag(self.__text) - - self.__rect = canvas.create_rectangle(0, 0, CARDWIDTH, CARDHEIGHT, - outline='black', fill='white') - self.group.addtag_withtag(self.__rect) - - self.__back = canvas.create_rectangle(MARGIN, MARGIN, - CARDWIDTH - MARGIN, - CARDHEIGHT - MARGIN, - outline='black', fill='blue') - self.group.addtag_withtag(self.__back) - - def __repr__(self): - """Return a string for debug print statements.""" - return "Card(%r, %r)" % (self.suit, self.value) - - def moveto(self, x, y): - """Move the card to absolute position (x, y).""" - self.moveby(x - self.x, y - self.y) - - def moveby(self, dx, dy): - """Move the card by (dx, dy).""" - self.x = self.x + dx - self.y = self.y + dy - self.group.move(dx, dy) - - def tkraise(self): - """Raise the card above all other objects in its canvas.""" - self.group.tkraise() - - def showface(self): - """Turn the card's face up.""" - self.tkraise() - self.canvas.tag_raise(self.__rect) - self.canvas.tag_raise(self.__text) - self.face_shown = 1 - - def showback(self): - """Turn the card's face down.""" - self.tkraise() - self.canvas.tag_raise(self.__rect) - self.canvas.tag_raise(self.__back) - self.face_shown = 0 - - -class Stack: - - """A generic stack of cards. - - This is used as a base class for all other stacks (e.g. the deck, - the suit stacks, and the row stacks). - - Public methods: - - add(card) -- add a card to the stack - delete(card) -- delete a card from the stack - showtop() -- show the top card (if any) face up - deal() -- delete and return the top card, or None if empty - - Method that subclasses may override: - - position(card) -- move the card to its proper (x, y) position - - The default position() method places all cards at the stack's - own (x, y) position. - - userclickhandler(), userdoubleclickhandler() -- called to do - subclass specific things on single and double clicks - - The default user (single) click handler shows the top card - face up. The default user double click handler calls the user - single click handler. - - usermovehandler(cards) -- called to complete a subpile move - - The default user move handler moves all moved cards back to - their original position (by calling the position() method). - - Private methods: - - clickhandler(event), doubleclickhandler(event), - motionhandler(event), releasehandler(event) -- event handlers - - The default event handlers turn the top card of the stack with - its face up on a (single or double) click, and also support - moving a subpile around. - - startmoving(event) -- begin a move operation - finishmoving() -- finish a move operation - - """ - - def __init__(self, x, y, game=None): - """Stack constructor. - - Arguments are the stack's nominal x and y position (the top - left corner of the first card placed in the stack), and the - game object (which is used to get the canvas; subclasses use - the game object to find other stacks). - - """ - self.x = x - self.y = y - self.game = game - self.cards = [] - self.group = Group(self.game.canvas) - self.group.bind('<1>', self.clickhandler) - self.group.bind('', self.doubleclickhandler) - self.group.bind('', self.motionhandler) - self.group.bind('', self.releasehandler) - self.makebottom() - - def makebottom(self): - pass - - def __repr__(self): - """Return a string for debug print statements.""" - return "%s(%d, %d)" % (self.__class__.__name__, self.x, self.y) - - # Public methods - - def add(self, card): - self.cards.append(card) - card.tkraise() - self.position(card) - self.group.addtag_withtag(card.group) - - def delete(self, card): - self.cards.remove(card) - card.group.dtag(self.group) - - def showtop(self): - if self.cards: - self.cards[-1].showface() - - def deal(self): - if not self.cards: - return None - card = self.cards[-1] - self.delete(card) - return card - - # Subclass overridable methods - - def position(self, card): - card.moveto(self.x, self.y) - - def userclickhandler(self): - self.showtop() - - def userdoubleclickhandler(self): - self.userclickhandler() - - def usermovehandler(self, cards): - for card in cards: - self.position(card) - - # Event handlers - - def clickhandler(self, event): - self.finishmoving() # In case we lost an event - self.userclickhandler() - self.startmoving(event) - - def motionhandler(self, event): - self.keepmoving(event) - - def releasehandler(self, event): - self.keepmoving(event) - self.finishmoving() - - def doubleclickhandler(self, event): - self.finishmoving() # In case we lost an event - self.userdoubleclickhandler() - self.startmoving(event) - - # Move internals - - moving = None - - def startmoving(self, event): - self.moving = None - tags = self.game.canvas.gettags('current') - for i in range(len(self.cards)): - card = self.cards[i] - if card.group.tag in tags: - break - else: - return - if not card.face_shown: - return - self.moving = self.cards[i:] - self.lastx = event.x - self.lasty = event.y - for card in self.moving: - card.tkraise() - - def keepmoving(self, event): - if not self.moving: - return - dx = event.x - self.lastx - dy = event.y - self.lasty - self.lastx = event.x - self.lasty = event.y - if dx or dy: - for card in self.moving: - card.moveby(dx, dy) - - def finishmoving(self): - cards = self.moving - self.moving = None - if cards: - self.usermovehandler(cards) - - -class Deck(Stack): - - """The deck is a stack with support for shuffling. - - New methods: - - fill() -- create the playing cards - shuffle() -- shuffle the playing cards - - A single click moves the top card to the game's open deck and - moves it face up; if we're out of cards, it moves the open deck - back to the deck. - - """ - - def makebottom(self): - bottom = self.game.canvas.create_rectangle(self.x, self.y, - self.x + CARDWIDTH, self.y + CARDHEIGHT, outline='black', - fill=BACKGROUND) - self.group.addtag_withtag(bottom) - - def fill(self): - for suit in ALLSUITS: - for value in ALLVALUES: - self.add(Card(suit, value, self.game.canvas)) - - def shuffle(self): - n = len(self.cards) - newcards = [] - for i in randperm(n): - newcards.append(self.cards[i]) - self.cards = newcards - - def userclickhandler(self): - opendeck = self.game.opendeck - card = self.deal() - if not card: - while 1: - card = opendeck.deal() - if not card: - break - self.add(card) - card.showback() - else: - self.game.opendeck.add(card) - card.showface() - - -def randperm(n): - """Function returning a random permutation of range(n).""" - r = list(range(n)) - x = [] - while r: - i = random.choice(r) - x.append(i) - r.remove(i) - return x - - -class OpenStack(Stack): - - def acceptable(self, cards): - return 0 - - def usermovehandler(self, cards): - card = cards[0] - stack = self.game.closeststack(card) - if not stack or stack is self or not stack.acceptable(cards): - Stack.usermovehandler(self, cards) - else: - for card in cards: - self.delete(card) - stack.add(card) - self.game.wincheck() - - def userdoubleclickhandler(self): - if not self.cards: - return - card = self.cards[-1] - if not card.face_shown: - self.userclickhandler() - return - for s in self.game.suits: - if s.acceptable([card]): - self.delete(card) - s.add(card) - self.game.wincheck() - break - - -class SuitStack(OpenStack): - - def makebottom(self): - bottom = self.game.canvas.create_rectangle(self.x, self.y, - self.x + CARDWIDTH, self.y + CARDHEIGHT, outline='black', fill='') - - def userclickhandler(self): - pass - - def userdoubleclickhandler(self): - pass - - def acceptable(self, cards): - if len(cards) != 1: - return 0 - card = cards[0] - if not self.cards: - return card.value == ACE - topcard = self.cards[-1] - return card.suit == topcard.suit and card.value == topcard.value + 1 - - -class RowStack(OpenStack): - - def acceptable(self, cards): - card = cards[0] - if not self.cards: - return card.value == KING - topcard = self.cards[-1] - if not topcard.face_shown: - return 0 - return card.color != topcard.color and card.value == topcard.value - 1 - - def position(self, card): - y = self.y - for c in self.cards: - if c == card: - break - if c.face_shown: - y = y + 2*MARGIN - else: - y = y + OFFSET - card.moveto(self.x, y) - - -class Solitaire: - - def __init__(self, master): - self.master = master - - self.canvas = Canvas(self.master, - background=BACKGROUND, - highlightthickness=0, - width=NROWS*XSPACING, - height=3*YSPACING + 20 + MARGIN) - self.canvas.pack(fill=BOTH, expand=TRUE) - - self.dealbutton = Button(self.canvas, - text="Deal", - highlightthickness=0, - background=BACKGROUND, - activebackground="green", - command=self.deal) - self.canvas.create_window(MARGIN, 3 * YSPACING + 20, - window=self.dealbutton, anchor=SW) - - x = MARGIN - y = MARGIN - - self.deck = Deck(x, y, self) - - x = x + XSPACING - self.opendeck = OpenStack(x, y, self) - - x = x + XSPACING - self.suits = [] - for i in range(NSUITS): - x = x + XSPACING - self.suits.append(SuitStack(x, y, self)) - - x = MARGIN - y = y + YSPACING - - self.rows = [] - for i in range(NROWS): - self.rows.append(RowStack(x, y, self)) - x = x + XSPACING - - self.openstacks = [self.opendeck] + self.suits + self.rows - - self.deck.fill() - self.deal() - - def wincheck(self): - for s in self.suits: - if len(s.cards) != NVALUES: - return - self.win() - self.deal() - - def win(self): - """Stupid animation when you win.""" - cards = [] - for s in self.openstacks: - cards = cards + s.cards - while cards: - card = random.choice(cards) - cards.remove(card) - self.animatedmoveto(card, self.deck) - - def animatedmoveto(self, card, dest): - for i in range(10, 0, -1): - dx, dy = (dest.x-card.x)//i, (dest.y-card.y)//i - card.moveby(dx, dy) - self.master.update_idletasks() - - def closeststack(self, card): - closest = None - cdist = 999999999 - # Since we only compare distances, - # we don't bother to take the square root. - for stack in self.openstacks: - dist = (stack.x - card.x)**2 + (stack.y - card.y)**2 - if dist < cdist: - closest = stack - cdist = dist - return closest - - def deal(self): - self.reset() - self.deck.shuffle() - for i in range(NROWS): - for r in self.rows[i:]: - card = self.deck.deal() - r.add(card) - for r in self.rows: - r.showtop() - - def reset(self): - for stack in self.openstacks: - while 1: - card = stack.deal() - if not card: - break - self.deck.add(card) - card.showback() - - -# Main function, run when invoked as a stand-alone Python program. - -def main(): - root = Tk() - game = Solitaire(root) - root.protocol('WM_DELETE_WINDOW', root.quit) - root.mainloop() - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/sortvisu.py b/Demo/tkinter/guido/sortvisu.py deleted file mode 100644 index 4173121..0000000 --- a/Demo/tkinter/guido/sortvisu.py +++ /dev/null @@ -1,636 +0,0 @@ -#! /usr/bin/env python3 - -"""Sorting algorithms visualizer using Tkinter. - -This module is comprised of three ``components'': - -- an array visualizer with methods that implement basic sorting -operations (compare, swap) as well as methods for ``annotating'' the -sorting algorithm (e.g. to show the pivot element); - -- a number of sorting algorithms (currently quicksort, insertion sort, -selection sort and bubble sort, as well as a randomization function), -all using the array visualizer for its basic operations and with calls -to its annotation methods; - -- and a ``driver'' class which can be used as a Grail applet or as a -stand-alone application. - -""" - -from tkinter import * -import random - - -XGRID = 10 -YGRID = 10 -WIDTH = 6 - - -class Array: - - class Cancelled(BaseException): - pass - - def __init__(self, master, data=None): - self.master = master - self.frame = Frame(self.master) - self.frame.pack(fill=X) - self.label = Label(self.frame) - self.label.pack() - self.canvas = Canvas(self.frame) - self.canvas.pack() - self.report = Label(self.frame) - self.report.pack() - self.left = self.canvas.create_line(0, 0, 0, 0) - self.right = self.canvas.create_line(0, 0, 0, 0) - self.pivot = self.canvas.create_line(0, 0, 0, 0) - self.items = [] - self.size = self.maxvalue = 0 - if data: - self.setdata(data) - - def setdata(self, data): - olditems = self.items - self.items = [] - for item in olditems: - item.delete() - self.size = len(data) - self.maxvalue = max(data) - self.canvas.config(width=(self.size+1)*XGRID, - height=(self.maxvalue+1)*YGRID) - for i in range(self.size): - self.items.append(ArrayItem(self, i, data[i])) - self.reset("Sort demo, size %d" % self.size) - - speed = "normal" - - def setspeed(self, speed): - self.speed = speed - - def destroy(self): - self.frame.destroy() - - in_mainloop = 0 - stop_mainloop = 0 - - def cancel(self): - self.stop_mainloop = 1 - if self.in_mainloop: - self.master.quit() - - def step(self): - if self.in_mainloop: - self.master.quit() - - def wait(self, msecs): - if self.speed == "fastest": - msecs = 0 - elif self.speed == "fast": - msecs = msecs//10 - elif self.speed == "single-step": - msecs = 1000000000 - if not self.stop_mainloop: - self.master.update() - id = self.master.after(msecs, self.master.quit) - self.in_mainloop = 1 - self.master.mainloop() - self.master.after_cancel(id) - self.in_mainloop = 0 - if self.stop_mainloop: - self.stop_mainloop = 0 - self.message("Cancelled") - raise Array.Cancelled - - def getsize(self): - return self.size - - def show_partition(self, first, last): - for i in range(self.size): - item = self.items[i] - if first <= i < last: - self.canvas.itemconfig(item, fill='red') - else: - self.canvas.itemconfig(item, fill='orange') - self.hide_left_right_pivot() - - def hide_partition(self): - for i in range(self.size): - item = self.items[i] - self.canvas.itemconfig(item, fill='red') - self.hide_left_right_pivot() - - def show_left(self, left): - if not 0 <= left < self.size: - self.hide_left() - return - x1, y1, x2, y2 = self.items[left].position() -## top, bot = HIRO - self.canvas.coords(self.left, (x1 - 2, 0, x1 - 2, 9999)) - self.master.update() - - def show_right(self, right): - if not 0 <= right < self.size: - self.hide_right() - return - x1, y1, x2, y2 = self.items[right].position() - self.canvas.coords(self.right, (x2 + 2, 0, x2 + 2, 9999)) - self.master.update() - - def hide_left_right_pivot(self): - self.hide_left() - self.hide_right() - self.hide_pivot() - - def hide_left(self): - self.canvas.coords(self.left, (0, 0, 0, 0)) - - def hide_right(self): - self.canvas.coords(self.right, (0, 0, 0, 0)) - - def show_pivot(self, pivot): - x1, y1, x2, y2 = self.items[pivot].position() - self.canvas.coords(self.pivot, (0, y1 - 2, 9999, y1 - 2)) - - def hide_pivot(self): - self.canvas.coords(self.pivot, (0, 0, 0, 0)) - - def swap(self, i, j): - if i == j: return - self.countswap() - item = self.items[i] - other = self.items[j] - self.items[i], self.items[j] = other, item - item.swapwith(other) - - def compare(self, i, j): - self.countcompare() - item = self.items[i] - other = self.items[j] - return item.compareto(other) - - def reset(self, msg): - self.ncompares = 0 - self.nswaps = 0 - self.message(msg) - self.updatereport() - self.hide_partition() - - def message(self, msg): - self.label.config(text=msg) - - def countswap(self): - self.nswaps = self.nswaps + 1 - self.updatereport() - - def countcompare(self): - self.ncompares = self.ncompares + 1 - self.updatereport() - - def updatereport(self): - text = "%d cmps, %d swaps" % (self.ncompares, self.nswaps) - self.report.config(text=text) - - -class ArrayItem: - - def __init__(self, array, index, value): - self.array = array - self.index = index - self.value = value - self.canvas = array.canvas - x1, y1, x2, y2 = self.position() - self.item_id = array.canvas.create_rectangle(x1, y1, x2, y2, - fill='red', outline='black', width=1) - self.canvas.tag_bind(self.item_id, '', self.mouse_down) - self.canvas.tag_bind(self.item_id, '', self.mouse_move) - self.canvas.tag_bind(self.item_id, '', self.mouse_up) - - def delete(self): - item_id = self.item_id - self.array = None - self.item_id = None - self.canvas.delete(item_id) - - def mouse_down(self, event): - self.lastx = event.x - self.lasty = event.y - self.origx = event.x - self.origy = event.y - self.canvas.tag_raise(self.item_id) - - def mouse_move(self, event): - self.canvas.move(self.item_id, - event.x - self.lastx, event.y - self.lasty) - self.lastx = event.x - self.lasty = event.y - - def mouse_up(self, event): - i = self.nearestindex(event.x) - if i >= self.array.getsize(): - i = self.array.getsize() - 1 - if i < 0: - i = 0 - other = self.array.items[i] - here = self.index - self.array.items[here], self.array.items[i] = other, self - self.index = i - x1, y1, x2, y2 = self.position() - self.canvas.coords(self.item_id, (x1, y1, x2, y2)) - other.setindex(here) - - def setindex(self, index): - nsteps = steps(self.index, index) - if not nsteps: return - if self.array.speed == "fastest": - nsteps = 0 - oldpts = self.position() - self.index = index - newpts = self.position() - trajectory = interpolate(oldpts, newpts, nsteps) - self.canvas.tag_raise(self.item_id) - for pts in trajectory: - self.canvas.coords(self.item_id, pts) - self.array.wait(50) - - def swapwith(self, other): - nsteps = steps(self.index, other.index) - if not nsteps: return - if self.array.speed == "fastest": - nsteps = 0 - myoldpts = self.position() - otheroldpts = other.position() - self.index, other.index = other.index, self.index - mynewpts = self.position() - othernewpts = other.position() - myfill = self.canvas.itemcget(self.item_id, 'fill') - otherfill = self.canvas.itemcget(other.item_id, 'fill') - self.canvas.itemconfig(self.item_id, fill='green') - self.canvas.itemconfig(other.item_id, fill='yellow') - self.array.master.update() - if self.array.speed == "single-step": - self.canvas.coords(self.item_id, mynewpts) - self.canvas.coords(other.item_id, othernewpts) - self.array.master.update() - self.canvas.itemconfig(self.item_id, fill=myfill) - self.canvas.itemconfig(other.item_id, fill=otherfill) - self.array.wait(0) - return - mytrajectory = interpolate(myoldpts, mynewpts, nsteps) - othertrajectory = interpolate(otheroldpts, othernewpts, nsteps) - if self.value > other.value: - self.canvas.tag_raise(self.item_id) - self.canvas.tag_raise(other.item_id) - else: - self.canvas.tag_raise(other.item_id) - self.canvas.tag_raise(self.item_id) - try: - for i in range(len(mytrajectory)): - mypts = mytrajectory[i] - otherpts = othertrajectory[i] - self.canvas.coords(self.item_id, mypts) - self.canvas.coords(other.item_id, otherpts) - self.array.wait(50) - finally: - mypts = mytrajectory[-1] - otherpts = othertrajectory[-1] - self.canvas.coords(self.item_id, mypts) - self.canvas.coords(other.item_id, otherpts) - self.canvas.itemconfig(self.item_id, fill=myfill) - self.canvas.itemconfig(other.item_id, fill=otherfill) - - def compareto(self, other): - myfill = self.canvas.itemcget(self.item_id, 'fill') - otherfill = self.canvas.itemcget(other.item_id, 'fill') - if self.value < other.value: - myflash = 'white' - otherflash = 'black' - outcome = -1 - elif self.value > other.value: - myflash = 'black' - otherflash = 'white' - outcome = 1 - else: - myflash = otherflash = 'grey' - outcome = 0 - try: - self.canvas.itemconfig(self.item_id, fill=myflash) - self.canvas.itemconfig(other.item_id, fill=otherflash) - self.array.wait(500) - finally: - self.canvas.itemconfig(self.item_id, fill=myfill) - self.canvas.itemconfig(other.item_id, fill=otherfill) - return outcome - - def position(self): - x1 = (self.index+1)*XGRID - WIDTH//2 - x2 = x1+WIDTH - y2 = (self.array.maxvalue+1)*YGRID - y1 = y2 - (self.value)*YGRID - return x1, y1, x2, y2 - - def nearestindex(self, x): - return int(round(float(x)/XGRID)) - 1 - - -# Subroutines that don't need an object - -def steps(here, there): - nsteps = abs(here - there) - if nsteps <= 3: - nsteps = nsteps * 3 - elif nsteps <= 5: - nsteps = nsteps * 2 - elif nsteps > 10: - nsteps = 10 - return nsteps - -def interpolate(oldpts, newpts, n): - if len(oldpts) != len(newpts): - raise ValueError("can't interpolate arrays of different length") - pts = [0]*len(oldpts) - res = [tuple(oldpts)] - for i in range(1, n): - for k in range(len(pts)): - pts[k] = oldpts[k] + (newpts[k] - oldpts[k])*i//n - res.append(tuple(pts)) - res.append(tuple(newpts)) - return res - - -# Various (un)sorting algorithms - -def uniform(array): - size = array.getsize() - array.setdata([(size+1)//2] * size) - array.reset("Uniform data, size %d" % size) - -def distinct(array): - size = array.getsize() - array.setdata(range(1, size+1)) - array.reset("Distinct data, size %d" % size) - -def randomize(array): - array.reset("Randomizing") - n = array.getsize() - for i in range(n): - j = random.randint(0, n-1) - array.swap(i, j) - array.message("Randomized") - -def insertionsort(array): - size = array.getsize() - array.reset("Insertion sort") - for i in range(1, size): - j = i-1 - while j >= 0: - if array.compare(j, j+1) <= 0: - break - array.swap(j, j+1) - j = j-1 - array.message("Sorted") - -def selectionsort(array): - size = array.getsize() - array.reset("Selection sort") - try: - for i in range(size): - array.show_partition(i, size) - for j in range(i+1, size): - if array.compare(i, j) > 0: - array.swap(i, j) - array.message("Sorted") - finally: - array.hide_partition() - -def bubblesort(array): - size = array.getsize() - array.reset("Bubble sort") - for i in range(size): - for j in range(1, size): - if array.compare(j-1, j) > 0: - array.swap(j-1, j) - array.message("Sorted") - -def quicksort(array): - size = array.getsize() - array.reset("Quicksort") - try: - stack = [(0, size)] - while stack: - first, last = stack[-1] - del stack[-1] - array.show_partition(first, last) - if last-first < 5: - array.message("Insertion sort") - for i in range(first+1, last): - j = i-1 - while j >= first: - if array.compare(j, j+1) <= 0: - break - array.swap(j, j+1) - j = j-1 - continue - array.message("Choosing pivot") - j, i, k = first, (first+last) // 2, last-1 - if array.compare(k, i) < 0: - array.swap(k, i) - if array.compare(k, j) < 0: - array.swap(k, j) - if array.compare(j, i) < 0: - array.swap(j, i) - pivot = j - array.show_pivot(pivot) - array.message("Pivot at left of partition") - array.wait(1000) - left = first - right = last - while 1: - array.message("Sweep right pointer") - right = right-1 - array.show_right(right) - while right > first and array.compare(right, pivot) >= 0: - right = right-1 - array.show_right(right) - array.message("Sweep left pointer") - left = left+1 - array.show_left(left) - while left < last and array.compare(left, pivot) <= 0: - left = left+1 - array.show_left(left) - if left > right: - array.message("End of partition") - break - array.message("Swap items") - array.swap(left, right) - array.message("Swap pivot back") - array.swap(pivot, right) - n1 = right-first - n2 = last-left - if n1 > 1: stack.append((first, right)) - if n2 > 1: stack.append((left, last)) - array.message("Sorted") - finally: - array.hide_partition() - -def demosort(array): - while 1: - for alg in [quicksort, insertionsort, selectionsort, bubblesort]: - randomize(array) - alg(array) - - -# Sort demo class -- usable as a Grail applet - -class SortDemo: - - def __init__(self, master, size=15): - self.master = master - self.size = size - self.busy = 0 - self.array = Array(self.master) - - self.botframe = Frame(master) - self.botframe.pack(side=BOTTOM) - self.botleftframe = Frame(self.botframe) - self.botleftframe.pack(side=LEFT, fill=Y) - self.botrightframe = Frame(self.botframe) - self.botrightframe.pack(side=RIGHT, fill=Y) - - self.b_qsort = Button(self.botleftframe, - text="Quicksort", command=self.c_qsort) - self.b_qsort.pack(fill=X) - self.b_isort = Button(self.botleftframe, - text="Insertion sort", command=self.c_isort) - self.b_isort.pack(fill=X) - self.b_ssort = Button(self.botleftframe, - text="Selection sort", command=self.c_ssort) - self.b_ssort.pack(fill=X) - self.b_bsort = Button(self.botleftframe, - text="Bubble sort", command=self.c_bsort) - self.b_bsort.pack(fill=X) - - # Terrible hack to overcome limitation of OptionMenu... - class MyIntVar(IntVar): - def __init__(self, master, demo): - self.demo = demo - IntVar.__init__(self, master) - def set(self, value): - IntVar.set(self, value) - if str(value) != '0': - self.demo.resize(value) - - self.v_size = MyIntVar(self.master, self) - self.v_size.set(size) - sizes = [1, 2, 3, 4] + list(range(5, 55, 5)) - if self.size not in sizes: - sizes.append(self.size) - sizes.sort() - self.m_size = OptionMenu(self.botleftframe, self.v_size, *sizes) - self.m_size.pack(fill=X) - - self.v_speed = StringVar(self.master) - self.v_speed.set("normal") - self.m_speed = OptionMenu(self.botleftframe, self.v_speed, - "single-step", "normal", "fast", "fastest") - self.m_speed.pack(fill=X) - - self.b_step = Button(self.botleftframe, - text="Step", command=self.c_step) - self.b_step.pack(fill=X) - - self.b_randomize = Button(self.botrightframe, - text="Randomize", command=self.c_randomize) - self.b_randomize.pack(fill=X) - self.b_uniform = Button(self.botrightframe, - text="Uniform", command=self.c_uniform) - self.b_uniform.pack(fill=X) - self.b_distinct = Button(self.botrightframe, - text="Distinct", command=self.c_distinct) - self.b_distinct.pack(fill=X) - self.b_demo = Button(self.botrightframe, - text="Demo", command=self.c_demo) - self.b_demo.pack(fill=X) - self.b_cancel = Button(self.botrightframe, - text="Cancel", command=self.c_cancel) - self.b_cancel.pack(fill=X) - self.b_cancel.config(state=DISABLED) - self.b_quit = Button(self.botrightframe, - text="Quit", command=self.c_quit) - self.b_quit.pack(fill=X) - - def resize(self, newsize): - if self.busy: - self.master.bell() - return - self.size = newsize - self.array.setdata(range(1, self.size+1)) - - def c_qsort(self): - self.run(quicksort) - - def c_isort(self): - self.run(insertionsort) - - def c_ssort(self): - self.run(selectionsort) - - def c_bsort(self): - self.run(bubblesort) - - def c_demo(self): - self.run(demosort) - - def c_randomize(self): - self.run(randomize) - - def c_uniform(self): - self.run(uniform) - - def c_distinct(self): - self.run(distinct) - - def run(self, func): - if self.busy: - self.master.bell() - return - self.busy = 1 - self.array.setspeed(self.v_speed.get()) - self.b_cancel.config(state=NORMAL) - try: - func(self.array) - except Array.Cancelled: - pass - self.b_cancel.config(state=DISABLED) - self.busy = 0 - - def c_cancel(self): - if not self.busy: - self.master.bell() - return - self.array.cancel() - - def c_step(self): - if not self.busy: - self.master.bell() - return - self.v_speed.set("single-step") - self.array.setspeed("single-step") - self.array.step() - - def c_quit(self): - if self.busy: - self.array.cancel() - self.master.after_idle(self.master.quit) - - -# Main program -- for stand-alone operation outside Grail - -def main(): - root = Tk() - demo = SortDemo(root) - root.protocol('WM_DELETE_WINDOW', demo.c_quit) - root.mainloop() - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/ss1.py b/Demo/tkinter/guido/ss1.py deleted file mode 100644 index 8b07489..0000000 --- a/Demo/tkinter/guido/ss1.py +++ /dev/null @@ -1,842 +0,0 @@ -"""SS1 -- a spreadsheet.""" - -import os -import re -import sys -import html -from xml.parsers import expat - -LEFT, CENTER, RIGHT = "LEFT", "CENTER", "RIGHT" - -def ljust(x, n): - return x.ljust(n) -def center(x, n): - return x.center(n) -def rjust(x, n): - return x.rjust(n) -align2action = {LEFT: ljust, CENTER: center, RIGHT: rjust} - -align2xml = {LEFT: "left", CENTER: "center", RIGHT: "right"} -xml2align = {"left": LEFT, "center": CENTER, "right": RIGHT} - -align2anchor = {LEFT: "w", CENTER: "center", RIGHT: "e"} - -def sum(seq): - total = 0 - for x in seq: - if x is not None: - total += x - return total - -class Sheet: - - def __init__(self): - self.cells = {} # {(x, y): cell, ...} - self.ns = dict( - cell = self.cellvalue, - cells = self.multicellvalue, - sum = sum, - ) - - def cellvalue(self, x, y): - cell = self.getcell(x, y) - if hasattr(cell, 'recalc'): - return cell.recalc(self.ns) - else: - return cell - - def multicellvalue(self, x1, y1, x2, y2): - if x1 > x2: - x1, x2 = x2, x1 - if y1 > y2: - y1, y2 = y2, y1 - seq = [] - for y in range(y1, y2+1): - for x in range(x1, x2+1): - seq.append(self.cellvalue(x, y)) - return seq - - def getcell(self, x, y): - return self.cells.get((x, y)) - - def setcell(self, x, y, cell): - assert x > 0 and y > 0 - assert isinstance(cell, BaseCell) - self.cells[x, y] = cell - - def clearcell(self, x, y): - try: - del self.cells[x, y] - except KeyError: - pass - - def clearcells(self, x1, y1, x2, y2): - for xy in self.selectcells(x1, y1, x2, y2): - del self.cells[xy] - - def clearrows(self, y1, y2): - self.clearcells(0, y1, sys.maxint, y2) - - def clearcolumns(self, x1, x2): - self.clearcells(x1, 0, x2, sys.maxint) - - def selectcells(self, x1, y1, x2, y2): - if x1 > x2: - x1, x2 = x2, x1 - if y1 > y2: - y1, y2 = y2, y1 - return [(x, y) for x, y in self.cells - if x1 <= x <= x2 and y1 <= y <= y2] - - def movecells(self, x1, y1, x2, y2, dx, dy): - if dx == 0 and dy == 0: - return - if x1 > x2: - x1, x2 = x2, x1 - if y1 > y2: - y1, y2 = y2, y1 - assert x1+dx > 0 and y1+dy > 0 - new = {} - for x, y in self.cells: - cell = self.cells[x, y] - if hasattr(cell, 'renumber'): - cell = cell.renumber(x1, y1, x2, y2, dx, dy) - if x1 <= x <= x2 and y1 <= y <= y2: - x += dx - y += dy - new[x, y] = cell - self.cells = new - - def insertrows(self, y, n): - assert n > 0 - self.movecells(0, y, sys.maxint, sys.maxint, 0, n) - - def deleterows(self, y1, y2): - if y1 > y2: - y1, y2 = y2, y1 - self.clearrows(y1, y2) - self.movecells(0, y2+1, sys.maxint, sys.maxint, 0, y1-y2-1) - - def insertcolumns(self, x, n): - assert n > 0 - self.movecells(x, 0, sys.maxint, sys.maxint, n, 0) - - def deletecolumns(self, x1, x2): - if x1 > x2: - x1, x2 = x2, x1 - self.clearcells(x1, x2) - self.movecells(x2+1, 0, sys.maxint, sys.maxint, x1-x2-1, 0) - - def getsize(self): - maxx = maxy = 0 - for x, y in self.cells: - maxx = max(maxx, x) - maxy = max(maxy, y) - return maxx, maxy - - def reset(self): - for cell in self.cells.values(): - if hasattr(cell, 'reset'): - cell.reset() - - def recalc(self): - self.reset() - for cell in self.cells.values(): - if hasattr(cell, 'recalc'): - cell.recalc(self.ns) - - def display(self): - maxx, maxy = self.getsize() - width, height = maxx+1, maxy+1 - colwidth = [1] * width - full = {} - # Add column heading labels in row 0 - for x in range(1, width): - full[x, 0] = text, alignment = colnum2name(x), RIGHT - colwidth[x] = max(colwidth[x], len(text)) - # Add row labels in column 0 - for y in range(1, height): - full[0, y] = text, alignment = str(y), RIGHT - colwidth[0] = max(colwidth[0], len(text)) - # Add sheet cells in columns with x>0 and y>0 - for (x, y), cell in self.cells.items(): - if x <= 0 or y <= 0: - continue - if hasattr(cell, 'recalc'): - cell.recalc(self.ns) - if hasattr(cell, 'format'): - text, alignment = cell.format() - assert isinstance(text, str) - assert alignment in (LEFT, CENTER, RIGHT) - else: - text = str(cell) - if isinstance(cell, str): - alignment = LEFT - else: - alignment = RIGHT - full[x, y] = (text, alignment) - colwidth[x] = max(colwidth[x], len(text)) - # Calculate the horizontal separator line (dashes and dots) - sep = "" - for x in range(width): - if sep: - sep += "+" - sep += "-"*colwidth[x] - # Now print The full grid - for y in range(height): - line = "" - for x in range(width): - text, alignment = full.get((x, y)) or ("", LEFT) - text = align2action[alignment](text, colwidth[x]) - if line: - line += '|' - line += text - print(line) - if y == 0: - print(sep) - - def xml(self): - out = [''] - for (x, y), cell in self.cells.items(): - if hasattr(cell, 'xml'): - cellxml = cell.xml() - else: - cellxml = '%s' % html.escape(cell) - out.append('\n %s\n' % - (y, x, cellxml)) - out.append('') - return '\n'.join(out) - - def save(self, filename): - text = self.xml() - f = open(filename, "w") - f.write(text) - if text and not text.endswith('\n'): - f.write('\n') - f.close() - - def load(self, filename): - f = open(filename, 'rb') - SheetParser(self).parsefile(f) - f.close() - -class SheetParser: - - def __init__(self, sheet): - self.sheet = sheet - - def parsefile(self, f): - parser = expat.ParserCreate() - parser.StartElementHandler = self.startelement - parser.EndElementHandler = self.endelement - parser.CharacterDataHandler = self.data - parser.ParseFile(f) - - def startelement(self, tag, attrs): - method = getattr(self, 'start_'+tag, None) - if method: - for key, value in attrs.items(): - attrs[key] = str(value) # XXX Convert Unicode to 8-bit - method(attrs) - self.texts = [] - - def data(self, text): - text = str(text) # XXX Convert Unicode to 8-bit - self.texts.append(text) - - def endelement(self, tag): - method = getattr(self, 'end_'+tag, None) - if method: - method("".join(self.texts)) - - def start_cell(self, attrs): - self.y = int(attrs.get("row")) - self.x = int(attrs.get("col")) - - def start_value(self, attrs): - self.fmt = attrs.get('format') - self.alignment = xml2align.get(attrs.get('align')) - - start_formula = start_value - - def end_int(self, text): - try: - self.value = int(text) - except: - self.value = None - - def end_long(self, text): - try: - self.value = int(text) - except: - self.value = None - - def end_double(self, text): - try: - self.value = float(text) - except: - self.value = None - - def end_complex(self, text): - try: - self.value = complex(text) - except: - self.value = None - - def end_string(self, text): - try: - self.value = text - except: - self.value = None - - def end_value(self, text): - if isinstance(self.value, BaseCell): - self.cell = self.value - elif isinstance(self.value, str): - self.cell = StringCell(self.value, - self.fmt or "%s", - self.alignment or LEFT) - else: - self.cell = NumericCell(self.value, - self.fmt or "%s", - self.alignment or RIGHT) - - def end_formula(self, text): - self.cell = FormulaCell(text, - self.fmt or "%s", - self.alignment or RIGHT) - - def end_cell(self, text): - self.sheet.setcell(self.x, self.y, self.cell) - -class BaseCell: - __init__ = None # Must provide - """Abstract base class for sheet cells. - - Subclasses may but needn't provide the following APIs: - - cell.reset() -- prepare for recalculation - cell.recalc(ns) -> value -- recalculate formula - cell.format() -> (value, alignment) -- return formatted value - cell.xml() -> string -- return XML - """ - -class NumericCell(BaseCell): - - def __init__(self, value, fmt="%s", alignment=RIGHT): - assert isinstance(value, (int, int, float, complex)) - assert alignment in (LEFT, CENTER, RIGHT) - self.value = value - self.fmt = fmt - self.alignment = alignment - - def recalc(self, ns): - return self.value - - def format(self): - try: - text = self.fmt % self.value - except: - text = str(self.value) - return text, self.alignment - - def xml(self): - method = getattr(self, '_xml_' + type(self.value).__name__) - return '%s' % ( - align2xml[self.alignment], - self.fmt, - method()) - - def _xml_int(self): - if -2**31 <= self.value < 2**31: - return '%s' % self.value - else: - return self._xml_long() - - def _xml_long(self): - return '%s' % self.value - - def _xml_float(self): - return '%s' % repr(self.value) - - def _xml_complex(self): - return '%s' % repr(self.value) - -class StringCell(BaseCell): - - def __init__(self, text, fmt="%s", alignment=LEFT): - assert isinstance(text, (str, str)) - assert alignment in (LEFT, CENTER, RIGHT) - self.text = text - self.fmt = fmt - self.alignment = alignment - - def recalc(self, ns): - return self.text - - def format(self): - return self.text, self.alignment - - def xml(self): - s = '%s' - return s % ( - align2xml[self.alignment], - self.fmt, - html.escape(self.text)) - -class FormulaCell(BaseCell): - - def __init__(self, formula, fmt="%s", alignment=RIGHT): - assert alignment in (LEFT, CENTER, RIGHT) - self.formula = formula - self.translated = translate(self.formula) - self.fmt = fmt - self.alignment = alignment - self.reset() - - def reset(self): - self.value = None - - def recalc(self, ns): - if self.value is None: - try: - # A hack to evaluate expressions using true division - self.value = eval(self.translated, ns) - except: - exc = sys.exc_info()[0] - if hasattr(exc, "__name__"): - self.value = exc.__name__ - else: - self.value = str(exc) - return self.value - - def format(self): - try: - text = self.fmt % self.value - except: - text = str(self.value) - return text, self.alignment - - def xml(self): - return '%s' % ( - align2xml[self.alignment], - self.fmt, - self.formula) - - def renumber(self, x1, y1, x2, y2, dx, dy): - out = [] - for part in re.split('(\w+)', self.formula): - m = re.match('^([A-Z]+)([1-9][0-9]*)$', part) - if m is not None: - sx, sy = m.groups() - x = colname2num(sx) - y = int(sy) - if x1 <= x <= x2 and y1 <= y <= y2: - part = cellname(x+dx, y+dy) - out.append(part) - return FormulaCell("".join(out), self.fmt, self.alignment) - -def translate(formula): - """Translate a formula containing fancy cell names to valid Python code. - - Examples: - B4 -> cell(2, 4) - B4:Z100 -> cells(2, 4, 26, 100) - """ - out = [] - for part in re.split(r"(\w+(?::\w+)?)", formula): - m = re.match(r"^([A-Z]+)([1-9][0-9]*)(?::([A-Z]+)([1-9][0-9]*))?$", part) - if m is None: - out.append(part) - else: - x1, y1, x2, y2 = m.groups() - x1 = colname2num(x1) - if x2 is None: - s = "cell(%s, %s)" % (x1, y1) - else: - x2 = colname2num(x2) - s = "cells(%s, %s, %s, %s)" % (x1, y1, x2, y2) - out.append(s) - return "".join(out) - -def cellname(x, y): - "Translate a cell coordinate to a fancy cell name (e.g. (1, 1)->'A1')." - assert x > 0 # Column 0 has an empty name, so can't use that - return colnum2name(x) + str(y) - -def colname2num(s): - "Translate a column name to number (e.g. 'A'->1, 'Z'->26, 'AA'->27)." - s = s.upper() - n = 0 - for c in s: - assert 'A' <= c <= 'Z' - n = n*26 + ord(c) - ord('A') + 1 - return n - -def colnum2name(n): - "Translate a column number to name (e.g. 1->'A', etc.)." - assert n > 0 - s = "" - while n: - n, m = divmod(n-1, 26) - s = chr(m+ord('A')) + s - return s - -import tkinter as Tk - -class SheetGUI: - - """Beginnings of a GUI for a spreadsheet. - - TO DO: - - clear multiple cells - - Insert, clear, remove rows or columns - - Show new contents while typing - - Scroll bars - - Grow grid when window is grown - - Proper menus - - Undo, redo - - Cut, copy and paste - - Formatting and alignment - """ - - def __init__(self, filename="sheet1.xml", rows=10, columns=5): - """Constructor. - - Load the sheet from the filename argument. - Set up the Tk widget tree. - """ - # Create and load the sheet - self.filename = filename - self.sheet = Sheet() - if os.path.isfile(filename): - self.sheet.load(filename) - # Calculate the needed grid size - maxx, maxy = self.sheet.getsize() - rows = max(rows, maxy) - columns = max(columns, maxx) - # Create the widgets - self.root = Tk.Tk() - self.root.wm_title("Spreadsheet: %s" % self.filename) - self.beacon = Tk.Label(self.root, text="A1", - font=('helvetica', 16, 'bold')) - self.entry = Tk.Entry(self.root) - self.savebutton = Tk.Button(self.root, text="Save", - command=self.save) - self.cellgrid = Tk.Frame(self.root) - # Configure the widget lay-out - self.cellgrid.pack(side="bottom", expand=1, fill="both") - self.beacon.pack(side="left") - self.savebutton.pack(side="right") - self.entry.pack(side="left", expand=1, fill="x") - # Bind some events - self.entry.bind("", self.return_event) - self.entry.bind("", self.shift_return_event) - self.entry.bind("", self.tab_event) - self.entry.bind("", self.shift_tab_event) - self.entry.bind("", self.delete_event) - self.entry.bind("", self.escape_event) - # Now create the cell grid - self.makegrid(rows, columns) - # Select the top-left cell - self.currentxy = None - self.cornerxy = None - self.setcurrent(1, 1) - # Copy the sheet cells to the GUI cells - self.sync() - - def delete_event(self, event): - if self.cornerxy != self.currentxy and self.cornerxy is not None: - self.sheet.clearcells(*(self.currentxy + self.cornerxy)) - else: - self.sheet.clearcell(*self.currentxy) - self.sync() - self.entry.delete(0, 'end') - return "break" - - def escape_event(self, event): - x, y = self.currentxy - self.load_entry(x, y) - - def load_entry(self, x, y): - cell = self.sheet.getcell(x, y) - if cell is None: - text = "" - elif isinstance(cell, FormulaCell): - text = '=' + cell.formula - else: - text, alignment = cell.format() - self.entry.delete(0, 'end') - self.entry.insert(0, text) - self.entry.selection_range(0, 'end') - - def makegrid(self, rows, columns): - """Helper to create the grid of GUI cells. - - The edge (x==0 or y==0) is filled with labels; the rest is real cells. - """ - self.rows = rows - self.columns = columns - self.gridcells = {} - # Create the top left corner cell (which selects all) - cell = Tk.Label(self.cellgrid, relief='raised') - cell.grid_configure(column=0, row=0, sticky='NSWE') - cell.bind("", self.selectall) - # Create the top row of labels, and confiure the grid columns - for x in range(1, columns+1): - self.cellgrid.grid_columnconfigure(x, minsize=64) - cell = Tk.Label(self.cellgrid, text=colnum2name(x), relief='raised') - cell.grid_configure(column=x, row=0, sticky='WE') - self.gridcells[x, 0] = cell - cell.__x = x - cell.__y = 0 - cell.bind("", self.selectcolumn) - cell.bind("", self.extendcolumn) - cell.bind("", self.extendcolumn) - cell.bind("", self.extendcolumn) - # Create the leftmost column of labels - for y in range(1, rows+1): - cell = Tk.Label(self.cellgrid, text=str(y), relief='raised') - cell.grid_configure(column=0, row=y, sticky='WE') - self.gridcells[0, y] = cell - cell.__x = 0 - cell.__y = y - cell.bind("", self.selectrow) - cell.bind("", self.extendrow) - cell.bind("", self.extendrow) - cell.bind("", self.extendrow) - # Create the real cells - for x in range(1, columns+1): - for y in range(1, rows+1): - cell = Tk.Label(self.cellgrid, relief='sunken', - bg='white', fg='black') - cell.grid_configure(column=x, row=y, sticky='NSWE') - self.gridcells[x, y] = cell - cell.__x = x - cell.__y = y - # Bind mouse events - cell.bind("", self.press) - cell.bind("", self.motion) - cell.bind("", self.release) - cell.bind("", self.release) - - def selectall(self, event): - self.setcurrent(1, 1) - self.setcorner(sys.maxint, sys.maxint) - - def selectcolumn(self, event): - x, y = self.whichxy(event) - self.setcurrent(x, 1) - self.setcorner(x, sys.maxint) - - def extendcolumn(self, event): - x, y = self.whichxy(event) - if x > 0: - self.setcurrent(self.currentxy[0], 1) - self.setcorner(x, sys.maxint) - - def selectrow(self, event): - x, y = self.whichxy(event) - self.setcurrent(1, y) - self.setcorner(sys.maxint, y) - - def extendrow(self, event): - x, y = self.whichxy(event) - if y > 0: - self.setcurrent(1, self.currentxy[1]) - self.setcorner(sys.maxint, y) - - def press(self, event): - x, y = self.whichxy(event) - if x > 0 and y > 0: - self.setcurrent(x, y) - - def motion(self, event): - x, y = self.whichxy(event) - if x > 0 and y > 0: - self.setcorner(x, y) - - release = motion - - def whichxy(self, event): - w = self.cellgrid.winfo_containing(event.x_root, event.y_root) - if w is not None and isinstance(w, Tk.Label): - try: - return w.__x, w.__y - except AttributeError: - pass - return 0, 0 - - def save(self): - self.sheet.save(self.filename) - - def setcurrent(self, x, y): - "Make (x, y) the current cell." - if self.currentxy is not None: - self.change_cell() - self.clearfocus() - self.beacon['text'] = cellname(x, y) - self.load_entry(x, y) - self.entry.focus_set() - self.currentxy = x, y - self.cornerxy = None - gridcell = self.gridcells.get(self.currentxy) - if gridcell is not None: - gridcell['bg'] = 'yellow' - - def setcorner(self, x, y): - if self.currentxy is None or self.currentxy == (x, y): - self.setcurrent(x, y) - return - self.clearfocus() - self.cornerxy = x, y - x1, y1 = self.currentxy - x2, y2 = self.cornerxy or self.currentxy - if x1 > x2: - x1, x2 = x2, x1 - if y1 > y2: - y1, y2 = y2, y1 - for (x, y), cell in self.gridcells.items(): - if x1 <= x <= x2 and y1 <= y <= y2: - cell['bg'] = 'lightBlue' - gridcell = self.gridcells.get(self.currentxy) - if gridcell is not None: - gridcell['bg'] = 'yellow' - self.setbeacon(x1, y1, x2, y2) - - def setbeacon(self, x1, y1, x2, y2): - if x1 == y1 == 1 and x2 == y2 == sys.maxint: - name = ":" - elif (x1, x2) == (1, sys.maxint): - if y1 == y2: - name = "%d" % y1 - else: - name = "%d:%d" % (y1, y2) - elif (y1, y2) == (1, sys.maxint): - if x1 == x2: - name = "%s" % colnum2name(x1) - else: - name = "%s:%s" % (colnum2name(x1), colnum2name(x2)) - else: - name1 = cellname(*self.currentxy) - name2 = cellname(*self.cornerxy) - name = "%s:%s" % (name1, name2) - self.beacon['text'] = name - - - def clearfocus(self): - if self.currentxy is not None: - x1, y1 = self.currentxy - x2, y2 = self.cornerxy or self.currentxy - if x1 > x2: - x1, x2 = x2, x1 - if y1 > y2: - y1, y2 = y2, y1 - for (x, y), cell in self.gridcells.items(): - if x1 <= x <= x2 and y1 <= y <= y2: - cell['bg'] = 'white' - - def return_event(self, event): - "Callback for the Return key." - self.change_cell() - x, y = self.currentxy - self.setcurrent(x, y+1) - return "break" - - def shift_return_event(self, event): - "Callback for the Return key with Shift modifier." - self.change_cell() - x, y = self.currentxy - self.setcurrent(x, max(1, y-1)) - return "break" - - def tab_event(self, event): - "Callback for the Tab key." - self.change_cell() - x, y = self.currentxy - self.setcurrent(x+1, y) - return "break" - - def shift_tab_event(self, event): - "Callback for the Tab key with Shift modifier." - self.change_cell() - x, y = self.currentxy - self.setcurrent(max(1, x-1), y) - return "break" - - def change_cell(self): - "Set the current cell from the entry widget." - x, y = self.currentxy - text = self.entry.get() - cell = None - if text.startswith('='): - cell = FormulaCell(text[1:]) - else: - for cls in int, int, float, complex: - try: - value = cls(text) - except: - continue - else: - cell = NumericCell(value) - break - if cell is None and text: - cell = StringCell(text) - if cell is None: - self.sheet.clearcell(x, y) - else: - self.sheet.setcell(x, y, cell) - self.sync() - - def sync(self): - "Fill the GUI cells from the sheet cells." - self.sheet.recalc() - for (x, y), gridcell in self.gridcells.items(): - if x == 0 or y == 0: - continue - cell = self.sheet.getcell(x, y) - if cell is None: - gridcell['text'] = "" - else: - if hasattr(cell, 'format'): - text, alignment = cell.format() - else: - text, alignment = str(cell), LEFT - gridcell['text'] = text - gridcell['anchor'] = align2anchor[alignment] - - -def test_basic(): - "Basic non-gui self-test." - import os - a = Sheet() - for x in range(1, 11): - for y in range(1, 11): - if x == 1: - cell = NumericCell(y) - elif y == 1: - cell = NumericCell(x) - else: - c1 = cellname(x, 1) - c2 = cellname(1, y) - formula = "%s*%s" % (c1, c2) - cell = FormulaCell(formula) - a.setcell(x, y, cell) -## if os.path.isfile("sheet1.xml"): -## print "Loading from sheet1.xml" -## a.load("sheet1.xml") - a.display() - a.save("sheet1.xml") - -def test_gui(): - "GUI test." - if sys.argv[1:]: - filename = sys.argv[1] - else: - filename = "sheet1.xml" - g = SheetGUI(filename) - g.root.mainloop() - -if __name__ == '__main__': - #test_basic() - test_gui() diff --git a/Demo/tkinter/guido/svkill.py b/Demo/tkinter/guido/svkill.py deleted file mode 100755 index 5ed8f0f..0000000 --- a/Demo/tkinter/guido/svkill.py +++ /dev/null @@ -1,124 +0,0 @@ -#! /usr/bin/env python3 - -# Tkinter interface to SYSV `ps' and `kill' commands. - -from tkinter import * - -if TkVersion < 4.0: - raise ImportError("This version of svkill requires Tk 4.0 or later") - -import subprocess -import os - -user = os.environ['LOGNAME'] - -class BarButton(Menubutton): - def __init__(self, master=None, **cnf): - Menubutton.__init__(self, master, **cnf) - self.pack(side=LEFT) - self.menu = Menu(self, name='menu') - self['menu'] = self.menu - -class Kill(Frame): - # List of (name, option, pid_column) - view_list = [ - ('Default', ''), - ('Every (-e)', '-e'), - ('Non process group leaders (-d)', '-d'), - ('Non leaders with tty (-a)', '-a'), - ('For this user (-u %s)' % user, '-u %s' % user), - ] - format_list = [ - ('Default', '', 0), - ('Long (-l)', '-l', 3), - ('Full (-f)', '-f', 1), - ('Full Long (-f -l)', '-l -f', 3), - ('Session and group ID (-j)', '-j', 0), - ('Scheduler properties (-c)', '-c', 0), - ] - def kill(self, selected): - c = self.format_list[self.format.get()][2] - pid = selected.split()[c] - os.system('kill -9 ' + pid) - self.do_update() - def do_update(self): - format = self.format_list[self.format.get()][1] - view = self.view_list[self.view.get()][1] - s = subprocess.getoutput('ps %s %s' % (view, format)) - list = s.split('\n') - self.header.set(list[0] + ' ') - del list[0] - self.frame.list.delete(0, AtEnd()) - for line in list: - self.frame.list.insert(0, line) - def do_motion(self, e): - e.widget.select_clear('0', 'end') - e.widget.select_set(e.widget.nearest(e.y)) - def do_leave(self, e): - e.widget.select_clear('0', 'end') - def do_1(self, e): - self.kill(e.widget.get(e.widget.nearest(e.y))) - def __init__(self, master=None, **cnf): - Frame.__init__(self, master, **cnf) - self.pack(expand=1, fill=BOTH) - self.bar = Frame(self, name='bar', relief=RAISED, - borderwidth=2) - self.bar.pack(fill=X) - self.bar.file = BarButton(self.bar, text='File') - self.bar.file.menu.add_command( - label='Quit', command=self.quit) - self.bar.view = BarButton(self.bar, text='View') - self.bar.format = BarButton(self.bar, text='Format') - self.view = IntVar(self) - self.view.set(0) - self.format = IntVar(self) - self.format.set(0) - for num in range(len(self.view_list)): - label, option = self.view_list[num] - self.bar.view.menu.add_radiobutton( - label=label, - command=self.do_update, - variable=self.view, - value=num) - for num in range(len(self.format_list)): - label, option, col = self.format_list[num] - self.bar.format.menu.add_radiobutton( - label=label, - command=self.do_update, - variable=self.format, - value=num) - self.bar.tk_menuBar(self.bar.file, - self.bar.view, - self.bar.format) - self.frame = Frame(self, relief=RAISED, borderwidth=2) - self.frame.pack(expand=1, fill=BOTH) - self.header = StringVar(self) - self.frame.label = Label( - self.frame, relief=FLAT, anchor=NW, borderwidth=0, - textvariable=self.header) - self.frame.label.pack(fill=Y, anchor=W) - self.frame.vscroll = Scrollbar(self.frame, orient=VERTICAL) - self.frame.list = Listbox( - self.frame, - relief=SUNKEN, - width=40, height=10, - selectbackground='#eed5b7', - selectborderwidth=0, - selectmode=BROWSE, - yscroll=self.frame.vscroll.set) - self.frame.vscroll['command'] = self.frame.list.yview - self.frame.vscroll.pack(side=RIGHT, fill=Y) - self.frame.list.pack(expand=1, fill=BOTH) - self.update = Button(self, text='Update', - command=self.do_update) - self.update.pack(fill=X) - self.frame.list.bind('', self.do_motion) - self.frame.list.bind('', self.do_leave) - self.frame.list.bind('<1>', self.do_1) - self.do_update() - -if __name__ == '__main__': - kill = Kill(None, borderwidth=5) - kill.winfo_toplevel().title('Tkinter Process Killer (SYSV)') - kill.winfo_toplevel().minsize(1, 1) - kill.mainloop() diff --git a/Demo/tkinter/guido/switch.py b/Demo/tkinter/guido/switch.py deleted file mode 100644 index 3f43925..0000000 --- a/Demo/tkinter/guido/switch.py +++ /dev/null @@ -1,55 +0,0 @@ -# Show how to do switchable panels. - -from tkinter import * - -class App: - - def __init__(self, top=None, master=None): - if top is None: - if master is None: - top = Tk() - else: - top = Toplevel(master) - self.top = top - self.buttonframe = Frame(top) - self.buttonframe.pack() - self.panelframe = Frame(top, borderwidth=2, relief=GROOVE) - self.panelframe.pack(expand=1, fill=BOTH) - self.panels = {} - self.curpanel = None - - def addpanel(self, name, klass): - button = Button(self.buttonframe, text=name, - command=lambda self=self, name=name: self.show(name)) - button.pack(side=LEFT) - frame = Frame(self.panelframe) - instance = klass(frame) - self.panels[name] = (button, frame, instance) - if self.curpanel is None: - self.show(name) - - def show(self, name): - (button, frame, instance) = self.panels[name] - if self.curpanel: - self.curpanel.pack_forget() - self.curpanel = frame - frame.pack(expand=1, fill="both") - -class LabelPanel: - def __init__(self, frame): - self.label = Label(frame, text="Hello world") - self.label.pack() - -class ButtonPanel: - def __init__(self, frame): - self.button = Button(frame, text="Press me") - self.button.pack() - -def main(): - app = App() - app.addpanel("label", LabelPanel) - app.addpanel("button", ButtonPanel) - app.top.mainloop() - -if __name__ == '__main__': - main() diff --git a/Demo/tkinter/guido/tkman.py b/Demo/tkinter/guido/tkman.py deleted file mode 100755 index c7081a6..0000000 --- a/Demo/tkinter/guido/tkman.py +++ /dev/null @@ -1,267 +0,0 @@ -#! /usr/bin/env python3 - -# Tk man page browser -- currently only shows the Tcl/Tk man pages - -import os -import re -import sys -from tkinter import * - -from manpage import ManPage - -MANNDIRLIST = ['/usr/local/man/mann', '/usr/share/man/mann'] -MAN3DIRLIST = ['/usr/local/man/man3', '/usr/share/man/man3'] - -foundmanndir = 0 -for dir in MANNDIRLIST: - if os.path.exists(dir): - MANNDIR = dir - foundmanndir = 1 - -foundman3dir = 0 -for dir in MAN3DIRLIST: - if os.path.exists(dir): - MAN3DIR = dir - foundman3dir = 1 - -if not foundmanndir or not foundman3dir: - sys.stderr.write('\n') - if not foundmanndir: - msg = """\ -Failed to find mann directory. -Please add the correct entry to the MANNDIRLIST -at the top of %s script.""" % \ -sys.argv[0] - sys.stderr.write("%s\n\n" % msg) - if not foundman3dir: - msg = """\ -Failed to find man3 directory. -Please add the correct entry to the MAN3DIRLIST -at the top of %s script.""" % \ -sys.argv[0] - sys.stderr.write("%s\n\n" % msg) - sys.exit(1) - -del foundmanndir -del foundman3dir - -def listmanpages(mandir): - files = os.listdir(mandir) - names = [] - for file in files: - if file[-2:-1] == '.' and (file[-1] in 'ln123456789'): - names.append(file[:-2]) - names.sort() - return names - -class SelectionBox: - - def __init__(self, master=None): - self.choices = [] - - self.frame = Frame(master, name="frame") - self.frame.pack(expand=1, fill=BOTH) - self.master = self.frame.master - self.subframe = Frame(self.frame, name="subframe") - self.subframe.pack(expand=0, fill=BOTH) - self.leftsubframe = Frame(self.subframe, name='leftsubframe') - self.leftsubframe.pack(side=LEFT, expand=1, fill=BOTH) - self.rightsubframe = Frame(self.subframe, name='rightsubframe') - self.rightsubframe.pack(side=RIGHT, expand=1, fill=BOTH) - self.chaptervar = StringVar(master) - self.chapter = Menubutton(self.rightsubframe, name='chapter', - text='Directory', relief=RAISED, - borderwidth=2) - self.chapter.pack(side=TOP) - self.chaptermenu = Menu(self.chapter, name='chaptermenu') - self.chaptermenu.add_radiobutton(label='C functions', - value=MAN3DIR, - variable=self.chaptervar, - command=self.newchapter) - self.chaptermenu.add_radiobutton(label='Tcl/Tk functions', - value=MANNDIR, - variable=self.chaptervar, - command=self.newchapter) - self.chapter['menu'] = self.chaptermenu - self.listbox = Listbox(self.rightsubframe, name='listbox', - relief=SUNKEN, borderwidth=2, - width=20, height=5) - self.listbox.pack(expand=1, fill=BOTH) - self.l1 = Button(self.leftsubframe, name='l1', - text='Display manual page named:', - command=self.entry_cb) - self.l1.pack(side=TOP) - self.entry = Entry(self.leftsubframe, name='entry', - relief=SUNKEN, borderwidth=2, - width=20) - self.entry.pack(expand=0, fill=X) - self.l2frame = Frame(self.leftsubframe, name='l2frame') - self.l2frame.pack(expand=0, fill=NONE) - self.l2 = Button(self.l2frame, name='l2', - text='Search regexp:', - command=self.search_cb) - self.l2.pack(side=LEFT) - self.casevar = BooleanVar() - self.casesense = Checkbutton(self.l2frame, name='casesense', - text='Case sensitive', - variable=self.casevar, - relief=FLAT) - self.casesense.pack(side=LEFT) - self.search = Entry(self.leftsubframe, name='search', - relief=SUNKEN, borderwidth=2, - width=20) - self.search.pack(expand=0, fill=X) - self.title = Label(self.leftsubframe, name='title', - text='(none)') - self.title.pack(side=BOTTOM) - self.text = ManPage(self.frame, name='text', - relief=SUNKEN, borderwidth=2, - wrap=NONE, width=72, - selectbackground='pink') - self.text.pack(expand=1, fill=BOTH) - - self.entry.bind('', self.entry_cb) - self.search.bind('', self.search_cb) - self.listbox.bind('', self.listbox_cb) - - self.entry.bind('', self.entry_tab) - self.search.bind('', self.search_tab) - self.text.bind('', self.text_tab) - - self.entry.focus_set() - - self.chaptervar.set(MANNDIR) - self.newchapter() - - def newchapter(self): - mandir = self.chaptervar.get() - self.choices = [] - self.addlist(listmanpages(mandir)) - - def addchoice(self, choice): - if choice not in self.choices: - self.choices.append(choice) - self.choices.sort() - self.update() - - def addlist(self, list): - self.choices[len(self.choices):] = list - self.choices.sort() - self.update() - - def entry_cb(self, *e): - self.update() - - def listbox_cb(self, e): - selection = self.listbox.curselection() - if selection and len(selection) == 1: - name = self.listbox.get(selection[0]) - self.show_page(name) - - def search_cb(self, *e): - self.search_string(self.search.get()) - - def entry_tab(self, e): - self.search.focus_set() - - def search_tab(self, e): - self.entry.focus_set() - - def text_tab(self, e): - self.entry.focus_set() - - def updatelist(self): - key = self.entry.get() - ok = list(filter(lambda name, key=key, n=len(key): name[:n]==key, - self.choices)) - if not ok: - self.frame.bell() - self.listbox.delete(0, AtEnd()) - exactmatch = 0 - for item in ok: - if item == key: exactmatch = 1 - self.listbox.insert(AtEnd(), item) - if exactmatch: - return key - n = self.listbox.size() - if n == 1: - return self.listbox.get(0) - # Else return None, meaning not a unique selection - - def update(self): - name = self.updatelist() - if name: - self.show_page(name) - self.entry.delete(0, AtEnd()) - self.updatelist() - - def show_page(self, name): - file = '%s/%s.?' % (self.chaptervar.get(), name) - fp = os.popen('nroff -man -c %s | ul -i' % file, 'r') - self.text.kill() - self.title['text'] = name - self.text.parsefile(fp) - - def search_string(self, search): - if not search: - self.frame.bell() - print('Empty search string') - return - if not self.casevar.get(): - map = re.IGNORECASE - else: - map = None - try: - if map: - prog = re.compile(search, map) - else: - prog = re.compile(search) - except re.error as msg: - self.frame.bell() - print('Regex error:', msg) - return - here = self.text.index(AtInsert()) - lineno = int(here[:here.find('.')]) - end = self.text.index(AtEnd()) - endlineno = int(end[:end.find('.')]) - wraplineno = lineno - found = 0 - while 1: - lineno = lineno + 1 - if lineno > endlineno: - if wraplineno <= 0: - break - endlineno = wraplineno - lineno = 0 - wraplineno = 0 - line = self.text.get('%d.0 linestart' % lineno, - '%d.0 lineend' % lineno) - i = prog.search(line) - if i: - found = 1 - n = max(1, len(i.group(0))) - try: - self.text.tag_remove('sel', - AtSelFirst(), - AtSelLast()) - except TclError: - pass - self.text.tag_add('sel', - '%d.%d' % (lineno, i.start()), - '%d.%d' % (lineno, i.start()+n)) - self.text.mark_set(AtInsert(), - '%d.%d' % (lineno, i.start())) - self.text.yview_pickplace(AtInsert()) - break - if not found: - self.frame.bell() - -def main(): - root = Tk() - sb = SelectionBox(root) - if sys.argv[1:]: - sb.show_page(sys.argv[1]) - root.minsize(1, 1) - root.mainloop() - -main() diff --git a/Demo/tkinter/guido/wish.py b/Demo/tkinter/guido/wish.py deleted file mode 100644 index 332501d..0000000 --- a/Demo/tkinter/guido/wish.py +++ /dev/null @@ -1,34 +0,0 @@ -# This is about all it requires to write a wish shell in Python! - -import _tkinter -import os -import sys - -tk = _tkinter.create(os.environ['DISPLAY'], 'wish', 'Tk', 1, 1) -tk.call('update') - -cmd = '' - -while True: - if cmd: - prompt = '' - else: - prompt = '% ' - try: - sys.stdout.write(prompt) - sys.stdout.flush() - line = sys.stdin.readline() - if not line: - break - except EOFError: - break - cmd += line - if tk.getboolean(tk.call('info', 'complete', cmd)): - tk.record(line) - try: - result = tk.call('eval', cmd) - except _tkinter.TclError as msg: - print('TclError:', msg) - else: - if result: print(result) - cmd = '' diff --git a/Demo/tkinter/matt/00-HELLO-WORLD.py b/Demo/tkinter/matt/00-HELLO-WORLD.py deleted file mode 100644 index 3b4092a..0000000 --- a/Demo/tkinter/matt/00-HELLO-WORLD.py +++ /dev/null @@ -1,27 +0,0 @@ -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. - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - - self.QUIT.pack(side=LEFT, fill=BOTH) - - # a hello button - self.hi_there = Button(self, text='Hello', - command=self.printit) - self.hi_there.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/README b/Demo/tkinter/matt/README deleted file mode 100644 index eb9d302..0000000 --- a/Demo/tkinter/matt/README +++ /dev/null @@ -1,30 +0,0 @@ -This directory contains some ad-hoc examples of Tkinter widget -creation. The files named - - *-simple.py - -are the ones to start with if you're looking for a bare-bones usage of -a widget. The other files are meant to show common usage patters that -are a tad more involved. - -If you have a suggestion for an example program, please send mail to - - conway@virginia.edu - -and I'll include it. - - -matt - -TODO -------- -The X selection -Dialog Boxes -More canvas examples -Message widgets -Text Editors -Scrollbars -Listboxes - - - diff --git a/Demo/tkinter/matt/animation-simple.py b/Demo/tkinter/matt/animation-simple.py deleted file mode 100644 index 4120d66..0000000 --- a/Demo/tkinter/matt/animation-simple.py +++ /dev/null @@ -1,35 +0,0 @@ -from tkinter import * - -# This program shows how to use the "after" function to make animation. - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=LEFT, fill=BOTH) - - self.draw = Canvas(self, width="5i", height="5i") - - # all of these work.. - self.draw.create_rectangle(0, 0, 10, 10, tags="thing", fill="blue") - self.draw.pack(side=LEFT) - - def moveThing(self, *args): - # move 1/10 of an inch every 1/10 sec (1" per second, smoothly) - self.draw.move("thing", "0.01i", "0.01i") - self.after(10, self.moveThing) - - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - self.after(10, self.moveThing) - - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/animation-w-velocity-ctrl.py b/Demo/tkinter/matt/animation-w-velocity-ctrl.py deleted file mode 100644 index 88309ca..0000000 --- a/Demo/tkinter/matt/animation-w-velocity-ctrl.py +++ /dev/null @@ -1,44 +0,0 @@ -from tkinter import * - -# this is the same as simple-demo-1.py, but uses -# subclassing. -# note that there is no explicit call to start Tk. -# Tkinter is smart enough to start the system if it's not already going. - - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - - self.draw = Canvas(self, width="5i", height="5i") - - self.speed = Scale(self, orient=HORIZONTAL, from_=-100, to=100) - - self.speed.pack(side=BOTTOM, fill=X) - - # all of these work.. - self.draw.create_rectangle(0, 0, 10, 10, tags="thing", fill="blue") - self.draw.pack(side=LEFT) - - def moveThing(self, *args): - velocity = self.speed.get() - str = float(velocity) / 1000.0 - str = "%ri" % (str,) - self.draw.move("thing", str, str) - self.after(10, self.moveThing) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - self.after(10, self.moveThing) - - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/bind-w-mult-calls-p-type.py b/Demo/tkinter/matt/bind-w-mult-calls-p-type.py deleted file mode 100644 index 0da7c37..0000000 --- a/Demo/tkinter/matt/bind-w-mult-calls-p-type.py +++ /dev/null @@ -1,43 +0,0 @@ -from tkinter import * - -# This program shows how to use a simple type-in box - -class App(Frame): - def __init__(self, master=None): - Frame.__init__(self, master) - self.pack() - - self.entrythingy = Entry() - self.entrythingy.pack() - - # and here we get a callback when the user hits return. we could - # make the key that triggers the callback anything we wanted to. - # other typical options might be or (for anything) - self.entrythingy.bind('', self.print_contents) - - # Note that here is where we bind a completely different callback to - # the same event. We pass "+" here to indicate that we wish to ADD - # this callback to the list associated with this event type. - # Not specifying "+" would simply override whatever callback was - # defined on this event. - self.entrythingy.bind('', self.print_something_else, "+") - - def print_contents(self, event): - print("hi. contents of entry is now ---->", self.entrythingy.get()) - - - def print_something_else(self, event): - print("hi. Now doing something completely different") - - -root = App() -root.master.title("Foo") -root.mainloop() - - - -# secret tip for experts: if you pass *any* non-false value as -# the third parameter to bind(), Tkinter.py will accumulate -# callbacks instead of overwriting. I use "+" here because that's -# the Tk notation for getting this sort of behavior. The perfect GUI -# interface would use a less obscure notation. diff --git a/Demo/tkinter/matt/canvas-demo-simple.py b/Demo/tkinter/matt/canvas-demo-simple.py deleted file mode 100644 index 7f2c17b..0000000 --- a/Demo/tkinter/matt/canvas-demo-simple.py +++ /dev/null @@ -1,28 +0,0 @@ -from tkinter import * - -# this program creates a canvas and puts a single polygon on the canvas - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - - self.draw = Canvas(self, width="5i", height="5i") - - # see the other demos for other ways of specifying coords for a polygon - self.draw.create_rectangle(0, 0, "3i", "3i", fill="black") - - self.draw.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/canvas-gridding.py b/Demo/tkinter/matt/canvas-gridding.py deleted file mode 100644 index 2f9d23a..0000000 --- a/Demo/tkinter/matt/canvas-gridding.py +++ /dev/null @@ -1,61 +0,0 @@ -from tkinter import * - -# this is the same as simple-demo-1.py, but uses -# subclassing. -# note that there is no explicit call to start Tk. -# Tkinter is smart enough to start the system if it's not already going. - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', - background='red', - foreground='white', - height=3, - command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - - self.canvasObject = Canvas(self, width="5i", height="5i") - self.canvasObject.pack(side=LEFT) - - def mouseDown(self, event): - # canvas x and y take the screen coords from the event and translate - # them into the coordinate system of the canvas object - self.startx = self.canvasObject.canvasx(event.x, self.griddingSize) - self.starty = self.canvasObject.canvasy(event.y, self.griddingSize) - - def mouseMotion(self, event): - # canvas x and y take the screen coords from the event and translate - # them into the coordinate system of the canvas object - x = self.canvasObject.canvasx(event.x, self.griddingSize) - y = self.canvasObject.canvasy(event.y, self.griddingSize) - - if (self.startx != event.x) and (self.starty != event.y) : - self.canvasObject.delete(self.rubberbandBox) - self.rubberbandBox = self.canvasObject.create_rectangle( - self.startx, self.starty, x, y) - # this flushes the output, making sure that - # the rectangle makes it to the screen - # before the next event is handled - self.update_idletasks() - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - - # this is a "tagOrId" for the rectangle we draw on the canvas - self.rubberbandBox = None - - # this is the size of the gridding squares - self.griddingSize = 50 - - Widget.bind(self.canvasObject, "", self.mouseDown) - Widget.bind(self.canvasObject, "", self.mouseMotion) - - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/canvas-moving-or-creating.py b/Demo/tkinter/matt/canvas-moving-or-creating.py deleted file mode 100644 index edd64f7..0000000 --- a/Demo/tkinter/matt/canvas-moving-or-creating.py +++ /dev/null @@ -1,62 +0,0 @@ -from tkinter import * - -# this file demonstrates a more sophisticated movement -- -# move dots or create new ones if you click outside the dots - -class Test(Frame): - ################################################################### - ###### Event callbacks for THE CANVAS (not the stuff drawn on it) - ################################################################### - def mouseDown(self, event): - # see if we're inside a dot. If we are, it - # gets tagged as CURRENT for free by tk. - if not event.widget.find_withtag(CURRENT): - # there is no dot here, so we can make one, - # and bind some interesting behavior to it. - # ------ - # create a dot, and mark it as CURRENT - fred = self.draw.create_oval( - event.x - 10, event.y -10, event.x +10, event.y + 10, - fill="green", tags=CURRENT) - - self.draw.tag_bind(fred, "", self.mouseEnter) - self.draw.tag_bind(fred, "", self.mouseLeave) - - self.lastx = event.x - self.lasty = event.y - - def mouseMove(self, event): - self.draw.move(CURRENT, event.x - self.lastx, event.y - self.lasty) - self.lastx = event.x - self.lasty = event.y - - ################################################################### - ###### Event callbacks for canvas ITEMS (stuff drawn on the canvas) - ################################################################### - def mouseEnter(self, event): - # the CURRENT tag is applied to the object the cursor is over. - # this happens automatically. - self.draw.itemconfig(CURRENT, fill="red") - - def mouseLeave(self, event): - # the CURRENT tag is applied to the object the cursor is over. - # this happens automatically. - self.draw.itemconfig(CURRENT, fill="blue") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=LEFT, fill=BOTH) - self.draw = Canvas(self, width="5i", height="5i") - self.draw.pack(side=LEFT) - - Widget.bind(self.draw, "<1>", self.mouseDown) - Widget.bind(self.draw, "", self.mouseMove) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/canvas-moving-w-mouse.py b/Demo/tkinter/matt/canvas-moving-w-mouse.py deleted file mode 100644 index 21d724f..0000000 --- a/Demo/tkinter/matt/canvas-moving-w-mouse.py +++ /dev/null @@ -1,55 +0,0 @@ -from tkinter import * - -# this file demonstrates the movement of a single canvas item under mouse control - -class Test(Frame): - ################################################################### - ###### Event callbacks for THE CANVAS (not the stuff drawn on it) - ################################################################### - def mouseDown(self, event): - # remember where the mouse went down - self.lastx = event.x - self.lasty = event.y - - def mouseMove(self, event): - # whatever the mouse is over gets tagged as CURRENT for free by tk. - self.draw.move(CURRENT, event.x - self.lastx, event.y - self.lasty) - self.lastx = event.x - self.lasty = event.y - - ################################################################### - ###### Event callbacks for canvas ITEMS (stuff drawn on the canvas) - ################################################################### - def mouseEnter(self, event): - # the CURRENT tag is applied to the object the cursor is over. - # this happens automatically. - self.draw.itemconfig(CURRENT, fill="red") - - def mouseLeave(self, event): - # the CURRENT tag is applied to the object the cursor is over. - # this happens automatically. - self.draw.itemconfig(CURRENT, fill="blue") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=LEFT, fill=BOTH) - self.draw = Canvas(self, width="5i", height="5i") - self.draw.pack(side=LEFT) - - fred = self.draw.create_oval(0, 0, 20, 20, - fill="green", tags="selected") - - self.draw.tag_bind(fred, "", self.mouseEnter) - self.draw.tag_bind(fred, "", self.mouseLeave) - - Widget.bind(self.draw, "<1>", self.mouseDown) - Widget.bind(self.draw, "", self.mouseMove) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/canvas-mult-item-sel.py b/Demo/tkinter/matt/canvas-mult-item-sel.py deleted file mode 100644 index 4875b44..0000000 --- a/Demo/tkinter/matt/canvas-mult-item-sel.py +++ /dev/null @@ -1,78 +0,0 @@ -from tkinter import * - -# allows moving dots with multiple selection. - -SELECTED_COLOR = "red" -UNSELECTED_COLOR = "blue" - -class Test(Frame): - ################################################################### - ###### Event callbacks for THE CANVAS (not the stuff drawn on it) - ################################################################### - def mouseDown(self, event): - # see if we're inside a dot. If we are, it - # gets tagged as CURRENT for free by tk. - - if not event.widget.find_withtag(CURRENT): - # we clicked outside of all dots on the canvas. unselect all. - - # re-color everything back to an unselected color - self.draw.itemconfig("selected", fill=UNSELECTED_COLOR) - # unselect everything - self.draw.dtag("selected") - else: - # mark as "selected" the thing the cursor is under - self.draw.addtag("selected", "withtag", CURRENT) - # color it as selected - self.draw.itemconfig("selected", fill=SELECTED_COLOR) - - self.lastx = event.x - self.lasty = event.y - - - def mouseMove(self, event): - self.draw.move("selected", event.x - self.lastx, event.y - self.lasty) - self.lastx = event.x - self.lasty = event.y - - def makeNewDot(self): - # create a dot, and mark it as current - fred = self.draw.create_oval(0, 0, 20, 20, - fill=SELECTED_COLOR, tags=CURRENT) - # and make it selected - self.draw.addtag("selected", "withtag", CURRENT) - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - - ################ - # make the canvas and bind some behavior to it - ################ - self.draw = Canvas(self, width="5i", height="5i") - Widget.bind(self.draw, "<1>", self.mouseDown) - Widget.bind(self.draw, "", self.mouseMove) - - # and other things..... - self.button = Button(self, text="make a new dot", foreground="blue", - command=self.makeNewDot) - - message = ("%s dots are selected and can be dragged.\n" - "%s are not selected.\n" - "Click in a dot to select it.\n" - "Click on empty space to deselect all dots." - ) % (SELECTED_COLOR, UNSELECTED_COLOR) - self.label = Message(self, width="5i", text=message) - - self.QUIT.pack(side=BOTTOM, fill=BOTH) - self.label.pack(side=BOTTOM, fill=X, expand=1) - self.button.pack(side=BOTTOM, fill=X) - self.draw.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/canvas-reading-tag-info.py b/Demo/tkinter/matt/canvas-reading-tag-info.py deleted file mode 100644 index 265f0a1..0000000 --- a/Demo/tkinter/matt/canvas-reading-tag-info.py +++ /dev/null @@ -1,49 +0,0 @@ -from tkinter import * - - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - - self.drawing = Canvas(self, width="5i", height="5i") - - # make a shape - pgon = self.drawing.create_polygon( - 10, 10, 110, 10, 110, 110, 10 , 110, - fill="red", tags=("weee", "foo", "groo")) - - # this is how you query an object for its attributes - # config options FOR CANVAS ITEMS always come back in tuples of length 5. - # 0 attribute name - # 1 BLANK - # 2 BLANK - # 3 default value - # 4 current value - # the blank spots are for consistency with the config command that - # is used for widgets. (remember, this is for ITEMS drawn - # on a canvas widget, not widgets) - option_value = self.drawing.itemconfig(pgon, "stipple") - print("pgon's current stipple value is -->", option_value[4], "<--") - option_value = self.drawing.itemconfig(pgon, "fill") - print("pgon's current fill value is -->", option_value[4], "<--") - print(" when he is usually colored -->", option_value[3], "<--") - - ## here we print out all the tags associated with this object - option_value = self.drawing.itemconfig(pgon, "tags") - print("pgon's tags are", option_value[4]) - - self.drawing.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/canvas-w-widget-draw-el.py b/Demo/tkinter/matt/canvas-w-widget-draw-el.py deleted file mode 100644 index ca96583..0000000 --- a/Demo/tkinter/matt/canvas-w-widget-draw-el.py +++ /dev/null @@ -1,36 +0,0 @@ -from tkinter import * - -# this file demonstrates the creation of widgets as part of a canvas object - -class Test(Frame): - def printhi(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - - self.draw = Canvas(self, width="5i", height="5i") - - self.button = Button(self, text="this is a button", - command=self.printhi) - - # note here the coords are given in pixels (form the - # upper right and corner of the window, as usual for X) - # but might just have well been given in inches or points or - # whatever...use the "anchor" option to control what point of the - # widget (in this case the button) gets mapped to the given x, y. - # you can specify corners, edges, center, etc... - self.draw.create_window(300, 300, window=self.button) - - self.draw.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/canvas-with-scrollbars.py b/Demo/tkinter/matt/canvas-with-scrollbars.py deleted file mode 100644 index 1c5681a..0000000 --- a/Demo/tkinter/matt/canvas-with-scrollbars.py +++ /dev/null @@ -1,60 +0,0 @@ -from tkinter import * - -# This example program creates a scroling canvas, and demonstrates -# how to tie scrollbars and canvses together. The mechanism -# is analogus for listboxes and other widgets with -# "xscroll" and "yscroll" configuration options. - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.question = Label(self, text="Can Find The BLUE Square??????") - self.question.pack() - - self.QUIT = Button(self, text='QUIT', background='red', - height=3, command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - spacer = Frame(self, height="0.25i") - spacer.pack(side=BOTTOM) - - # notice that the scroll region (20" x 20") is larger than - # displayed size of the widget (5" x 5") - self.draw = Canvas(self, width="5i", height="5i", - background="white", - scrollregion=(0, 0, "20i", "20i")) - - self.draw.scrollX = Scrollbar(self, orient=HORIZONTAL) - self.draw.scrollY = Scrollbar(self, orient=VERTICAL) - - # now tie the three together. This is standard boilerplate text - self.draw['xscrollcommand'] = self.draw.scrollX.set - self.draw['yscrollcommand'] = self.draw.scrollY.set - self.draw.scrollX['command'] = self.draw.xview - self.draw.scrollY['command'] = self.draw.yview - - # draw something. Note that the first square - # is visible, but you need to scroll to see the second one. - self.draw.create_rectangle(0, 0, "3.5i", "3.5i", fill="black") - self.draw.create_rectangle("10i", "10i", "13.5i", "13.5i", fill="blue") - - # pack 'em up - self.draw.scrollX.pack(side=BOTTOM, fill=X) - self.draw.scrollY.pack(side=RIGHT, fill=Y) - self.draw.pack(side=LEFT) - - - def scrollCanvasX(self, *args): - print("scrolling", args) - print(self.draw.scrollX.get()) - - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/dialog-box.py b/Demo/tkinter/matt/dialog-box.py deleted file mode 100644 index c0b8825..0000000 --- a/Demo/tkinter/matt/dialog-box.py +++ /dev/null @@ -1,64 +0,0 @@ -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 - -class Test(Frame): - def printit(self): - print("hi") - - def makeWindow(self): - """Create a top-level dialog with some buttons. - - This uses the Dialog class, which is a wrapper around the Tcl/Tk - tk_dialog script. The function returns 0 if the user clicks 'yes' - or 1 if the user clicks 'no'. - """ - # the parameters to this call are as follows: - d = Dialog( - self, ## name of a toplevel window - title="fred the dialog box",## title on the window - text="click on a choice", ## message to appear in window - bitmap="info", ## bitmap (if any) to appear; - ## if none, use "" - # legal values here are: - # string what it looks like - # ---------------------------------------------- - # error a circle with a slash through it - # grey25 grey square - # grey50 darker grey square - # hourglass use for "wait.." - # info a large, lower case "i" - # questhead a human head with a "?" in it - # question a large "?" - # warning a large "!" - # @fname X bitmap where fname is the path to the file - # - default=0, # the index of the default button choice. - # hitting return selects this - strings=("yes", "no")) - # values of the 'strings' key are the labels for the - # buttons that appear left to right in the dialog box - return d.num - - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=LEFT, fill=BOTH) - - # a hello button - self.hi_there = Button(self, text='Make a New Window', - command=self.makeWindow) - self.hi_there.pack(side=LEFT) - - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.windownum = 0 - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/entry-simple.py b/Demo/tkinter/matt/entry-simple.py deleted file mode 100644 index 1f55df5..0000000 --- a/Demo/tkinter/matt/entry-simple.py +++ /dev/null @@ -1,24 +0,0 @@ -from tkinter import * -import string - -# This program shows how to use a simple type-in box - -class App(Frame): - def __init__(self, master=None): - Frame.__init__(self, master) - self.pack() - - self.entrythingy = Entry() - self.entrythingy.pack() - - # and here we get a callback when the user hits return. we could - # make the key that triggers the callback anything we wanted to. - # other typical options might be or (for anything) - self.entrythingy.bind('', self.print_contents) - - def print_contents(self, event): - print("hi. contents of entry is now ---->", self.entrythingy.get()) - -root = App() -root.master.title("Foo") -root.mainloop() diff --git a/Demo/tkinter/matt/entry-with-shared-variable.py b/Demo/tkinter/matt/entry-with-shared-variable.py deleted file mode 100644 index 7d93da7..0000000 --- a/Demo/tkinter/matt/entry-with-shared-variable.py +++ /dev/null @@ -1,45 +0,0 @@ -from tkinter import * - -# This program shows how to make a typein box shadow a program variable. - -class App(Frame): - def __init__(self, master=None): - Frame.__init__(self, master) - self.pack() - - self.entrythingy = Entry(self) - self.entrythingy.pack() - - self.button = Button(self, text="Uppercase The Entry", - command=self.upper) - self.button.pack() - - # here we have the text in the entry widget tied to a variable. - # changes in the variable are echoed in the widget and vice versa. - # Very handy. - # there are other Variable types. See Tkinter.py for all - # the other variable types that can be shadowed - self.contents = StringVar() - self.contents.set("this is a variable") - self.entrythingy.config(textvariable=self.contents) - - # and here we get a callback when the user hits return. we could - # make the key that triggers the callback anything we wanted to. - # other typical options might be or (for anything) - self.entrythingy.bind('', self.print_contents) - - def upper(self): - # notice here, we don't actually refer to the entry box. - # we just operate on the string variable and we - # because it's being looked at by the entry widget, changing - # the variable changes the entry widget display automatically. - # the strange get/set operators are clunky, true... - str = self.contents.get().upper() - self.contents.set(str) - - def print_contents(self, event): - print("hi. contents of entry is now ---->", self.contents.get()) - -root = App() -root.master.title("Foo") -root.mainloop() diff --git a/Demo/tkinter/matt/killing-window-w-wm.py b/Demo/tkinter/matt/killing-window-w-wm.py deleted file mode 100644 index b4034d1..0000000 --- a/Demo/tkinter/matt/killing-window-w-wm.py +++ /dev/null @@ -1,42 +0,0 @@ -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 -# menu in the decoration border). - - -### ******* this isn't really called -- read the comments -def my_delete_callback(): - print("whoops -- tried to delete me!") - -class Test(Frame): - def deathHandler(self, event): - print(self, "is now getting nuked. performing some save here....") - - def createWidgets(self): - # a hello button - self.hi_there = Button(self, text='Hello') - self.hi_there.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - - ### - ### PREVENT WM kills from happening - ### - - # the docs would have you do this: - -# self.master.protocol("WM_DELETE_WINDOW", my_delete_callback) - - # unfortunately, some window managers will not send this request to a window. - # the "protocol" function seems incapable of trapping these "aggressive" window kills. - # this line of code catches everything, tho. The window is deleted, but you have a chance - # of cleaning up first. - self.bind_all("", self.deathHandler) - - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/menu-all-types-of-entries.py b/Demo/tkinter/matt/menu-all-types-of-entries.py deleted file mode 100644 index 84f162e..0000000 --- a/Demo/tkinter/matt/menu-all-types-of-entries.py +++ /dev/null @@ -1,244 +0,0 @@ -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 -# pretty closely -# -# -# -# This is a MENUBUTTON -# V -# +-------------+ -# | | -# -# +------------++------------++------------+ -# | || || | -# | File || Edit || Options | <-------- the MENUBAR -# | || || | -# +------------++------------++------------+ -# | New... | -# | Open... | -# | Print | -# | | <-------- This is a MENU. The lines of text in the menu are -# | | MENU ENTRIES -# | +---------------+ -# | Open Files > | file1 | -# | | file2 | -# | | another file | <------ this cascading part is also a MENU -# +----------------| | -# | | -# | | -# | | -# +---------------+ - - - -# some miscellaneous callbacks -def new_file(): - print("opening new file") - -def open_file(): - print("opening OLD file") - -def print_something(): - print("picked a menu item") - - - -anchovies = 0 - -def print_anchovies(): - global anchovies - anchovies = not anchovies - print("anchovies?", anchovies) - -def makeCommandMenu(): - # make menu button - Command_button = Menubutton(mBar, text='Simple Button Commands', - underline=0) - Command_button.pack(side=LEFT, padx="2m") - - # make the pulldown part of the File menu. The parameter passed is the master. - # we attach it to the button as a python attribute called "menu" by convention. - # hopefully this isn't too confusing... - Command_button.menu = Menu(Command_button) - - # just to be cute, let's disable the undo option: - Command_button.menu.add_command(label="Undo") - # undo is the 0th entry... - Command_button.menu.entryconfig(0, state=DISABLED) - - Command_button.menu.add_command(label='New...', underline=0, - command=new_file) - Command_button.menu.add_command(label='Open...', underline=0, - command=open_file) - Command_button.menu.add_command(label='Different Font', underline=0, - font='-*-helvetica-*-r-*-*-*-180-*-*-*-*-*-*', - command=print_something) - - # we can make bitmaps be menu entries too. File format is X11 bitmap. - # if you use XV, save it under X11 bitmap format. duh-uh.,.. - Command_button.menu.add_command( - bitmap="info") - #bitmap='@/home/mjc4y/dilbert/project.status.is.doomed.last.panel.bm') - - # this is just a line - Command_button.menu.add('separator') - - # change the color - Command_button.menu.add_command(label='Quit', underline=0, - background='red', - activebackground='green', - command=Command_button.quit) - - # set up a pointer from the file menubutton back to the file menu - Command_button['menu'] = Command_button.menu - - return Command_button - - - -def makeCascadeMenu(): - # make menu button - Cascade_button = Menubutton(mBar, text='Cascading Menus', underline=0) - Cascade_button.pack(side=LEFT, padx="2m") - - # the primary pulldown - Cascade_button.menu = Menu(Cascade_button) - - # this is the menu that cascades from the primary pulldown.... - Cascade_button.menu.choices = Menu(Cascade_button.menu) - - # ...and this is a menu that cascades from that. - Cascade_button.menu.choices.weirdones = Menu(Cascade_button.menu.choices) - - # then you define the menus from the deepest level on up. - Cascade_button.menu.choices.weirdones.add_command(label='avacado') - Cascade_button.menu.choices.weirdones.add_command(label='belgian endive') - Cascade_button.menu.choices.weirdones.add_command(label='beefaroni') - - # definition of the menu one level up... - Cascade_button.menu.choices.add_command(label='Chocolate') - Cascade_button.menu.choices.add_command(label='Vanilla') - Cascade_button.menu.choices.add_command(label='TuttiFruiti') - Cascade_button.menu.choices.add_command(label='WopBopaLoopBapABopBamBoom') - Cascade_button.menu.choices.add_command(label='Rocky Road') - Cascade_button.menu.choices.add_command(label='BubbleGum') - Cascade_button.menu.choices.add_cascade( - label='Weird Flavors', - menu=Cascade_button.menu.choices.weirdones) - - # and finally, the definition for the top level - Cascade_button.menu.add_cascade(label='more choices', - menu=Cascade_button.menu.choices) - - Cascade_button['menu'] = Cascade_button.menu - - return Cascade_button - -def makeCheckbuttonMenu(): - global fred - # make menu button - Checkbutton_button = Menubutton(mBar, text='Checkbutton Menus', - underline=0) - Checkbutton_button.pack(side=LEFT, padx='2m') - - # the primary pulldown - Checkbutton_button.menu = Menu(Checkbutton_button) - - # and all the check buttons. Note that the "variable" "onvalue" and "offvalue" options - # are not supported correctly at present. You have to do all your application - # work through the calback. - Checkbutton_button.menu.add_checkbutton(label='Pepperoni') - Checkbutton_button.menu.add_checkbutton(label='Sausage') - Checkbutton_button.menu.add_checkbutton(label='Extra Cheese') - - # so here's a callback - Checkbutton_button.menu.add_checkbutton(label='Anchovy', - command=print_anchovies) - - # and start with anchovies selected to be on. Do this by - # calling invoke on this menu option. To refer to the "anchovy" menu - # entry we need to know it's index. To do this, we use the index method - # which takes arguments of several forms: - # - # argument what it does - # ----------------------------------- - # a number -- this is useless. - # "last" -- last option in the menu - # "none" -- used with the activate command. see the man page on menus - # "active" -- the currently active menu option. A menu option is made active - # with the 'activate' method - # "@number" -- where 'number' is an integer and is treated like a y coordinate in pixels - # string pattern -- this is the option used below, and attempts to match "labels" using the - # rules of Tcl_StringMatch - Checkbutton_button.menu.invoke(Checkbutton_button.menu.index('Anchovy')) - - # set up a pointer from the file menubutton back to the file menu - Checkbutton_button['menu'] = Checkbutton_button.menu - - return Checkbutton_button - - -def makeRadiobuttonMenu(): - # make menu button - Radiobutton_button = Menubutton(mBar, text='Radiobutton Menus', - underline=0) - Radiobutton_button.pack(side=LEFT, padx='2m') - - # the primary pulldown - Radiobutton_button.menu = Menu(Radiobutton_button) - - # and all the Radio buttons. Note that the "variable" "onvalue" and "offvalue" options - # are not supported correctly at present. You have to do all your application - # work through the calback. - Radiobutton_button.menu.add_radiobutton(label='Republican') - Radiobutton_button.menu.add_radiobutton(label='Democrat') - Radiobutton_button.menu.add_radiobutton(label='Libertarian') - Radiobutton_button.menu.add_radiobutton(label='Commie') - Radiobutton_button.menu.add_radiobutton(label='Facist') - Radiobutton_button.menu.add_radiobutton(label='Labor Party') - Radiobutton_button.menu.add_radiobutton(label='Torie') - Radiobutton_button.menu.add_radiobutton(label='Independent') - Radiobutton_button.menu.add_radiobutton(label='Anarchist') - Radiobutton_button.menu.add_radiobutton(label='No Opinion') - - # set up a pointer from the file menubutton back to the file menu - Radiobutton_button['menu'] = Radiobutton_button.menu - - return Radiobutton_button - - -def makeDisabledMenu(): - Dummy_button = Menubutton(mBar, text='Dead Menu', underline=0) - Dummy_button.pack(side=LEFT, padx='2m') - - # this is the standard way of turning off a whole menu - Dummy_button["state"] = DISABLED - return Dummy_button - - -################################################# -#### Main starts here ... -root = Tk() - - -# make a menu bar -mBar = Frame(root, relief=RAISED, borderwidth=2) -mBar.pack(fill=X) - -Command_button = makeCommandMenu() -Cascade_button = makeCascadeMenu() -Checkbutton_button = makeCheckbuttonMenu() -Radiobutton_button = makeRadiobuttonMenu() -NoMenu = makeDisabledMenu() - -# finally, install the buttons in the menu bar. -# This allows for scanning from one menubutton to the next. -mBar.tk_menuBar(Command_button, Cascade_button, Checkbutton_button, Radiobutton_button, NoMenu) - - -root.title('menu demo') -root.iconname('menu demo') - -root.mainloop() diff --git a/Demo/tkinter/matt/menu-simple.py b/Demo/tkinter/matt/menu-simple.py deleted file mode 100644 index 5d3303f..0000000 --- a/Demo/tkinter/matt/menu-simple.py +++ /dev/null @@ -1,112 +0,0 @@ -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 -# pretty closely -# -# -# -# This is a MENUBUTTON -# V -# +-------------+ -# | | -# -# +------------++------------++------------+ -# | || || | -# | File || Edit || Options | <-------- the MENUBAR -# | || || | -# +------------++------------++------------+ -# | New... | -# | Open... | -# | Print | -# | | <------ This is a MENU. The lines of text in the menu are -# | | MENU ENTRIES -# | +---------------+ -# | Open Files > | file1 | -# | | file2 | -# | | another file | <------ this cascading part is also a MENU -# +----------------| | -# | | -# | | -# | | -# +---------------+ - - - -def new_file(): - print("opening new file") - - -def open_file(): - print("opening OLD file") - - -def makeFileMenu(): - # make menu button : "File" - File_button = Menubutton(mBar, text='File', underline=0) - File_button.pack(side=LEFT, padx="1m") - File_button.menu = Menu(File_button) - - # add an item. The first param is a menu entry type, - # must be one of: "cascade", "checkbutton", "command", "radiobutton", "separator" - # see menu-demo-2.py for examples of use - File_button.menu.add_command(label='New...', underline=0, - command=new_file) - - - File_button.menu.add_command(label='Open...', underline=0, - command=open_file) - - File_button.menu.add_command(label='Quit', underline=0, - command='exit') - - # set up a pointer from the file menubutton back to the file menu - File_button['menu'] = File_button.menu - - return File_button - - - -def makeEditMenu(): - Edit_button = Menubutton(mBar, text='Edit', underline=0) - Edit_button.pack(side=LEFT, padx="1m") - Edit_button.menu = Menu(Edit_button) - - # just to be cute, let's disable the undo option: - Edit_button.menu.add('command', label="Undo") - # Since the tear-off bar is the 0th entry, - # undo is the 1st entry... - Edit_button.menu.entryconfig(1, state=DISABLED) - - # and these are just for show. No "command" callbacks attached. - Edit_button.menu.add_command(label="Cut") - Edit_button.menu.add_command(label="Copy") - Edit_button.menu.add_command(label="Paste") - - # set up a pointer from the file menubutton back to the file menu - Edit_button['menu'] = Edit_button.menu - - return Edit_button - - -################################################# - -#### Main starts here ... -root = Tk() - - -# make a menu bar -mBar = Frame(root, relief=RAISED, borderwidth=2) -mBar.pack(fill=X) - -File_button = makeFileMenu() -Edit_button = makeEditMenu() - -# finally, install the buttons in the menu bar. -# This allows for scanning from one menubutton to the next. -mBar.tk_menuBar(File_button, Edit_button) - -root.title('menu demo') -root.iconname('packer') - -root.mainloop() diff --git a/Demo/tkinter/matt/not-what-you-might-think-1.py b/Demo/tkinter/matt/not-what-you-might-think-1.py deleted file mode 100644 index 85c65c8..0000000 --- a/Demo/tkinter/matt/not-what-you-might-think-1.py +++ /dev/null @@ -1,28 +0,0 @@ -from tkinter import * - - -class Test(Frame): - def createWidgets(self): - - self.Gpanel = Frame(self, width='1i', height='1i', - background='green') - self.Gpanel.pack(side=LEFT) - - # a QUIT button - self.Gpanel.QUIT = Button(self.Gpanel, text='QUIT', - foreground='red', - command=self.quit) - self.Gpanel.QUIT.pack(side=LEFT) - - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() - -test.master.title('packer demo') -test.master.iconname('packer') - -test.mainloop() diff --git a/Demo/tkinter/matt/not-what-you-might-think-2.py b/Demo/tkinter/matt/not-what-you-might-think-2.py deleted file mode 100644 index 4512063..0000000 --- a/Demo/tkinter/matt/not-what-you-might-think-2.py +++ /dev/null @@ -1,30 +0,0 @@ -from tkinter import * - - -class Test(Frame): - def createWidgets(self): - - self.Gpanel = Frame(self, width='1i', height='1i', - background='green') - - # this line turns off the recalculation of geometry by masters. - self.Gpanel.propagate(0) - - self.Gpanel.pack(side=LEFT) - - # a QUIT button - self.Gpanel.QUIT = Button(self.Gpanel, text='QUIT', foreground='red', - command=self.quit) - self.Gpanel.QUIT.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() - -test.master.title('packer demo') -test.master.iconname('packer') - -test.mainloop() diff --git a/Demo/tkinter/matt/packer-and-placer-together.py b/Demo/tkinter/matt/packer-and-placer-together.py deleted file mode 100644 index 3cf6c45..0000000 --- a/Demo/tkinter/matt/packer-and-placer-together.py +++ /dev/null @@ -1,41 +0,0 @@ -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 - - -def do_motion(event): - app.button.place(x=event.x, y=event.y) - -def dothis(): - print('calling me!') - -def createWidgets(top): - # make a frame. Note that the widget is 200 x 200 - # and the window containing is 400x400. We do this - # simply to show that this is possible. The rest of the - # area is inaccesssible. - f = Frame(top, width=200, height=200, background='green') - - # note that we use a different manager here. - # This way, the top level frame widget resizes when the - # application window does. - f.pack(fill=BOTH, expand=1) - - # now make a button - f.button = Button(f, foreground='red', text='amazing', command=dothis) - - # and place it so that the nw corner is - # 1/2 way along the top X edge of its' parent - f.button.place(relx=0.5, rely=0.0, anchor=NW) - - # allow the user to move the button SUIT-style. - f.bind('', do_motion) - - return f - -root = Tk() -app = createWidgets(root) -root.geometry("400x400") -root.maxsize(1000, 1000) -root.mainloop() diff --git a/Demo/tkinter/matt/packer-simple.py b/Demo/tkinter/matt/packer-simple.py deleted file mode 100644 index 64f61d5..0000000 --- a/Demo/tkinter/matt/packer-simple.py +++ /dev/null @@ -1,32 +0,0 @@ -from tkinter import * - - -class Test(Frame): - def printit(self): - print(self.hi_there["command"]) - - def createWidgets(self): - # a hello button - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=LEFT, fill=BOTH) - - self.hi_there = Button(self, text='Hello', - command=self.printit) - self.hi_there.pack(side=LEFT) - - # note how Packer defaults to side=TOP - - self.guy2 = Button(self, text='button 2') - self.guy2.pack() - - self.guy3 = Button(self, text='button 3') - self.guy3.pack() - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/placer-simple.py b/Demo/tkinter/matt/placer-simple.py deleted file mode 100644 index 6be0de9..0000000 --- a/Demo/tkinter/matt/placer-simple.py +++ /dev/null @@ -1,39 +0,0 @@ -from tkinter import * - -# This is a program that tests the placer geom manager - -def do_motion(event): - app.button.place(x=event.x, y=event.y) - -def dothis(): - print('calling me!') - -def createWidgets(top): - # make a frame. Note that the widget is 200 x 200 - # and the window containing is 400x400. We do this - # simply to show that this is possible. The rest of the - # area is inaccesssible. - f = Frame(top, width=200, height=200, background='green') - - # place it so the upper left hand corner of - # the frame is in the upper left corner of - # the parent - f.place(relx=0.0, rely=0.0) - - # now make a button - f.button = Button(f, foreground='red', text='amazing', command=dothis) - - # and place it so that the nw corner is - # 1/2 way along the top X edge of its' parent - f.button.place(relx=0.5, rely=0.0, anchor=NW) - - # allow the user to move the button SUIT-style. - f.bind('', do_motion) - - return f - -root = Tk() -app = createWidgets(root) -root.geometry("400x400") -root.maxsize(1000, 1000) -root.mainloop() diff --git a/Demo/tkinter/matt/pong-demo-1.py b/Demo/tkinter/matt/pong-demo-1.py deleted file mode 100644 index 82a5dc0..0000000 --- a/Demo/tkinter/matt/pong-demo-1.py +++ /dev/null @@ -1,52 +0,0 @@ -from tkinter import * - - -class Pong(Frame): - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=LEFT, fill=BOTH) - - ## The playing field - self.draw = Canvas(self, width="5i", height="5i") - - ## The speed control for the ball - self.speed = Scale(self, orient=HORIZONTAL, label="ball speed", - from_=-100, to=100) - - self.speed.pack(side=BOTTOM, fill=X) - - # The ball - self.ball = self.draw.create_oval("0i", "0i", "0.10i", "0.10i", - fill="red") - self.x = 0.05 - self.y = 0.05 - self.velocity_x = 0.3 - self.velocity_y = 0.5 - - self.draw.pack(side=LEFT) - - def moveBall(self, *args): - if (self.x > 5.0) or (self.x < 0.0): - self.velocity_x = -1.0 * self.velocity_x - if (self.y > 5.0) or (self.y < 0.0): - self.velocity_y = -1.0 * self.velocity_y - - deltax = (self.velocity_x * self.speed.get() / 100.0) - deltay = (self.velocity_y * self.speed.get() / 100.0) - self.x = self.x + deltax - self.y = self.y + deltay - - self.draw.move(self.ball, "%ri" % deltax, "%ri" % deltay) - self.after(10, self.moveBall) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - self.after(10, self.moveBall) - - -game = Pong() - -game.mainloop() diff --git a/Demo/tkinter/matt/printing-coords-of-items.py b/Demo/tkinter/matt/printing-coords-of-items.py deleted file mode 100644 index 771a60d..0000000 --- a/Demo/tkinter/matt/printing-coords-of-items.py +++ /dev/null @@ -1,61 +0,0 @@ -from tkinter import * - -# this file demonstrates the creation of widgets as part of a canvas object - -class Test(Frame): - ################################################################### - ###### Event callbacks for THE CANVAS (not the stuff drawn on it) - ################################################################### - def mouseDown(self, event): - # see if we're inside a dot. If we are, it - # gets tagged as CURRENT for free by tk. - - if not event.widget.find_withtag(CURRENT): - # there is no dot here, so we can make one, - # and bind some interesting behavior to it. - # ------ - # create a dot, and mark it as current - fred = self.draw.create_oval( - event.x - 10, event.y -10, event.x +10, event.y + 10, - fill="green") - self.draw.tag_bind(fred, "", self.mouseEnter) - self.draw.tag_bind(fred, "", self.mouseLeave) - self.lastx = event.x - self.lasty = event.y - - def mouseMove(self, event): - self.draw.move(CURRENT, event.x - self.lastx, event.y - self.lasty) - self.lastx = event.x - self.lasty = event.y - - ################################################################### - ###### Event callbacks for canvas ITEMS (stuff drawn on the canvas) - ################################################################### - def mouseEnter(self, event): - # the "current" tag is applied to the object the cursor is over. - # this happens automatically. - self.draw.itemconfig(CURRENT, fill="red") - print(list(self.draw.coords(CURRENT))) - - def mouseLeave(self, event): - # the "current" tag is applied to the object the cursor is over. - # this happens automatically. - self.draw.itemconfig(CURRENT, fill="blue") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=LEFT, fill=BOTH) - self.draw = Canvas(self, width="5i", height="5i") - self.draw.pack(side=LEFT) - - Widget.bind(self.draw, "<1>", self.mouseDown) - Widget.bind(self.draw, "", self.mouseMove) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/radiobutton-simple.py b/Demo/tkinter/matt/radiobutton-simple.py deleted file mode 100644 index a2719b8..0000000 --- a/Demo/tkinter/matt/radiobutton-simple.py +++ /dev/null @@ -1,62 +0,0 @@ -from tkinter import * - -# This is a demo program that shows how to -# create radio buttons and how to get other widgets to -# share the information in a radio button. -# -# There are other ways of doing this too, but -# the "variable" option of radiobuttons seems to be the easiest. -# -# note how each button has a value it sets the variable to as it gets hit. - - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - - self.flavor = StringVar() - self.flavor.set("chocolate") - - self.radioframe = Frame(self) - self.radioframe.pack() - - # 'text' is the label - # 'variable' is the name of the variable that all these radio buttons share - # 'value' is the value this variable takes on when the radio button is selected - # 'anchor' makes the text appear left justified (default is centered. ick) - self.radioframe.choc = Radiobutton( - self.radioframe, text="Chocolate Flavor", - variable=self.flavor, value="chocolate", - anchor=W) - self.radioframe.choc.pack(fill=X) - - self.radioframe.straw = Radiobutton( - self.radioframe, text="Strawberry Flavor", - variable=self.flavor, value="strawberry", - anchor=W) - self.radioframe.straw.pack(fill=X) - - self.radioframe.lemon = Radiobutton( - self.radioframe, text="Lemon Flavor", - variable=self.flavor, value="lemon", - anchor=W) - self.radioframe.lemon.pack(fill=X) - - # this is a text entry that lets you type in the name of a flavor too. - self.entry = Entry(self, textvariable=self.flavor) - self.entry.pack(fill=X) - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/rubber-band-box-demo-1.py b/Demo/tkinter/matt/rubber-band-box-demo-1.py deleted file mode 100644 index 48526d8..0000000 --- a/Demo/tkinter/matt/rubber-band-box-demo-1.py +++ /dev/null @@ -1,58 +0,0 @@ -from tkinter import * - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', - background='red', - foreground='white', - height=3, - command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - - self.canvasObject = Canvas(self, width="5i", height="5i") - self.canvasObject.pack(side=LEFT) - - def mouseDown(self, event): - # canvas x and y take the screen coords from the event and translate - # them into the coordinate system of the canvas object - self.startx = self.canvasObject.canvasx(event.x) - self.starty = self.canvasObject.canvasy(event.y) - - def mouseMotion(self, event): - # canvas x and y take the screen coords from the event and translate - # them into the coordinate system of the canvas object - x = self.canvasObject.canvasx(event.x) - y = self.canvasObject.canvasy(event.y) - - if (self.startx != event.x) and (self.starty != event.y) : - self.canvasObject.delete(self.rubberbandBox) - self.rubberbandBox = self.canvasObject.create_rectangle( - self.startx, self.starty, x, y) - # this flushes the output, making sure that - # the rectangle makes it to the screen - # before the next event is handled - self.update_idletasks() - - def mouseUp(self, event): - self.canvasObject.delete(self.rubberbandBox) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - - # this is a "tagOrId" for the rectangle we draw on the canvas - self.rubberbandBox = None - - # and the bindings that make it work.. - Widget.bind(self.canvasObject, "", self.mouseDown) - Widget.bind(self.canvasObject, "", self.mouseMotion) - Widget.bind(self.canvasObject, "", self.mouseUp) - - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/rubber-line-demo-1.py b/Demo/tkinter/matt/rubber-line-demo-1.py deleted file mode 100644 index cfc4882..0000000 --- a/Demo/tkinter/matt/rubber-line-demo-1.py +++ /dev/null @@ -1,51 +0,0 @@ -from tkinter import * - -class Test(Frame): - def printit(self): - print("hi") - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', - background='red', - foreground='white', - height=3, - command=self.quit) - self.QUIT.pack(side=BOTTOM, fill=BOTH) - - self.canvasObject = Canvas(self, width="5i", height="5i") - self.canvasObject.pack(side=LEFT) - - def mouseDown(self, event): - # canvas x and y take the screen coords from the event and translate - # them into the coordinate system of the canvas object - self.startx = self.canvasObject.canvasx(event.x) - self.starty = self.canvasObject.canvasy(event.y) - - def mouseMotion(self, event): - # canvas x and y take the screen coords from the event and translate - # them into the coordinate system of the canvas object - x = self.canvasObject.canvasx(event.x) - y = self.canvasObject.canvasy(event.y) - - if (self.startx != event.x) and (self.starty != event.y) : - self.canvasObject.delete(self.rubberbandLine) - self.rubberbandLine = self.canvasObject.create_line( - self.startx, self.starty, x, y) - # this flushes the output, making sure that - # the rectangle makes it to the screen - # before the next event is handled - self.update_idletasks() - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - # this is a "tagOrId" for the rectangle we draw on the canvas - self.rubberbandLine = None - Widget.bind(self.canvasObject, "", self.mouseDown) - Widget.bind(self.canvasObject, "", self.mouseMotion) - - -test = Test() - -test.mainloop() diff --git a/Demo/tkinter/matt/slider-demo-1.py b/Demo/tkinter/matt/slider-demo-1.py deleted file mode 100644 index 687f8a3..0000000 --- a/Demo/tkinter/matt/slider-demo-1.py +++ /dev/null @@ -1,36 +0,0 @@ -from tkinter import * - -# shows how to make a slider, set and get its value under program control - - -class Test(Frame): - def print_value(self, val): - print("slider now at", val) - - def reset(self): - self.slider.set(0) - - def createWidgets(self): - self.slider = Scale(self, from_=0, to=100, - orient=HORIZONTAL, - length="3i", - label="happy slider", - command=self.print_value) - - self.reset = Button(self, text='reset slider', - command=self.reset) - - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - - self.slider.pack(side=LEFT) - self.reset.pack(side=LEFT) - self.QUIT.pack(side=LEFT, fill=BOTH) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/subclass-existing-widgets.py b/Demo/tkinter/matt/subclass-existing-widgets.py deleted file mode 100644 index ce97f35..0000000 --- a/Demo/tkinter/matt/subclass-existing-widgets.py +++ /dev/null @@ -1,28 +0,0 @@ -from tkinter import * - -# This is a program that makes a simple two button application - - -class New_Button(Button): - def callback(self): - print(self.counter) - self.counter = self.counter + 1 - -def createWidgets(top): - f = Frame(top) - f.pack() - f.QUIT = Button(f, text='QUIT', foreground='red', command=top.quit) - - f.QUIT.pack(side=LEFT, fill=BOTH) - - # a hello button - f.hi_there = New_Button(f, text='Hello') - # we do this on a different line because we need to reference f.hi_there - f.hi_there.config(command=f.hi_there.callback) - f.hi_there.pack(side=LEFT) - f.hi_there.counter = 43 - - -root = Tk() -createWidgets(root) -root.mainloop() diff --git a/Demo/tkinter/matt/two-radio-groups.py b/Demo/tkinter/matt/two-radio-groups.py deleted file mode 100644 index 38b61b1..0000000 --- a/Demo/tkinter/matt/two-radio-groups.py +++ /dev/null @@ -1,110 +0,0 @@ -from tkinter import * - -# The way to think about this is that each radio button menu -# controls a different variable -- clicking on one of the -# mutually exclusive choices in a radiobutton assigns some value -# to an application variable you provide. When you define a -# radiobutton menu choice, you have the option of specifying the -# name of a varaible and value to assign to that variable when -# that choice is selected. This clever mechanism relieves you, -# the programmer, from having to write a dumb callback that -# probably wouldn't have done anything more than an assignment -# anyway. The Tkinter options for this follow their Tk -# counterparts: -# {"variable" : my_flavor_variable, "value" : "strawberry"} -# where my_flavor_variable is an instance of one of the -# subclasses of Variable, provided in Tkinter.py (there is -# StringVar(), IntVar(), DoubleVar() and BooleanVar() to choose -# from) - - - -def makePoliticalParties(var): - # make menu button - Radiobutton_button = Menubutton(mBar, text='Political Party', - underline=0) - Radiobutton_button.pack(side=LEFT, padx='2m') - - # the primary pulldown - Radiobutton_button.menu = Menu(Radiobutton_button) - - Radiobutton_button.menu.add_radiobutton(label='Republican', - variable=var, value=1) - - Radiobutton_button.menu.add('radiobutton', {'label': 'Democrat', - 'variable' : var, - 'value' : 2}) - - Radiobutton_button.menu.add('radiobutton', {'label': 'Libertarian', - 'variable' : var, - 'value' : 3}) - - var.set(2) - - # set up a pointer from the file menubutton back to the file menu - Radiobutton_button['menu'] = Radiobutton_button.menu - - return Radiobutton_button - - -def makeFlavors(var): - # make menu button - Radiobutton_button = Menubutton(mBar, text='Flavors', - underline=0) - Radiobutton_button.pack(side=LEFT, padx='2m') - - # the primary pulldown - Radiobutton_button.menu = Menu(Radiobutton_button) - - Radiobutton_button.menu.add_radiobutton(label='Strawberry', - variable=var, value='Strawberry') - - Radiobutton_button.menu.add_radiobutton(label='Chocolate', - variable=var, value='Chocolate') - - Radiobutton_button.menu.add_radiobutton(label='Rocky Road', - variable=var, value='Rocky Road') - - # choose a default - var.set("Chocolate") - - # set up a pointer from the file menubutton back to the file menu - Radiobutton_button['menu'] = Radiobutton_button.menu - - return Radiobutton_button - - -def printStuff(): - print("party is", party.get()) - print("flavor is", flavor.get()) - print() - -################################################# -#### Main starts here ... -root = Tk() - - -# make a menu bar -mBar = Frame(root, relief=RAISED, borderwidth=2) -mBar.pack(fill=X) - -# make two application variables, -# one to control each radio button set -party = IntVar() -flavor = StringVar() - -Radiobutton_button = makePoliticalParties(party) -Radiobutton_button2 = makeFlavors(flavor) - -# finally, install the buttons in the menu bar. -# This allows for scanning from one menubutton to the next. -mBar.tk_menuBar(Radiobutton_button, Radiobutton_button2) - -b = Button(root, text="print party and flavor", foreground="red", - command=printStuff) -b.pack(side=TOP) - -root.title('menu demo') -root.iconname('menu demo') - -root.mainloop() diff --git a/Demo/tkinter/matt/window-creation-more.py b/Demo/tkinter/matt/window-creation-more.py deleted file mode 100644 index 32c8b70..0000000 --- a/Demo/tkinter/matt/window-creation-more.py +++ /dev/null @@ -1,35 +0,0 @@ -from tkinter import * - -# this shows how to create a new window with a button in it -# that can create new windows - -class Test(Frame): - def printit(self): - print("hi") - - def makeWindow(self): - fred = Toplevel() - fred.label = Button(fred, - text="This is window number %d." % self.windownum, - command=self.makeWindow) - fred.label.pack() - self.windownum = self.windownum + 1 - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - self.QUIT.pack(side=LEFT, fill=BOTH) - - # a hello button - self.hi_there = Button(self, text='Make a New Window', - command=self.makeWindow) - self.hi_there.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.windownum = 0 - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/window-creation-simple.py b/Demo/tkinter/matt/window-creation-simple.py deleted file mode 100644 index f5e6230..0000000 --- a/Demo/tkinter/matt/window-creation-simple.py +++ /dev/null @@ -1,31 +0,0 @@ -from tkinter import * - -# this shows how to spawn off new windows at a button press - -class Test(Frame): - def printit(self): - print("hi") - - def makeWindow(self): - fred = Toplevel() - fred.label = Label(fred, text="Here's a new window") - fred.label.pack() - - def createWidgets(self): - self.QUIT = Button(self, text='QUIT', foreground='red', - command=self.quit) - - self.QUIT.pack(side=LEFT, fill=BOTH) - - # a hello button - self.hi_there = Button(self, text='Make a New Window', - command=self.makeWindow) - self.hi_there.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/matt/window-creation-w-location.py b/Demo/tkinter/matt/window-creation-w-location.py deleted file mode 100644 index 9f82367..0000000 --- a/Demo/tkinter/matt/window-creation-w-location.py +++ /dev/null @@ -1,45 +0,0 @@ -from tkinter import * - -import sys -##sys.path.append("/users/mjc4y/projects/python/tkinter/utils") -##from TkinterUtils import * - -# this shows how to create a new window with a button in it that -# can create new windows - -class QuitButton(Button): - def __init__(self, master, *args, **kwargs): - if "text" not in kwargs: - kwargs["text"] = "QUIT" - if "command" not in kwargs: - kwargs["command"] = master.quit - Button.__init__(self, master, *args, **kwargs) - -class Test(Frame): - def makeWindow(self, *args): - fred = Toplevel() - - fred.label = Canvas (fred, width="2i", height="2i") - - fred.label.create_line("0", "0", "2i", "2i") - fred.label.create_line("0", "2i", "2i", "0") - fred.label.pack() - - ##centerWindow(fred, self.master) - - def createWidgets(self): - self.QUIT = QuitButton(self) - self.QUIT.pack(side=LEFT, fill=BOTH) - - self.makeWindow = Button(self, text='Make a New Window', - width=50, height=20, - command=self.makeWindow) - self.makeWindow.pack(side=LEFT) - - def __init__(self, master=None): - Frame.__init__(self, master) - Pack.config(self) - self.createWidgets() - -test = Test() -test.mainloop() diff --git a/Demo/tkinter/ttk/combo_themes.py b/Demo/tkinter/ttk/combo_themes.py deleted file mode 100644 index 45eee2d..0000000 --- a/Demo/tkinter/ttk/combo_themes.py +++ /dev/null @@ -1,46 +0,0 @@ -"""Ttk Theme Selector. - -Although it is a theme selector, you won't notice many changes since -there is only a combobox and a frame around. -""" -from tkinter import ttk - -class App(ttk.Frame): - def __init__(self): - ttk.Frame.__init__(self) - - self.style = ttk.Style() - self._setup_widgets() - - def _change_theme(self, event): - if event.widget.current(): # value #0 is not a theme - newtheme = event.widget.get() - # change to the new theme and refresh all the widgets - self.style.theme_use(newtheme) - - def _setup_widgets(self): - themes = list(self.style.theme_names()) - themes.insert(0, "Pick a theme") - # Create a readonly Combobox which will display 4 values at max, - # which will cause it to create a scrollbar if there are more - # than 4 values in total. - themes_combo = ttk.Combobox(self, values=themes, state="readonly", - height=4) - themes_combo.set(themes[0]) # sets the combobox value to "Pick a theme" - # Combobox widget generates a <> virtual event - # when the user selects an element. This event is generated after - # the listbox is unposted (after you select an item, the combobox's - # listbox disappears, then it is said that listbox is now unposted). - themes_combo.bind("<>", self._change_theme) - themes_combo.pack(fill='x') - - self.pack(fill='both', expand=1) - - -def main(): - app = App() - app.master.title("Ttk Combobox") - app.mainloop() - -if __name__ == "__main__": - main() diff --git a/Demo/tkinter/ttk/dirbrowser.py b/Demo/tkinter/ttk/dirbrowser.py deleted file mode 100644 index bacddb5..0000000 --- a/Demo/tkinter/ttk/dirbrowser.py +++ /dev/null @@ -1,93 +0,0 @@ -"""A directory browser using Ttk Treeview. - -Based on the demo found in Tk 8.5 library/demos/browse -""" -import os -import glob -import tkinter -from tkinter import ttk - -def populate_tree(tree, node): - if tree.set(node, "type") != 'directory': - return - - path = tree.set(node, "fullpath") - tree.delete(*tree.get_children(node)) - - parent = tree.parent(node) - special_dirs = [] if parent else glob.glob('.') + glob.glob('..') - - for p in special_dirs + os.listdir(path): - ptype = None - p = os.path.join(path, p).replace('\\', '/') - if os.path.isdir(p): ptype = "directory" - elif os.path.isfile(p): ptype = "file" - - fname = os.path.split(p)[1] - id = tree.insert(node, "end", text=fname, values=[p, ptype]) - - if ptype == 'directory': - if fname not in ('.', '..'): - tree.insert(id, 0, text="dummy") - tree.item(id, text=fname) - elif ptype == 'file': - size = os.stat(p).st_size - tree.set(id, "size", "%d bytes" % size) - - -def populate_roots(tree): - dir = os.path.abspath('.').replace('\\', '/') - node = tree.insert('', 'end', text=dir, values=[dir, "directory"]) - populate_tree(tree, node) - -def update_tree(event): - tree = event.widget - populate_tree(tree, tree.focus()) - -def change_dir(event): - tree = event.widget - node = tree.focus() - if tree.parent(node): - path = os.path.abspath(tree.set(node, "fullpath")) - if os.path.isdir(path): - os.chdir(path) - tree.delete(tree.get_children('')) - populate_roots(tree) - -def autoscroll(sbar, first, last): - """Hide and show scrollbar as needed.""" - first, last = float(first), float(last) - if first <= 0 and last >= 1: - sbar.grid_remove() - else: - sbar.grid() - sbar.set(first, last) - -root = tkinter.Tk() - -vsb = ttk.Scrollbar(orient="vertical") -hsb = ttk.Scrollbar(orient="horizontal") - -tree = ttk.Treeview(columns=("fullpath", "type", "size"), - displaycolumns="size", yscrollcommand=lambda f, l: autoscroll(vsb, f, l), - xscrollcommand=lambda f, l:autoscroll(hsb, f, l)) - -vsb['command'] = tree.yview -hsb['command'] = tree.xview - -tree.heading("#0", text="Directory Structure", anchor='w') -tree.heading("size", text="File Size", anchor='w') -tree.column("size", stretch=0, width=100) - -populate_roots(tree) -tree.bind('<>', update_tree) -tree.bind('', change_dir) - -# Arrange the tree and its scrollbars in the toplevel -tree.grid(column=0, row=0, sticky='nswe') -vsb.grid(column=1, row=0, sticky='ns') -hsb.grid(column=0, row=1, sticky='ew') -root.grid_columnconfigure(0, weight=1) -root.grid_rowconfigure(0, weight=1) - -root.mainloop() diff --git a/Demo/tkinter/ttk/img/close.gif b/Demo/tkinter/ttk/img/close.gif deleted file mode 100644 index 18cf6c7..0000000 Binary files a/Demo/tkinter/ttk/img/close.gif and /dev/null differ diff --git a/Demo/tkinter/ttk/img/close_active.gif b/Demo/tkinter/ttk/img/close_active.gif deleted file mode 100644 index db7f392..0000000 Binary files a/Demo/tkinter/ttk/img/close_active.gif and /dev/null differ diff --git a/Demo/tkinter/ttk/img/close_pressed.gif b/Demo/tkinter/ttk/img/close_pressed.gif deleted file mode 100644 index 5616954..0000000 Binary files a/Demo/tkinter/ttk/img/close_pressed.gif and /dev/null differ diff --git a/Demo/tkinter/ttk/listbox_scrollcmd.py b/Demo/tkinter/ttk/listbox_scrollcmd.py deleted file mode 100644 index 05faf63..0000000 --- a/Demo/tkinter/ttk/listbox_scrollcmd.py +++ /dev/null @@ -1,37 +0,0 @@ -"""Sample taken from: http://www.tkdocs.com/tutorial/morewidgets.html and -converted to Python, mainly to demonstrate xscrollcommand option. - -grid [tk::listbox .l -yscrollcommand ".s set" -height 5] -column 0 -row 0 -sticky nwes -grid [ttk::scrollbar .s -command ".l yview" -orient vertical] -column 1 -row 0 -sticky ns -grid [ttk::label .stat -text "Status message here" -anchor w] -column 0 -row 1 -sticky we -grid [ttk::sizegrip .sz] -column 1 -row 1 -sticky se -grid columnconfigure . 0 -weight 1; grid rowconfigure . 0 -weight 1 -for {set i 0} {$i<100} {incr i} { - .l insert end "Line $i of 100" - } -""" -import tkinter -from tkinter import ttk - -root = tkinter.Tk() - -l = tkinter.Listbox(height=5) -l.grid(column=0, row=0, sticky='nwes') - -s = ttk.Scrollbar(command=l.yview, orient='vertical') -l['yscrollcommand'] = s.set -s.grid(column=1, row=0, sticky="ns") - -stat = ttk.Label(text="Status message here", anchor='w') -stat.grid(column=0, row=1, sticky='we') - -sz = ttk.Sizegrip() -sz.grid(column=1, row=1, sticky='se') - -root.grid_columnconfigure(0, weight=1) -root.grid_rowconfigure(0, weight=1) - -for i in range(100): - l.insert('end', "Line %d of 100" % i) - -root.mainloop() diff --git a/Demo/tkinter/ttk/mac_searchentry.py b/Demo/tkinter/ttk/mac_searchentry.py deleted file mode 100644 index 97b1eaf..0000000 --- a/Demo/tkinter/ttk/mac_searchentry.py +++ /dev/null @@ -1,78 +0,0 @@ -"""Mac style search widget - -Translated from Tcl code by Schelte Bron, http://wiki.tcl.tk/18188 -""" -import tkinter -from tkinter import ttk - -root = tkinter.Tk() - -data = """ -R0lGODlhKgAaAOfnAFdZVllbWFpcWVtdWlxeW11fXF9hXmBiX2ZnZWhpZ2lraGxua25wbXJ0 -cXR2c3V3dHZ4dXh6d3x+e31/fH6AfYSGg4eJhoiKh4qMiYuNio2PjHmUqnqVq3yXrZGTkJKU -kX+asJSWk32cuJWXlIGcs5aYlX6euZeZloOetZial4SftpqbmIWgt4GhvYahuIKivpudmYei -uYOjv5yem4ijuoSkwIWlwYmlu56gnYamwp+hnoenw4unvaCin4ioxJCnuZykrImpxZmlsoaq -zI2pv6KkoZGouoqqxpqms4erzaOloo6qwYurx5Kqu5untIiszqSmo5CrwoysyJeqtpOrvJyo -tZGsw42typSsvaaopZKtxJWtvp6qt4+uy6epppOuxZCvzKiqp5quuZSvxoyx06mrqJWwx42y -1JKxzpmwwaqsqZaxyI6z1ZqxwqutqpOzz4+01qyuq56yvpizypS00Jm0y5W10Zq1zJa20rCy -rpu3zqizwbGzr6C3yZy4z7K0saG4yp250LO1sqK5y5660Z+70qO7zKy4xaC806S8zba4taG9 -1KW9zq66x6+7yLi6t6S/1rC8yrm7uLO8xLG9y7q8ubS9xabB2anB07K+zLW+xrO/za7CzrTA -zrjAyLXBz77BvbbC0K/G2LjD0bnE0rLK28TGw8bIxcLL07vP28HN28rMycvOyr/T38DU4cnR -2s/RztHT0NLU0cTY5MrW5MvX5dHX2c3Z59bY1dPb5Nbb3dLe7Nvd2t3f3NXh797g3d3j5dnl -9OPl4eTm4+Ln6tzo9uXn5Obo5eDp8efp5uHq8uXq7ejq5+nr6OPs9Ovu6unu8O3v6+vw8+7w -7ezx9O/x7vDy7/Hz8O/19/P18vT38/L3+fb49Pf59vX6/fj69/b7/vn7+Pr8+ff9//v9+vz/ -+/7//P////////////////////////////////////////////////////////////////// -/////////////////////////////////yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJZAD/ACwC -AAIAKAAWAAAI/gD/CRz4bwUGCg8eQFjIsGHDBw4iTLAQgqBFgisuePCiyJOpUyBDihRpypMi -Lx8qaLhIMIyGFZ5sAUsmjZrNmzhzWpO2DJgtTysqfGDpxoMbW8ekeQsXzty4p1CjRjUXrps3 -asJsuclQ4uKKSbamMR3n1JzZs2jRkh1HzuxVXX8y4CDYAwqua+DInVrRwMGJU2kDp31KThy1 -XGWGDlxhi1rTPAUICBBAoEAesoIzn6Vm68MKgVAUHftmzhOCBCtQwQKSoABgzZnJdSMmyIPA -FbCotdUQAIhNa9B6DPCAGbZac+SowVIMRVe4pwkA4GpqDlwuAAmMZx4nTtfnf1mO5JEDNy46 -MHJkxQEDgKC49rPjwC0bqGaZuOoZAKjBPE4NgAzUvYcWOc0QZF91imAnCDHJ5JFAAJN0I2Ba -4iRDUC/gOEVNDwIUcEABCAgAAATUTIgWOMBYRFp80ghiAQIIVAAEAwJIYI2JZnUji0XSYAYO -NcsQA8wy0hCTwAASXGOiONFcxAtpTokTHznfiLMNMAkcAMuE43jDC0vLeGOWe2R5o4sn1LgH -GzkWsvTPMgEOaA433Ag4TjjMuDkQMNi0tZ12sqWoJ0HATMPNffAZZ6U0wLAyqJ62RGoLLrhI -aqmlpzwaEAAh+QQJZAD/ACwAAAAAKgAaAAAI/gD/CRw40JEhQoEC+fGjcOHCMRAjRkxDsKLF -f5YcAcID582ZjyBDJhmZZIjJIUySEDHiBMhFghrtdNnRAgSHmzhz6sTZQcSLITx+CHn5bxSk -Nz5MCMGy55CjTVCjbuJEtSrVQ3uwqDBRQwrFi476SHHxow8qXcemVbPGtm21t3CnTaP27Jgu -VHtuiIjBsuImQkRiiEEFTNo2cOTMKV7MuLE5cN68QUOGSgwKG1EqJqJDY8+rZt8UjxtNunTj -cY3DgZOWS46KIFgGjiI0ZIsqaqNNjWjgYMUpx8Adc3v2aosNMAI1DbqyI9WycOb4IAggQEAB -A3lQBxet/TG4cMpI/tHwYeSfIzxM0uTKNs7UgAQrYL1akaDA7+3bueVqY4NJlUhIcQLNYx8E -AIQ01mwjTQ8DeNAdfouNA8440GBCQxJY3MEGD6p4Y844CQCAizcSgpMLAAlAuJ03qOyQRBR3 -nEHEK+BMGKIui4kDDAAIPKiiYuSYSMQQRCDCxhiziPMYBgDkEaEaAGQA3Y+MjUPOLFoMoUUh -cKxRC4ngeILiH8Qkk0cCAUzSDZWpzbLEE1EwggcYqWCj2DNADFDAAQUgIAAAEFDDJmPYqNJF -F1s4cscTmCDjDTjdSPOHBQggUAEQDAgggTWDPoYMJkFoUdRmddyyjWLeULMMMcAsIw0x4wkM -IME1g25zyxpHxFYUHmyIggw4H4ojITnfiLMNMAkcAAub4BQjihRdDGTJHmvc4Qo1wD6Imje6 -eILbj+BQ4wqu5Q3ECSJ0FOKKMtv4mBg33Pw4zjbKuBIIE1xYpIkhdQQiyi7OtAucj6dt48wu -otQhBRa6VvSJIRwhIkotvgRTzMUYZ6xxMcj4QkspeKDxxRhEmUfIHWjAgQcijEDissuXvCyz -zH7Q8YQURxDhUsn/bCInR3AELfTQZBRt9BBJkCGFFVhMwTNBlnBCSCGEIJQQIAklZMXWRBAR -RRRWENHwRQEBADs=""" - - -s1 = tkinter.PhotoImage("search1", data=data, format="gif -index 0") -s2 = tkinter.PhotoImage("search2", data=data, format="gif -index 1") - -style = ttk.Style() - -style.element_create("Search.field", "image", "search1", - ("focus", "search2"), border=[22, 7, 14], sticky="ew") - -style.layout("Search.entry", [ - ("Search.field", {"sticky": "nswe", "border": 1, "children": - [("Entry.padding", {"sticky": "nswe", "children": - [("Entry.textarea", {"sticky": "nswe"})] - })] - })] -) - -style.configure("Search.entry", background="#b2b2b2") - -root.configure(background="#b2b2b2") - -e1 = ttk.Entry(style="Search.entry", width=20) -e2 = ttk.Entry(style="Search.entry", width=20) - -e1.grid(padx=10, pady=10) -e2.grid(padx=10, pady=10) - -root.mainloop() diff --git a/Demo/tkinter/ttk/notebook_closebtn.py b/Demo/tkinter/ttk/notebook_closebtn.py deleted file mode 100644 index 6e65f09..0000000 --- a/Demo/tkinter/ttk/notebook_closebtn.py +++ /dev/null @@ -1,78 +0,0 @@ -"""A Ttk Notebook with close buttons. - -Based on an example by patthoyts, http://paste.tclers.tk/896 -""" -import os -import tkinter -from tkinter import ttk - -root = tkinter.Tk() - -imgdir = os.path.join(os.path.dirname(__file__), 'img') -i1 = tkinter.PhotoImage("img_close", file=os.path.join(imgdir, 'close.gif')) -i2 = tkinter.PhotoImage("img_closeactive", - file=os.path.join(imgdir, 'close_active.gif')) -i3 = tkinter.PhotoImage("img_closepressed", - file=os.path.join(imgdir, 'close_pressed.gif')) - -style = ttk.Style() - -style.element_create("close", "image", "img_close", - ("active", "pressed", "!disabled", "img_closepressed"), - ("active", "!disabled", "img_closeactive"), border=8, sticky='') - -style.layout("ButtonNotebook", [("ButtonNotebook.client", {"sticky": "nswe"})]) -style.layout("ButtonNotebook.Tab", [ - ("ButtonNotebook.tab", {"sticky": "nswe", "children": - [("ButtonNotebook.padding", {"side": "top", "sticky": "nswe", - "children": - [("ButtonNotebook.focus", {"side": "top", "sticky": "nswe", - "children": - [("ButtonNotebook.label", {"side": "left", "sticky": ''}), - ("ButtonNotebook.close", {"side": "left", "sticky": ''})] - })] - })] - })] -) - -def btn_press(event): - x, y, widget = event.x, event.y, event.widget - elem = widget.identify(x, y) - index = widget.index("@%d,%d" % (x, y)) - - if "close" in elem: - widget.state(['pressed']) - widget.pressed_index = index - -def btn_release(event): - x, y, widget = event.x, event.y, event.widget - - if not widget.instate(['pressed']): - return - - elem = widget.identify(x, y) - index = widget.index("@%d,%d" % (x, y)) - - if "close" in elem and widget.pressed_index == index: - widget.forget(index) - widget.event_generate("<>") - - widget.state(["!pressed"]) - widget.pressed_index = None - - -root.bind_class("TNotebook", "", btn_press, True) -root.bind_class("TNotebook", "", btn_release) - -# create a ttk notebook with our custom style, and add some tabs to it -nb = ttk.Notebook(width=200, height=200, style="ButtonNotebook") -nb.pressed_index = None -f1 = tkinter.Frame(nb, background="red") -f2 = tkinter.Frame(nb, background="green") -f3 = tkinter.Frame(nb, background="blue") -nb.add(f1, text='Red', padding=3) -nb.add(f2, text='Green', padding=3) -nb.add(f3, text='Blue', padding=3) -nb.pack(expand=1, fill='both') - -root.mainloop() diff --git a/Demo/tkinter/ttk/plastik_theme.py b/Demo/tkinter/ttk/plastik_theme.py deleted file mode 100644 index 9c68bb5..0000000 --- a/Demo/tkinter/ttk/plastik_theme.py +++ /dev/null @@ -1,268 +0,0 @@ -"""This demonstrates good part of the syntax accepted by theme_create. - -This is a translation of plastik.tcl to python. -You will need the images used by the plastik theme to test this. The -images (and other tile themes) can be retrived by doing: - -$ cvs -z3 -d:pserver:anonymous@tktable.cvs.sourceforge.net:/cvsroot/tktable \ - co tile-themes - -To test this module you should do, for example: - -import Tkinter -import plastik_theme - -root = Tkinter.Tk() -plastik_theme.install(plastik_image_dir) -... - -Where plastik_image_dir contains the path to the images directory used by -the plastik theme, something like: tile-themes/plastik/plastik -""" -import os -import glob -from tkinter import ttk, PhotoImage - -__all__ = ['install'] - -colors = { - "frame": "#efefef", - "disabledfg": "#aaaaaa", - "selectbg": "#657a9e", - "selectfg": "#ffffff" - } - -imgs = {} -def _load_imgs(imgdir): - imgdir = os.path.expanduser(imgdir) - if not os.path.isdir(imgdir): - raise Exception("%r is not a directory, can't load images" % imgdir) - for f in glob.glob("%s/*.gif" % imgdir): - img = os.path.split(f)[1] - name = img[:-4] - imgs[name] = PhotoImage(name, file=f, format="gif89") - -def install(imgdir): - _load_imgs(imgdir) - style = ttk.Style() - style.theme_create("plastik", "default", settings={ - ".": { - "configure": - {"background": colors['frame'], - "troughcolor": colors['frame'], - "selectbackground": colors['selectbg'], - "selectforeground": colors['selectfg'], - "fieldbackground": colors['frame'], - "font": "TkDefaultFont", - "borderwidth": 1}, - "map": {"foreground": [("disabled", colors['disabledfg'])]} - }, - - "Vertical.TScrollbar": {"layout": [ - ("Vertical.Scrollbar.uparrow", {"side": "top", "sticky": ''}), - ("Vertical.Scrollbar.downarrow", {"side": "bottom", "sticky": ''}), - ("Vertical.Scrollbar.uparrow", {"side": "bottom", "sticky": ''}), - ("Vertical.Scrollbar.trough", {"sticky": "ns", "children": - [("Vertical.Scrollbar.thumb", {"expand": 1, "unit": 1, - "children": [("Vertical.Scrollbar.grip", {"sticky": ''})] - })] - })] - }, - - "Horizontal.TScrollbar": {"layout": [ - ("Horizontal.Scrollbar.leftarrow", {"side": "left", "sticky": ''}), - ("Horizontal.Scrollbar.rightarrow", - {"side": "right", "sticky": ''}), - ("Horizontal.Scrollbar.leftarrow", - {"side": "right", "sticky": ''}), - ("Horizontal.Scrollbar.trough", {"sticky": "ew", "children": - [("Horizontal.Scrollbar.thumb", {"expand": 1, "unit": 1, - "children": [("Horizontal.Scrollbar.grip", {"sticky": ''})] - })] - })] - }, - - "TButton": { - "configure": {"width": 10, "anchor": "center"}, - "layout": [ - ("Button.button", {"children": - [("Button.focus", {"children": - [("Button.padding", {"children": - [("Button.label", {"side": "left", "expand": 1})] - })] - })] - }) - ] - }, - - "Toolbutton": { - "configure": {"anchor": "center"}, - "layout": [ - ("Toolbutton.border", {"children": - [("Toolbutton.button", {"children": - [("Toolbutton.padding", {"children": - [("Toolbutton.label", {"side":"left", "expand":1})] - })] - })] - }) - ] - }, - - "TMenubutton": {"layout": [ - ("Menubutton.button", {"children": - [("Menubutton.indicator", {"side": "right"}), - ("Menubutton.focus", {"children": - [("Menubutton.padding", {"children": - [("Menubutton.label", {"side": "left", "expand": 1})] - })] - })] - })] - }, - - "TNotebook": {"configure": {"tabmargins": [0, 2, 0, 0]}}, - "TNotebook.tab": { - "configure": {"padding": [6, 2, 6, 2], "expand": [0, 0, 2]}, - "map": {"expand": [("selected", [1, 2, 4, 2])]} - }, - "Treeview": {"configure": {"padding": 0}}, - - # elements - "Button.button": {"element create": - ("image", 'button-n', - ("pressed", 'button-p'), ("active", 'button-h'), - {"border": [4, 10], "padding": 4, "sticky":"ewns"} - ) - }, - - "Toolbutton.button": {"element create": - ("image", 'tbutton-n', - ("selected", 'tbutton-p'), ("pressed", 'tbutton-p'), - ("active", 'tbutton-h'), - {"border": [4, 9], "padding": 3, "sticky": "news"} - ) - }, - - "Checkbutton.indicator": {"element create": - ("image", 'check-nu', - ('active', 'selected', 'check-hc'), - ('pressed', 'selected', 'check-pc'), - ('active', 'check-hu'), - ("selected", 'check-nc'), - {"sticky": ''} - ) - }, - - "Radiobutton.indicator": {"element create": - ("image", 'radio-nu', - ('active', 'selected', 'radio-hc'), - ('pressed', 'selected', 'radio-pc'), - ('active', 'radio-hu'), ('selected', 'radio-nc'), - {"sticky": ''} - ) - }, - - "Horizontal.Scrollbar.thumb": {"element create": - ("image", 'hsb-n', {"border": 3, "sticky": "ew"}) - }, - - "Horizontal.Scrollbar.grip": {"element create": ("image", 'hsb-g')}, - "Horizontal.Scrollbar.trough": {"element create": ("image", 'hsb-t')}, - "Vertical.Scrollbar.thumb": {"element create": - ("image", 'vsb-n', {"border": 3, "sticky": "ns"}) - }, - "Vertical.Scrollbar.grip": {"element create": ("image", 'vsb-g')}, - "Vertical.Scrollbar.trough": {"element create": ("image", 'vsb-t')}, - "Scrollbar.uparrow": {"element create": - ("image", 'arrowup-n', ("pressed", 'arrowup-p'), {"sticky": ''}) - }, - "Scrollbar.downarrow": {"element create": - ("image", 'arrowdown-n', - ("pressed", 'arrowdown-p'), {'sticky': ''}) - }, - "Scrollbar.leftarrow": {"element create": - ("image", 'arrowleft-n', - ("pressed", 'arrowleft-p'), {'sticky': ''}) - }, - "Scrollbar.rightarrow": {"element create": - ("image", 'arrowright-n', ("pressed", 'arrowright-p'), - {'sticky': ''}) - }, - - "Horizontal.Scale.slider": {"element create": - ("image", 'hslider-n', {'sticky': ''}) - }, - "Horizontal.Scale.trough": {"element create": - ("image", 'hslider-t', {'border': 1, 'padding': 0}) - }, - "Vertical.Scale.slider": {"element create": - ("image", 'vslider-n', {'sticky': ''}) - }, - "Vertical.Scale.trough": {"element create": - ("image", 'vslider-t', {'border': 1, 'padding': 0}) - }, - - "Entry.field": {"element create": - ("image", 'entry-n', - ("focus", 'entry-f'), - {'border': 2, 'padding': [3, 4], 'sticky': 'news'} - ) - }, - - "Labelframe.border": {"element create": - ("image", 'border', {'border': 4, 'padding': 4, 'sticky': 'news'}) - }, - - "Menubutton.button": {"element create": - ("image", 'combo-r', - ('active', 'combo-ra'), - {'sticky': 'news', 'border': [4, 6, 24, 15], - 'padding': [4, 4, 5]} - ) - }, - "Menubutton.indicator": {"element create": - ("image", 'arrow-d', {"sticky": "e", "border": [15, 0, 0, 0]}) - }, - - "Combobox.field": {"element create": - ("image", 'combo-n', - ('readonly', 'active', 'combo-ra'), - ('focus', 'active', 'combo-fa'), - ('active', 'combo-a'), ('!readonly', 'focus', 'combo-f'), - ('readonly', 'combo-r'), - {'border': [4, 6, 24, 15], 'padding': [4, 4, 5], - 'sticky': 'news'} - ) - }, - "Combobox.downarrow": {"element create": - ("image", 'arrow-d', {'sticky': 'e', 'border': [15, 0, 0, 0]}) - }, - - "Notebook.client": {"element create": - ("image", 'notebook-c', {'border': 4}) - }, - "Notebook.tab": {"element create": - ("image", 'notebook-tn', - ("selected", 'notebook-ts'), ("active", 'notebook-ta'), - {'padding': [0, 2, 0, 0], 'border': [4, 10, 4, 10]} - ) - }, - - "Progressbar.trough": {"element create": - ("image", 'hprogress-t', {'border': 2}) - }, - "Horizontal.Progressbar.pbar": {"element create": - ("image", 'hprogress-b', {'border': [2, 9]}) - }, - "Vertical.Progressbar.pbar": {"element create": - ("image", 'vprogress-b', {'border': [9, 2]}) - }, - - "Treeheading.cell": {"element create": - ("image", 'tree-n', - ("pressed", 'tree-p'), - {'border': [4, 10], 'padding': 4, 'sticky': 'news'} - ) - } - - }) - style.theme_use("plastik") diff --git a/Demo/tkinter/ttk/roundframe.py b/Demo/tkinter/ttk/roundframe.py deleted file mode 100644 index ce3685a..0000000 --- a/Demo/tkinter/ttk/roundframe.py +++ /dev/null @@ -1,111 +0,0 @@ -"""Ttk Frame with rounded corners. - -Based on an example by Bryan Oakley, found at: http://wiki.tcl.tk/20152""" -import tkinter -from tkinter import ttk - -root = tkinter.Tk() - -img1 = tkinter.PhotoImage("frameFocusBorder", data=""" -R0lGODlhQABAAPcAAHx+fMTCxKSipOTi5JSSlNTS1LSytPTy9IyKjMzKzKyq -rOzq7JyanNza3Ly6vPz6/ISChMTGxKSmpOTm5JSWlNTW1LS2tPT29IyOjMzO -zKyurOzu7JyenNze3Ly+vPz+/OkAKOUA5IEAEnwAAACuQACUAAFBAAB+AFYd -QAC0AABBAAB+AIjMAuEEABINAAAAAHMgAQAAAAAAAAAAAKjSxOIEJBIIpQAA -sRgBMO4AAJAAAHwCAHAAAAUAAJEAAHwAAP+eEP8CZ/8Aif8AAG0BDAUAAJEA -AHwAAIXYAOfxAIESAHwAAABAMQAbMBZGMAAAIEggJQMAIAAAAAAAfqgaXESI -5BdBEgB+AGgALGEAABYAAAAAAACsNwAEAAAMLwAAAH61MQBIAABCM8B+AAAU -AAAAAAAApQAAsf8Brv8AlP8AQf8Afv8AzP8A1P8AQf8AfgAArAAABAAADAAA -AACQDADjAAASAAAAAACAAADVABZBAAB+ALjMwOIEhxINUAAAANIgAOYAAIEA -AHwAAGjSAGEEABYIAAAAAEoBB+MAAIEAAHwCACABAJsAAFAAAAAAAGjJAGGL -AAFBFgB+AGmIAAAQAABHAAB+APQoAOE/ABIAAAAAAADQAADjAAASAAAAAPiF -APcrABKDAAB8ABgAGO4AAJAAqXwAAHAAAAUAAJEAAHwAAP8AAP8AAP8AAP8A -AG0pIwW3AJGSAHx8AEocI/QAAICpAHwAAAA0SABk6xaDEgB8AAD//wD//wD/ -/wD//2gAAGEAABYAAAAAAAC0/AHj5AASEgAAAAA01gBkWACDTAB8AFf43PT3 -5IASEnwAAOAYd+PuMBKQTwB8AGgAEGG35RaSEgB8AOj/NOL/ZBL/gwD/fMkc -q4sA5UGpEn4AAIg02xBk/0eD/358fx/4iADk5QASEgAAAALnHABkAACDqQB8 -AMyINARkZA2DgwB8fBABHL0AAEUAqQAAAIAxKOMAPxIwAAAAAIScAOPxABIS -AAAAAIIAnQwA/0IAR3cAACwAAAAAQABAAAAI/wA/CBxIsKDBgwgTKlzIsKFD -gxceNnxAsaLFixgzUrzAsWPFCw8kDgy5EeQDkBxPolypsmXKlx1hXnS48UEH -CwooMCDAgIJOCjx99gz6k+jQnkWR9lRgYYDJkAk/DlAgIMICZlizat3KtatX -rAsiCNDgtCJClQkoFMgqsu3ArBkoZDgA8uDJAwk4bGDmtm9BZgcYzK078m4D -Cgf4+l0skNkGCg3oUhR4d4GCDIoZM2ZWQMECyZQvLMggIbPmzQIyfCZ5YcME -AwFMn/bLLIKBCRtMHljQQcDV2ZqZTRDQYfWFAwMqUJANvC8zBhUWbDi5YUAB -Bsybt2VGoUKH3AcmdP+Im127xOcJih+oXsEDdvOLuQfIMGBD9QwBlsOnzcBD -hfrsuVfefgzJR599A+CnH4Hb9fcfgu29x6BIBgKYYH4DTojQc/5ZGGGGGhpU -IYIKghgiQRw+GKCEJxZIwXwWlthiQyl6KOCMLsJIIoY4LlQjhDf2mNCI9/Eo -5IYO2sjikX+9eGCRCzL5V5JALillY07GaOSVb1G5ookzEnlhlFx+8OOXZb6V -5Y5kcnlmckGmKaaMaZrpJZxWXjnnlmW++WGdZq5ZXQEetKmnlxPgl6eUYhJq -KKOI0imnoNbF2ScFHQJJwW99TsBAAAVYWEAAHEQAZoi1cQDqAAeEV0EACpT/ -JqcACgRQAW6uNWCbYKcyyEwGDBgQwa2tTlBBAhYIQMFejC5AgQAWJNDABK3y -loEDEjCgV6/aOcYBAwp4kIF6rVkXgAEc8IQZVifCBRQHGqya23HGIpsTBgSU -OsFX/PbrVVjpYsCABA4kQCxHu11ogAQUIOAwATpBLDFQFE9sccUYS0wAxD5h -4DACFEggbAHk3jVBA/gtTIHHEADg8sswxyzzzDQDAAEECGAQsgHiTisZResN -gLIHBijwLQEYePzx0kw37fTSSjuMr7ZMzfcgYZUZi58DGsTKwbdgayt22GSP -bXbYY3MggQIaONDzAJ8R9kFlQheQQAAOWGCAARrwdt23Bn8H7vfggBMueOEG -WOBBAAkU0EB9oBGUdXIFZJBABAEEsPjmmnfO+eeeh/55BBEk0Ph/E8Q9meQq -bbDABAN00EADFRRQ++2254777rr3jrvjFTTQwQCpz7u6QRut5/oEzA/g/PPQ -Ry/99NIz//oGrZpUUEAAOw==""") - -img2 = tkinter.PhotoImage("frameBorder", data=""" -R0lGODlhQABAAPcAAHx+fMTCxKSipOTi5JSSlNTS1LSytPTy9IyKjMzKzKyq -rOzq7JyanNza3Ly6vPz6/ISChMTGxKSmpOTm5JSWlNTW1LS2tPT29IyOjMzO -zKyurOzu7JyenNze3Ly+vPz+/OkAKOUA5IEAEnwAAACuQACUAAFBAAB+AFYd -QAC0AABBAAB+AIjMAuEEABINAAAAAHMgAQAAAAAAAAAAAKjSxOIEJBIIpQAA -sRgBMO4AAJAAAHwCAHAAAAUAAJEAAHwAAP+eEP8CZ/8Aif8AAG0BDAUAAJEA -AHwAAIXYAOfxAIESAHwAAABAMQAbMBZGMAAAIEggJQMAIAAAAAAAfqgaXESI -5BdBEgB+AGgALGEAABYAAAAAAACsNwAEAAAMLwAAAH61MQBIAABCM8B+AAAU -AAAAAAAApQAAsf8Brv8AlP8AQf8Afv8AzP8A1P8AQf8AfgAArAAABAAADAAA -AACQDADjAAASAAAAAACAAADVABZBAAB+ALjMwOIEhxINUAAAANIgAOYAAIEA -AHwAAGjSAGEEABYIAAAAAEoBB+MAAIEAAHwCACABAJsAAFAAAAAAAGjJAGGL -AAFBFgB+AGmIAAAQAABHAAB+APQoAOE/ABIAAAAAAADQAADjAAASAAAAAPiF -APcrABKDAAB8ABgAGO4AAJAAqXwAAHAAAAUAAJEAAHwAAP8AAP8AAP8AAP8A -AG0pIwW3AJGSAHx8AEocI/QAAICpAHwAAAA0SABk6xaDEgB8AAD//wD//wD/ -/wD//2gAAGEAABYAAAAAAAC0/AHj5AASEgAAAAA01gBkWACDTAB8AFf43PT3 -5IASEnwAAOAYd+PuMBKQTwB8AGgAEGG35RaSEgB8AOj/NOL/ZBL/gwD/fMkc -q4sA5UGpEn4AAIg02xBk/0eD/358fx/4iADk5QASEgAAAALnHABkAACDqQB8 -AMyINARkZA2DgwB8fBABHL0AAEUAqQAAAIAxKOMAPxIwAAAAAIScAOPxABIS -AAAAAIIAnQwA/0IAR3cAACwAAAAAQABAAAAI/wA/CBxIsKDBgwgTKlzIsKFD -gxceNnxAsaLFixgzUrzAsWPFCw8kDgy5EeQDkBxPolypsmXKlx1hXnS48UEH -CwooMCDAgIJOCjx99gz6k+jQnkWR9lRgYYDJkAk/DlAgIMICkVgHLoggQIPT -ighVJqBQIKvZghkoZDgA8uDJAwk4bDhLd+ABBmvbjnzbgMKBuoA/bKDQgC1F -gW8XKMgQOHABBQsMI76wIIOExo0FZIhM8sKGCQYCYA4cwcCEDSYPLOgg4Oro -uhMEdOB84cCAChReB2ZQYcGGkxsGFGCgGzCFCh1QH5jQIW3xugwSzD4QvIIH -4s/PUgiQYcCG4BkC5P/ObpaBhwreq18nb3Z79+8Dwo9nL9I8evjWsdOX6D59 -fPH71Xeef/kFyB93/sln4EP2Ebjegg31B5+CEDLUIH4PVqiQhOABqKFCF6qn -34cHcfjffCQaFOJtGaZYkIkUuljQigXK+CKCE3po40A0trgjjDru+EGPI/6I -Y4co7kikkAMBmaSNSzL5gZNSDjkghkXaaGIBHjwpY4gThJeljFt2WSWYMQpZ -5pguUnClehS4tuMEDARQgH8FBMBBBExGwIGdAxywXAUBKHCZkAIoEEAFp33W -QGl47ZgBAwZEwKigE1SQgAUCUDCXiwtQIIAFCTQwgaCrZeCABAzIleIGHDD/ -oIAHGUznmXABGMABT4xpmBYBHGgAKGq1ZbppThgAG8EEAW61KwYMSOBAApdy -pNp/BkhAAQLcEqCTt+ACJW645I5rLrgEeOsTBtwiQIEElRZg61sTNBBethSw -CwEA/Pbr778ABywwABBAgAAG7xpAq6mGUUTdAPZ6YIACsRKAAbvtZqzxxhxn -jDG3ybbKFHf36ZVYpuE5oIGhHMTqcqswvyxzzDS/HDMHEiiggQMLDxCZXh8k -BnEBCQTggAUGGKCB0ktr0PTTTEfttNRQT22ABR4EkEABDXgnGUEn31ZABglE -EEAAWaeN9tpqt832221HEEECW6M3wc+Hga3SBgtMODBABw00UEEBgxdO+OGG -J4744oZzXUEDHQxwN7F5G7QRdXxPoPkAnHfu+eeghw665n1vIKhJBQUEADs=""") - -style = ttk.Style() - -style.element_create("RoundedFrame", "image", "frameBorder", - ("focus", "frameFocusBorder"), border=16, sticky="nsew") - -style.layout("RoundedFrame", [("RoundedFrame", {"sticky": "nsew"})]) -style.configure("TEntry", borderwidth=0) - -frame = ttk.Frame(style="RoundedFrame", padding=10) -frame.pack(fill='x') - -frame2 = ttk.Frame(style="RoundedFrame", padding=10) -frame2.pack(fill='both', expand=1) - -entry = ttk.Entry(frame, text='Test') -entry.pack(fill='x') -entry.bind("", lambda evt: frame.state(["focus"])) -entry.bind("", lambda evt: frame.state(["!focus"])) - -text = tkinter.Text(frame2, borderwidth=0, bg="white", highlightthickness=0) -text.pack(fill='both', expand=1) -text.bind("", lambda evt: frame2.state(["focus"])) -text.bind("", lambda evt: frame2.state(["!focus"])) - -root.mainloop() diff --git a/Demo/tkinter/ttk/theme_selector.py b/Demo/tkinter/ttk/theme_selector.py deleted file mode 100644 index 09c5a72..0000000 --- a/Demo/tkinter/ttk/theme_selector.py +++ /dev/null @@ -1,61 +0,0 @@ -"""Ttk Theme Selector v2. - -This is an improvement from the other theme selector (themes_combo.py) -since now you can notice theme changes in Ttk Combobox, Ttk Frame, -Ttk Label and Ttk Button. -""" -import tkinter -from tkinter import ttk - -class App(ttk.Frame): - def __init__(self): - ttk.Frame.__init__(self, borderwidth=3) - - self.style = ttk.Style() - - # XXX Ideally I wouldn't want to create a Tkinter.IntVar to make - # it works with Checkbutton variable option. - self.theme_autochange = tkinter.IntVar(self, 0) - self._setup_widgets() - - def _change_theme(self): - self.style.theme_use(self.themes_combo.get()) - - def _theme_sel_changed(self, widget): - if self.theme_autochange.get(): - self._change_theme() - - def _setup_widgets(self): - themes_lbl = ttk.Label(self, text="Themes") - - themes = self.style.theme_names() - self.themes_combo = ttk.Combobox(self, values=themes, state="readonly") - self.themes_combo.set(themes[0]) - self.themes_combo.bind("<>", self._theme_sel_changed) - - change_btn = ttk.Button(self, text='Change Theme', - command=self._change_theme) - - theme_change_checkbtn = ttk.Checkbutton(self, - text="Change themes when combobox item is activated", - variable=self.theme_autochange) - - themes_lbl.grid(ipadx=6, sticky="w") - self.themes_combo.grid(row=0, column=1, padx=6, sticky="ew") - change_btn.grid(row=0, column=2, padx=6, sticky="e") - theme_change_checkbtn.grid(row=1, columnspan=3, sticky="w", pady=6) - - top = self.winfo_toplevel() - top.rowconfigure(0, weight=1) - top.columnconfigure(0, weight=1) - self.columnconfigure(1, weight=1) - self.grid(row=0, column=0, sticky="nsew", columnspan=3, rowspan=2) - - -def main(): - app = App() - app.master.title("Theme Selector") - app.mainloop() - -if __name__ == "__main__": - main() diff --git a/Demo/tkinter/ttk/treeview_multicolumn.py b/Demo/tkinter/ttk/treeview_multicolumn.py deleted file mode 100644 index be72237..0000000 --- a/Demo/tkinter/ttk/treeview_multicolumn.py +++ /dev/null @@ -1,107 +0,0 @@ -"""Demo based on the demo mclist included with tk source distribution.""" -import tkinter -import tkinter.font -from tkinter import ttk - -tree_columns = ("country", "capital", "currency") -tree_data = [ - ("Argentina", "Buenos Aires", "ARS"), - ("Australia", "Canberra", "AUD"), - ("Brazil", "Brazilia", "BRL"), - ("Canada", "Ottawa", "CAD"), - ("China", "Beijing", "CNY"), - ("France", "Paris", "EUR"), - ("Germany", "Berlin", "EUR"), - ("India", "New Delhi", "INR"), - ("Italy", "Rome", "EUR"), - ("Japan", "Tokyo", "JPY"), - ("Mexico", "Mexico City", "MXN"), - ("Russia", "Moscow", "RUB"), - ("South Africa", "Pretoria", "ZAR"), - ("United Kingdom", "London", "GBP"), - ("United States", "Washington, D.C.", "USD") - ] - -def sortby(tree, col, descending): - """Sort tree contents when a column is clicked on.""" - # grab values to sort - data = [(tree.set(child, col), child) for child in tree.get_children('')] - - # reorder data - data.sort(reverse=descending) - for indx, item in enumerate(data): - tree.move(item[1], '', indx) - - # switch the heading so that it will sort in the opposite direction - tree.heading(col, - command=lambda col=col: sortby(tree, col, int(not descending))) - -class App(object): - def __init__(self): - self.tree = None - self._setup_widgets() - self._build_tree() - - def _setup_widgets(self): - msg = ttk.Label(wraplength="4i", justify="left", anchor="n", - padding=(10, 2, 10, 6), - text=("Ttk is the new Tk themed widget set. One of the widgets it " - "includes is a tree widget, which can be configured to " - "display multiple columns of informational data without " - "displaying the tree itself. This is a simple way to build " - "a listbox that has multiple columns. Clicking on the " - "heading for a column will sort the data by that column. " - "You can also change the width of the columns by dragging " - "the boundary between them.")) - msg.pack(fill='x') - - container = ttk.Frame() - container.pack(fill='both', expand=True) - - # XXX Sounds like a good support class would be one for constructing - # a treeview with scrollbars. - self.tree = ttk.Treeview(columns=tree_columns, show="headings") - vsb = ttk.Scrollbar(orient="vertical", command=self.tree.yview) - hsb = ttk.Scrollbar(orient="horizontal", command=self.tree.xview) - self.tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set) - self.tree.grid(column=0, row=0, sticky='nsew', in_=container) - vsb.grid(column=1, row=0, sticky='ns', in_=container) - hsb.grid(column=0, row=1, sticky='ew', in_=container) - - container.grid_columnconfigure(0, weight=1) - container.grid_rowconfigure(0, weight=1) - - def _build_tree(self): - for col in tree_columns: - self.tree.heading(col, text=col.title(), - command=lambda c=col: sortby(self.tree, c, 0)) - # XXX tkFont.Font().measure expected args are incorrect according - # to the Tk docs - self.tree.column(col, width=tkinter.font.Font().measure(col.title())) - - for item in tree_data: - self.tree.insert('', 'end', values=item) - - # adjust columns lenghts if necessary - for indx, val in enumerate(item): - ilen = tkinter.font.Font().measure(val) - if self.tree.column(tree_columns[indx], width=None) < ilen: - self.tree.column(tree_columns[indx], width=ilen) - -def main(): - root = tkinter.Tk() - root.wm_title("Multi-Column List") - root.wm_iconname("mclist") - - import plastik_theme - try: - plastik_theme.install('~/tile-themes/plastik/plastik') - except Exception: - import warnings - warnings.warn("plastik theme being used without images") - - app = App() - root.mainloop() - -if __name__ == "__main__": - main() diff --git a/Demo/tkinter/ttk/ttkcalendar.py b/Demo/tkinter/ttk/ttkcalendar.py deleted file mode 100644 index 8e35f1f..0000000 --- a/Demo/tkinter/ttk/ttkcalendar.py +++ /dev/null @@ -1,231 +0,0 @@ -""" -Simple calendar using ttk Treeview together with calendar and datetime -classes. -""" -import calendar -import tkinter -import tkinter.font -from tkinter import ttk - -def get_calendar(locale, fwday): - # instantiate proper calendar class - if locale is None: - return calendar.TextCalendar(fwday) - else: - return calendar.LocaleTextCalendar(fwday, locale) - -class Calendar(ttk.Frame): - # XXX ToDo: cget and configure - - datetime = calendar.datetime.datetime - timedelta = calendar.datetime.timedelta - - def __init__(self, master=None, **kw): - """ - WIDGET-SPECIFIC OPTIONS - - locale, firstweekday, year, month, selectbackground, - selectforeground - """ - # remove custom options from kw before initializating ttk.Frame - fwday = kw.pop('firstweekday', calendar.MONDAY) - year = kw.pop('year', self.datetime.now().year) - month = kw.pop('month', self.datetime.now().month) - locale = kw.pop('locale', None) - sel_bg = kw.pop('selectbackground', '#ecffc4') - sel_fg = kw.pop('selectforeground', '#05640e') - - self._date = self.datetime(year, month, 1) - self._selection = None # no date selected - - ttk.Frame.__init__(self, master, **kw) - - self._cal = get_calendar(locale, fwday) - - self.__setup_styles() # creates custom styles - self.__place_widgets() # pack/grid used widgets - self.__config_calendar() # adjust calendar columns and setup tags - # configure a canvas, and proper bindings, for selecting dates - self.__setup_selection(sel_bg, sel_fg) - - # store items ids, used for insertion later - self._items = [self._calendar.insert('', 'end', values='') - for _ in range(6)] - # insert dates in the currently empty calendar - self._build_calendar() - - # set the minimal size for the widget - self._calendar.bind('', self.__minsize) - - def __setitem__(self, item, value): - if item in ('year', 'month'): - raise AttributeError("attribute '%s' is not writeable" % item) - elif item == 'selectbackground': - self._canvas['background'] = value - elif item == 'selectforeground': - self._canvas.itemconfigure(self._canvas.text, item=value) - else: - ttk.Frame.__setitem__(self, item, value) - - def __getitem__(self, item): - if item in ('year', 'month'): - return getattr(self._date, item) - elif item == 'selectbackground': - return self._canvas['background'] - elif item == 'selectforeground': - return self._canvas.itemcget(self._canvas.text, 'fill') - else: - r = ttk.tclobjs_to_py({item: ttk.Frame.__getitem__(self, item)}) - return r[item] - - def __setup_styles(self): - # custom ttk styles - style = ttk.Style(self.master) - arrow_layout = lambda dir: ( - [('Button.focus', {'children': [('Button.%sarrow' % dir, None)]})] - ) - style.layout('L.TButton', arrow_layout('left')) - style.layout('R.TButton', arrow_layout('right')) - - def __place_widgets(self): - # header frame and its widgets - hframe = ttk.Frame(self) - lbtn = ttk.Button(hframe, style='L.TButton', command=self._prev_month) - rbtn = ttk.Button(hframe, style='R.TButton', command=self._next_month) - self._header = ttk.Label(hframe, width=15, anchor='center') - # the calendar - self._calendar = ttk.Treeview(show='', selectmode='none', height=7) - - # pack the widgets - hframe.pack(in_=self, side='top', pady=4, anchor='center') - lbtn.grid(in_=hframe) - self._header.grid(in_=hframe, column=1, row=0, padx=12) - rbtn.grid(in_=hframe, column=2, row=0) - self._calendar.pack(in_=self, expand=1, fill='both', side='bottom') - - def __config_calendar(self): - cols = self._cal.formatweekheader(3).split() - self._calendar['columns'] = cols - self._calendar.tag_configure('header', background='grey90') - self._calendar.insert('', 'end', values=cols, tag='header') - # adjust its columns width - font = tkinter.font.Font() - maxwidth = max(font.measure(col) for col in cols) - for col in cols: - self._calendar.column(col, width=maxwidth, minwidth=maxwidth, - anchor='e') - - def __setup_selection(self, sel_bg, sel_fg): - self._font = tkinter.font.Font() - self._canvas = canvas = tkinter.Canvas(self._calendar, - background=sel_bg, borderwidth=0, highlightthickness=0) - canvas.text = canvas.create_text(0, 0, fill=sel_fg, anchor='w') - - canvas.bind('', lambda evt: canvas.place_forget()) - self._calendar.bind('', lambda evt: canvas.place_forget()) - self._calendar.bind('', self._pressed) - - def __minsize(self, evt): - width, height = self._calendar.master.geometry().split('x') - height = height[:height.index('+')] - self._calendar.master.minsize(width, height) - - def _build_calendar(self): - year, month = self._date.year, self._date.month - - # update header text (Month, YEAR) - header = self._cal.formatmonthname(year, month, 0) - self._header['text'] = header.title() - - # update calendar shown dates - cal = self._cal.monthdayscalendar(year, month) - for indx, item in enumerate(self._items): - week = cal[indx] if indx < len(cal) else [] - fmt_week = [('%02d' % day) if day else '' for day in week] - self._calendar.item(item, values=fmt_week) - - def _show_selection(self, text, bbox): - """Configure canvas for a new selection.""" - x, y, width, height = bbox - - textw = self._font.measure(text) - - canvas = self._canvas - canvas.configure(width=width, height=height) - canvas.coords(canvas.text, width - textw, height / 2 - 1) - canvas.itemconfigure(canvas.text, text=text) - canvas.place(in_=self._calendar, x=x, y=y) - - # Callbacks - - def _pressed(self, evt): - """Clicked somewhere in the calendar.""" - x, y, widget = evt.x, evt.y, evt.widget - item = widget.identify_row(y) - column = widget.identify_column(x) - - if not column or not item in self._items: - # clicked in the weekdays row or just outside the columns - return - - item_values = widget.item(item)['values'] - if not len(item_values): # row is empty for this month - return - - text = item_values[int(column[1]) - 1] - if not text: # date is empty - return - - bbox = widget.bbox(item, column) - if not bbox: # calendar not visible yet - return - - # update and then show selection - text = '%02d' % text - self._selection = (text, item, column) - self._show_selection(text, bbox) - - def _prev_month(self): - """Updated calendar to show the previous month.""" - self._canvas.place_forget() - - self._date = self._date - self.timedelta(days=1) - self._date = self.datetime(self._date.year, self._date.month, 1) - self._build_calendar() # reconstuct calendar - - def _next_month(self): - """Update calendar to show the next month.""" - self._canvas.place_forget() - - year, month = self._date.year, self._date.month - self._date = self._date + self.timedelta( - days=calendar.monthrange(year, month)[1] + 1) - self._date = self.datetime(self._date.year, self._date.month, 1) - self._build_calendar() # reconstruct calendar - - # Properties - - @property - def selection(self): - """Return a datetime representing the current selected date.""" - if not self._selection: - return None - - year, month = self._date.year, self._date.month - return self.datetime(year, month, int(self._selection[0])) - -def test(): - import sys - root = tkinter.Tk() - root.title('Ttk Calendar') - ttkcal = Calendar(firstweekday=calendar.SUNDAY) - ttkcal.pack(expand=1, fill='both') - - if 'win' not in sys.platform: - style = ttk.Style() - style.theme_use('clam') - - root.mainloop() - -if __name__ == '__main__': - test() diff --git a/Demo/tkinter/ttk/widget_state.py b/Demo/tkinter/ttk/widget_state.py deleted file mode 100644 index b68f13b..0000000 --- a/Demo/tkinter/ttk/widget_state.py +++ /dev/null @@ -1,83 +0,0 @@ -"""Sample demo showing widget states and some font styling.""" -from tkinter import ttk - -states = ['active', 'disabled', 'focus', 'pressed', 'selected', - 'background', 'readonly', 'alternate', 'invalid'] - -for state in states[:]: - states.append("!" + state) - -def reset_state(widget): - nostate = states[len(states) // 2:] - widget.state(nostate) - -class App(ttk.Frame): - def __init__(self, title=None): - ttk.Frame.__init__(self, borderwidth=6) - self.master.title(title) - - self.style = ttk.Style() - - # get default font size and family - btn_font = self.style.lookup("TButton", "font") - fsize = str(self.tk.eval("font configure %s -size" % btn_font)) - self.font_family = self.tk.eval("font configure %s -family" % btn_font) - if ' ' in self.font_family: - self.font_family = '{%s}' % self.font_family - self.fsize_prefix = fsize[0] if fsize[0] == '-' else '' - self.base_fsize = int(fsize[1 if fsize[0] == '-' else 0:]) - - # a list to hold all the widgets that will have their states changed - self.update_widgets = [] - - self._setup_widgets() - - def _set_font(self, extra=0): - self.style.configure("TButton", font="%s %s%d" % (self.font_family, - self.fsize_prefix, self.base_fsize + extra)) - - def _new_state(self, widget, newtext): - widget = self.nametowidget(widget) - - if not newtext: - goodstates = ["disabled"] - font_extra = 0 - else: - # set widget state according to what has been entered in the entry - newstates = set(newtext.split()) # eliminate duplicates - - # keep only the valid states - goodstates = [state for state in newstates if state in states] - # define a new font size based on amount of states - font_extra = 2 * len(goodstates) - - # set new widget state - for widget in self.update_widgets: - reset_state(widget) # remove any previous state from the widget - widget.state(goodstates) - - # update Ttk Button font size - self._set_font(font_extra) - return 1 - - def _setup_widgets(self): - btn = ttk.Button(self, text='Enter states and watch') - - entry = ttk.Entry(self, cursor='xterm', validate="key") - entry['validatecommand'] = (self.register(self._new_state), '%W', '%P') - entry.focus() - - self.update_widgets.append(btn) - entry.validate() - - entry.pack(fill='x', padx=6) - btn.pack(side='left', pady=6, padx=6, anchor='n') - self.pack(fill='both', expand=1) - - -def main(): - app = App("Widget State Tester") - app.mainloop() - -if __name__ == "__main__": - main() diff --git a/Tools/demo/Eiffel.py b/Tools/demo/Eiffel.py new file mode 100644 index 0000000..15fa58a --- /dev/null +++ b/Tools/demo/Eiffel.py @@ -0,0 +1,141 @@ +"""Support Eiffel-style preconditions and postconditions.""" + +from types import FunctionType as function + +class EiffelBaseMetaClass(type): + + def __new__(meta, name, bases, dict): + meta.convert_methods(dict) + return super(EiffelBaseMetaClass, meta).__new__(meta, name, bases, + dict) + + @classmethod + def convert_methods(cls, dict): + """Replace functions in dict with EiffelMethod wrappers. + + The dict is modified in place. + + If a method ends in _pre or _post, it is removed from the dict + regardless of whether there is a corresponding method. + """ + # find methods with pre or post conditions + methods = [] + for k, v in dict.items(): + if k.endswith('_pre') or k.endswith('_post'): + assert isinstance(v, function) + elif isinstance(v, function): + methods.append(k) + for m in methods: + pre = dict.get("%s_pre" % m) + post = dict.get("%s_post" % m) + if pre or post: + dict[k] = cls.make_eiffel_method(dict[m], pre, post) + +class EiffelMetaClass1(EiffelBaseMetaClass): + # an implementation of the "eiffel" meta class that uses nested functions + + @staticmethod + def make_eiffel_method(func, pre, post): + def method(self, *args, **kwargs): + if pre: + pre(self, *args, **kwargs) + x = func(self, *args, **kwargs) + if post: + post(self, x, *args, **kwargs) + return x + + if func.__doc__: + method.__doc__ = func.__doc__ + + return method + +class EiffelMethodWrapper: + + def __init__(self, inst, descr): + self._inst = inst + self._descr = descr + + def __call__(self, *args, **kwargs): + return self._descr.callmethod(self._inst, args, kwargs) + +class EiffelDescriptor(object): + + def __init__(self, func, pre, post): + self._func = func + self._pre = pre + self._post = post + + self.__name__ = func.__name__ + self.__doc__ = func.__doc__ + + def __get__(self, obj, cls): + return EiffelMethodWrapper(obj, self) + + def callmethod(self, inst, args, kwargs): + if self._pre: + self._pre(inst, *args, **kwargs) + x = self._func(inst, *args, **kwargs) + if self._post: + self._post(inst, x, *args, **kwargs) + return x + +class EiffelMetaClass2(EiffelBaseMetaClass): + # an implementation of the "eiffel" meta class that uses descriptors + + make_eiffel_method = EiffelDescriptor + +def _test(metaclass): + class Eiffel(metaclass=metaclass): + pass + + class Test(Eiffel): + + def m(self, arg): + """Make it a little larger""" + return arg + 1 + + def m2(self, arg): + """Make it a little larger""" + return arg + 1 + + def m2_pre(self, arg): + assert arg > 0 + + def m2_post(self, result, arg): + assert result > arg + + class Sub(Test): + def m2(self, arg): + return arg**2 + def m2_post(self, Result, arg): + super(Sub, self).m2_post(Result, arg) + assert Result < 100 + + t = Test() + t.m(1) + t.m2(1) + try: + t.m2(0) + except AssertionError: + pass + else: + assert False + + s = Sub() + try: + s.m2(1) + except AssertionError: + pass # result == arg + else: + assert False + try: + s.m2(10) + except AssertionError: + pass # result == 100 + else: + assert False + s.m2(5) + +if __name__ == "__main__": + _test(EiffelMetaClass1) + _test(EiffelMetaClass2) diff --git a/Tools/demo/Vec.py b/Tools/demo/Vec.py new file mode 100644 index 0000000..787af69 --- /dev/null +++ b/Tools/demo/Vec.py @@ -0,0 +1,68 @@ +class Vec: + """ A simple vector class + + Instances of the Vec class can be constructed from numbers + + >>> a = Vec(1, 2, 3) + >>> b = Vec(3, 2, 1) + + added + >>> a + b + Vec(4, 4, 4) + + subtracted + >>> a - b + Vec(-2, 0, 2) + + and multiplied by a scalar on the left + >>> 3.0 * a + Vec(3.0, 6.0, 9.0) + + or on the right + >>> a * 3.0 + Vec(3.0, 6.0, 9.0) + """ + def __init__(self, *v): + self.v = list(v) + + @classmethod + def fromlist(cls, v): + if not isinstance(v, list): + raise TypeError + inst = cls() + inst.v = v + return inst + + def __repr__(self): + args = ', '.join(repr(x) for x in self.v) + return 'Vec({})'.format(args) + + def __len__(self): + return len(self.v) + + def __getitem__(self, i): + return self.v[i] + + def __add__(self, other): + # Element-wise addition + v = [x + y for x, y in zip(self.v, other.v)] + return Vec.fromlist(v) + + def __sub__(self, other): + # Element-wise subtraction + v = [x - y for x, y in zip(self.v, other.v)] + return Vec.fromlist(v) + + def __mul__(self, scalar): + # Multiply by scalar + v = [x * scalar for x in self.v] + return Vec.fromlist(v) + + __rmul__ = __mul__ + + +def test(): + import doctest + doctest.testmod() + +test() diff --git a/Tools/demo/beer.py b/Tools/demo/beer.py new file mode 100755 index 0000000..56eec7b --- /dev/null +++ b/Tools/demo/beer.py @@ -0,0 +1,20 @@ +#! /usr/bin/env python3 + +# By GvR, demystified after a version by Fredrik Lundh. + +import sys + +n = 100 +if sys.argv[1:]: + n = int(sys.argv[1]) + +def bottle(n): + if n == 0: return "no more bottles of beer" + if n == 1: return "one bottle of beer" + return str(n) + " bottles of beer" + +for i in range(n, 0, -1): + print(bottle(i), "on the wall,") + print(bottle(i) + ".") + print("Take one down, pass it around,") + print(bottle(i-1), "on the wall.") diff --git a/Tools/demo/hanoi.py b/Tools/demo/hanoi.py new file mode 100644 index 0000000..34a0bba --- /dev/null +++ b/Tools/demo/hanoi.py @@ -0,0 +1,154 @@ +# Animated Towers of Hanoi using Tk with optional bitmap file in +# background. +# +# Usage: tkhanoi [n [bitmapfile]] +# +# n is the number of pieces to animate; default is 4, maximum 15. +# +# The bitmap file can be any X11 bitmap file (look in +# /usr/include/X11/bitmaps for samples); it is displayed as the +# background of the animation. Default is no bitmap. + +# This uses Steen Lumholt's Tk interface +from tkinter import * + + +# Basic Towers-of-Hanoi algorithm: move n pieces from a to b, using c +# as temporary. For each move, call report() +def hanoi(n, a, b, c, report): + if n <= 0: return + hanoi(n-1, a, c, b, report) + report(n, a, b) + hanoi(n-1, c, b, a, report) + + +# The graphical interface +class Tkhanoi: + + # Create our objects + def __init__(self, n, bitmap = None): + self.n = n + self.tk = tk = Tk() + self.canvas = c = Canvas(tk) + c.pack() + width, height = tk.getint(c['width']), tk.getint(c['height']) + + # Add background bitmap + if bitmap: + self.bitmap = c.create_bitmap(width//2, height//2, + bitmap=bitmap, + foreground='blue') + + # Generate pegs + pegwidth = 10 + pegheight = height//2 + pegdist = width//3 + x1, y1 = (pegdist-pegwidth)//2, height*1//3 + x2, y2 = x1+pegwidth, y1+pegheight + self.pegs = [] + p = c.create_rectangle(x1, y1, x2, y2, fill='black') + self.pegs.append(p) + x1, x2 = x1+pegdist, x2+pegdist + p = c.create_rectangle(x1, y1, x2, y2, fill='black') + self.pegs.append(p) + x1, x2 = x1+pegdist, x2+pegdist + p = c.create_rectangle(x1, y1, x2, y2, fill='black') + self.pegs.append(p) + self.tk.update() + + # Generate pieces + pieceheight = pegheight//16 + maxpiecewidth = pegdist*2//3 + minpiecewidth = 2*pegwidth + self.pegstate = [[], [], []] + self.pieces = {} + x1, y1 = (pegdist-maxpiecewidth)//2, y2-pieceheight-2 + x2, y2 = x1+maxpiecewidth, y1+pieceheight + dx = (maxpiecewidth-minpiecewidth) // (2*max(1, n-1)) + for i in range(n, 0, -1): + p = c.create_rectangle(x1, y1, x2, y2, fill='red') + self.pieces[i] = p + self.pegstate[0].append(i) + x1, x2 = x1 + dx, x2-dx + y1, y2 = y1 - pieceheight-2, y2-pieceheight-2 + self.tk.update() + self.tk.after(25) + + # Run -- never returns + def run(self): + while 1: + hanoi(self.n, 0, 1, 2, self.report) + hanoi(self.n, 1, 2, 0, self.report) + hanoi(self.n, 2, 0, 1, self.report) + hanoi(self.n, 0, 2, 1, self.report) + hanoi(self.n, 2, 1, 0, self.report) + hanoi(self.n, 1, 0, 2, self.report) + + # Reporting callback for the actual hanoi function + def report(self, i, a, b): + if self.pegstate[a][-1] != i: raise RuntimeError # Assertion + del self.pegstate[a][-1] + p = self.pieces[i] + c = self.canvas + + # Lift the piece above peg a + ax1, ay1, ax2, ay2 = c.bbox(self.pegs[a]) + while 1: + x1, y1, x2, y2 = c.bbox(p) + if y2 < ay1: break + c.move(p, 0, -1) + self.tk.update() + + # Move it towards peg b + bx1, by1, bx2, by2 = c.bbox(self.pegs[b]) + newcenter = (bx1+bx2)//2 + while 1: + x1, y1, x2, y2 = c.bbox(p) + center = (x1+x2)//2 + if center == newcenter: break + if center > newcenter: c.move(p, -1, 0) + else: c.move(p, 1, 0) + self.tk.update() + + # Move it down on top of the previous piece + pieceheight = y2-y1 + newbottom = by2 - pieceheight*len(self.pegstate[b]) - 2 + while 1: + x1, y1, x2, y2 = c.bbox(p) + if y2 >= newbottom: break + c.move(p, 0, 1) + self.tk.update() + + # Update peg state + self.pegstate[b].append(i) + + +# Main program +def main(): + import sys + + # First argument is number of pegs, default 4 + if sys.argv[1:]: + n = int(sys.argv[1]) + else: + n = 4 + + # Second argument is bitmap file, default none + if sys.argv[2:]: + bitmap = sys.argv[2] + # Reverse meaning of leading '@' compared to Tk + if bitmap[0] == '@': bitmap = bitmap[1:] + else: bitmap = '@' + bitmap + else: + bitmap = None + + # Create the graphical objects... + h = Tkhanoi(n, bitmap) + + # ...and run! + h.run() + + +# Call main when run as script +if __name__ == '__main__': + main() diff --git a/Tools/demo/life.py b/Tools/demo/life.py new file mode 100755 index 0000000..3cbc053 --- /dev/null +++ b/Tools/demo/life.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python3 +# life.py -- A curses-based version of Conway's Game of Life. +# Contributed by AMK +# Mouse support and color by Dafydd Crosby +# +# An empty board will be displayed, and the following commands are available: +# E : Erase the board +# R : Fill the board randomly +# S : Step for a single generation +# C : Update continuously until a key is struck +# Q : Quit +# Cursor keys : Move the cursor around the board +# Space or Enter : Toggle the contents of the cursor's position +# +# TODO : +# Make board updates faster +# + +import random, string, traceback +import curses + +class LifeBoard: + """Encapsulates a Life board + + Attributes: + X,Y : horizontal and vertical size of the board + state : dictionary mapping (x,y) to 0 or 1 + + Methods: + display(update_board) -- If update_board is true, compute the + next generation. Then display the state + of the board and refresh the screen. + erase() -- clear the entire board + makeRandom() -- fill the board randomly + set(y,x) -- set the given cell to Live; doesn't refresh the screen + toggle(y,x) -- change the given cell from live to dead, or vice + versa, and refresh the screen display + + """ + def __init__(self, scr, char=ord('*')): + """Create a new LifeBoard instance. + + scr -- curses screen object to use for display + char -- character used to render live cells (default: '*') + """ + self.state = {} + self.scr = scr + Y, X = self.scr.getmaxyx() + self.X, self.Y = X-2, Y-2-1 + self.char = char + self.scr.clear() + + # Draw a border around the board + border_line = '+'+(self.X*'-')+'+' + self.scr.addstr(0, 0, border_line) + self.scr.addstr(self.Y+1,0, border_line) + for y in range(0, self.Y): + self.scr.addstr(1+y, 0, '|') + self.scr.addstr(1+y, self.X+1, '|') + self.scr.refresh() + + def set(self, y, x): + """Set a cell to the live state""" + if x<0 or self.X<=x or y<0 or self.Y<=y: + raise ValueError("Coordinates out of range %i,%i"% (y,x)) + self.state[x,y] = 1 + + def toggle(self, y, x): + """Toggle a cell's state between live and dead""" + if x<0 or self.X<=x or y<0 or self.Y<=y: + raise ValueError("Coordinates out of range %i,%i"% (y,x)) + if (x,y) in self.state: + del self.state[x,y] + self.scr.addch(y+1, x+1, ' ') + else: + self.state[x,y] = 1 + if curses.has_colors(): + #Let's pick a random color! + self.scr.attrset(curses.color_pair(random.randrange(1,7))) + self.scr.addch(y+1, x+1, self.char) + self.scr.attrset(0) + self.scr.refresh() + + def erase(self): + """Clear the entire board and update the board display""" + self.state = {} + self.display(update_board=False) + + def display(self, update_board=True): + """Display the whole board, optionally computing one generation""" + M,N = self.X, self.Y + if not update_board: + for i in range(0, M): + for j in range(0, N): + if (i,j) in self.state: + self.scr.addch(j+1, i+1, self.char) + else: + self.scr.addch(j+1, i+1, ' ') + self.scr.refresh() + return + + d = {} + self.boring = 1 + for i in range(0, M): + L = range( max(0, i-1), min(M, i+2) ) + for j in range(0, N): + s = 0 + live = (i,j) in self.state + for k in range( max(0, j-1), min(N, j+2) ): + for l in L: + if (l,k) in self.state: + s += 1 + s -= live + if s == 3: + # Birth + d[i,j] = 1 + if curses.has_colors(): + #Let's pick a random color! + self.scr.attrset(curses.color_pair(random.randrange(1,7))) + self.scr.addch(j+1, i+1, self.char) + self.scr.attrset(0) + if not live: self.boring = 0 + elif s == 2 and live: d[i,j] = 1 # Survival + elif live: + # Death + self.scr.addch(j+1, i+1, ' ') + self.boring = 0 + self.state = d + self.scr.refresh() + + def makeRandom(self): + "Fill the board with a random pattern" + self.state = {} + for i in range(0, self.X): + for j in range(0, self.Y): + if random.random() > 0.5: + self.set(j,i) + + +def erase_menu(stdscr, menu_y): + "Clear the space where the menu resides" + stdscr.move(menu_y, 0) + stdscr.clrtoeol() + stdscr.move(menu_y+1, 0) + stdscr.clrtoeol() + +def display_menu(stdscr, menu_y): + "Display the menu of possible keystroke commands" + erase_menu(stdscr, menu_y) + + # If color, then light the menu up :-) + if curses.has_colors(): + stdscr.attrset(curses.color_pair(1)) + stdscr.addstr(menu_y, 4, + 'Use the cursor keys to move, and space or Enter to toggle a cell.') + stdscr.addstr(menu_y+1, 4, + 'E)rase the board, R)andom fill, S)tep once or C)ontinuously, Q)uit') + stdscr.attrset(0) + +def keyloop(stdscr): + # Clear the screen and display the menu of keys + stdscr.clear() + stdscr_y, stdscr_x = stdscr.getmaxyx() + menu_y = (stdscr_y-3)-1 + display_menu(stdscr, menu_y) + + # If color, then initialize the color pairs + if curses.has_colors(): + curses.init_pair(1, curses.COLOR_BLUE, 0) + curses.init_pair(2, curses.COLOR_CYAN, 0) + curses.init_pair(3, curses.COLOR_GREEN, 0) + curses.init_pair(4, curses.COLOR_MAGENTA, 0) + curses.init_pair(5, curses.COLOR_RED, 0) + curses.init_pair(6, curses.COLOR_YELLOW, 0) + curses.init_pair(7, curses.COLOR_WHITE, 0) + + # Set up the mask to listen for mouse events + curses.mousemask(curses.BUTTON1_CLICKED) + + # Allocate a subwindow for the Life board and create the board object + subwin = stdscr.subwin(stdscr_y-3, stdscr_x, 0, 0) + board = LifeBoard(subwin, char=ord('*')) + board.display(update_board=False) + + # xpos, ypos are the cursor's position + xpos, ypos = board.X//2, board.Y//2 + + # Main loop: + while (1): + stdscr.move(1+ypos, 1+xpos) # Move the cursor + c = stdscr.getch() # Get a keystroke + if 00: ypos -= 1 + elif c == curses.KEY_DOWN and ypos0: xpos -= 1 + elif c == curses.KEY_RIGHT and xpos0 and mouse_x0 and mouse_y 1: print('feeding ...') + words = para.split() + if words: + if do_words: + data = tuple(words) + else: + data = ' '.join(words) + m.put(data) + except KeyboardInterrupt: + print('Interrupted -- continue with data read so far') + if not m.trans: + print('No valid input files') + return + if debug: print('done.') + + if debug > 1: + for key in m.trans.keys(): + if key is None or len(key) < histsize: + print(repr(key), m.trans[key]) + if histsize == 0: print(repr(''), m.trans['']) + print() + while True: + data = m.get() + if do_words: + words = data + else: + words = data.split() + n = 0 + limit = 72 + for w in words: + if n + len(w) > limit: + print() + n = 0 + print(w, end=' ') + n += len(w) + 1 + print() + print() + +if __name__ == "__main__": + test() diff --git a/Tools/demo/mcast.py b/Tools/demo/mcast.py new file mode 100755 index 0000000..6ce7c6d --- /dev/null +++ b/Tools/demo/mcast.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +# +# Send/receive UDP multicast packets. +# Requires that your OS kernel supports IP multicast. +# +# Usage: +# mcast -s (sender, IPv4) +# mcast -s -6 (sender, IPv6) +# mcast (receivers, IPv4) +# mcast -6 (receivers, IPv6) + +MYPORT = 8123 +MYGROUP_4 = '225.0.0.250' +MYGROUP_6 = 'ff15:7079:7468:6f6e:6465:6d6f:6d63:6173' +MYTTL = 1 # Increase to reach other networks + +import time +import struct +import socket +import sys + +def main(): + group = MYGROUP_6 if "-6" in sys.argv[1:] else MYGROUP_4 + + if "-s" in sys.argv[1:]: + sender(group) + else: + receiver(group) + + +def sender(group): + addrinfo = socket.getaddrinfo(group, None)[0] + + s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) + + # Set Time-to-live (optional) + ttl_bin = struct.pack('@i', MYTTL) + if addrinfo[0] == socket.AF_INET: # IPv4 + s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin) + else: + s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin) + + while True: + data = repr(time.time()).encode('utf-8') + b'\0' + s.sendto(data, (addrinfo[4][0], MYPORT)) + time.sleep(1) + + +def receiver(group): + # Look up multicast group address in name server and find out IP version + addrinfo = socket.getaddrinfo(group, None)[0] + + # Create a socket + s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) + + # Allow multiple copies of this program on one machine + # (not strictly needed) + s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + + # Bind it to the port + s.bind(('', MYPORT)) + + group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0]) + # Join group + if addrinfo[0] == socket.AF_INET: # IPv4 + mreq = group_bin + struct.pack('=I', socket.INADDR_ANY) + s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) + else: + mreq = group_bin + struct.pack('@I', 0) + s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq) + + # Loop, printing any data we receive + while True: + data, sender = s.recvfrom(1500) + while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's + print(str(sender) + ' ' + repr(data)) + + +if __name__ == '__main__': + main() diff --git a/Tools/demo/queens.py b/Tools/demo/queens.py new file mode 100755 index 0000000..ffd4bea --- /dev/null +++ b/Tools/demo/queens.py @@ -0,0 +1,85 @@ +#! /usr/bin/env python3 + +"""N queens problem. + +The (well-known) problem is due to Niklaus Wirth. + +This solution is inspired by Dijkstra (Structured Programming). It is +a classic recursive backtracking approach. + +""" + +N = 8 # Default; command line overrides + +class Queens: + + def __init__(self, n=N): + self.n = n + self.reset() + + def reset(self): + n = self.n + self.y = [None] * n # Where is the queen in column x + self.row = [0] * n # Is row[y] safe? + self.up = [0] * (2*n-1) # Is upward diagonal[x-y] safe? + self.down = [0] * (2*n-1) # Is downward diagonal[x+y] safe? + self.nfound = 0 # Instrumentation + + def solve(self, x=0): # Recursive solver + for y in range(self.n): + if self.safe(x, y): + self.place(x, y) + if x+1 == self.n: + self.display() + else: + self.solve(x+1) + self.remove(x, y) + + def safe(self, x, y): + return not self.row[y] and not self.up[x-y] and not self.down[x+y] + + def place(self, x, y): + self.y[x] = y + self.row[y] = 1 + self.up[x-y] = 1 + self.down[x+y] = 1 + + def remove(self, x, y): + self.y[x] = None + self.row[y] = 0 + self.up[x-y] = 0 + self.down[x+y] = 0 + + silent = 0 # If true, count solutions only + + def display(self): + self.nfound = self.nfound + 1 + if self.silent: + return + print('+-' + '--'*self.n + '+') + for y in range(self.n-1, -1, -1): + print('|', end=' ') + for x in range(self.n): + if self.y[x] == y: + print("Q", end=' ') + else: + print(".", end=' ') + print('|') + print('+-' + '--'*self.n + '+') + +def main(): + import sys + silent = 0 + n = N + if sys.argv[1:2] == ['-n']: + silent = 1 + del sys.argv[1] + if sys.argv[1:]: + n = int(sys.argv[1]) + q = Queens(n) + q.silent = silent + q.solve() + print("Found", q.nfound, "solutions.") + +if __name__ == "__main__": + main() diff --git a/Tools/demo/rpython.py b/Tools/demo/rpython.py new file mode 100755 index 0000000..e965720 --- /dev/null +++ b/Tools/demo/rpython.py @@ -0,0 +1,36 @@ +#! /usr/bin/env python3 + +# Remote python client. +# Execute Python commands remotely and send output back. + +import sys +from socket import socket, AF_INET, SOCK_STREAM, SHUT_WR + +PORT = 4127 +BUFSIZE = 1024 + +def main(): + if len(sys.argv) < 3: + print("usage: rpython host command") + sys.exit(2) + host = sys.argv[1] + port = PORT + i = host.find(':') + if i >= 0: + port = int(port[i+1:]) + host = host[:i] + command = ' '.join(sys.argv[2:]) + s = socket(AF_INET, SOCK_STREAM) + s.connect((host, port)) + s.send(command.encode()) + s.shutdown(SHUT_WR) + reply = b'' + while True: + data = s.recv(BUFSIZE) + if not data: + break + reply += data + print(reply.decode(), end=' ') + s.close() + +main() diff --git a/Tools/demo/rpythond.py b/Tools/demo/rpythond.py new file mode 100755 index 0000000..fe24b3d --- /dev/null +++ b/Tools/demo/rpythond.py @@ -0,0 +1,55 @@ +#! /usr/bin/env python3 + +# Remote python server. +# Execute Python commands remotely and send output back. +# WARNING: This version has a gaping security hole -- it accepts requests +# from any host on the Internet! + +import sys +from socket import socket, AF_INET, SOCK_STREAM +import io +import traceback + +PORT = 4127 +BUFSIZE = 1024 + +def main(): + if len(sys.argv) > 1: + port = int(sys.argv[1]) + else: + port = PORT + s = socket(AF_INET, SOCK_STREAM) + s.bind(('', port)) + s.listen(1) + while True: + conn, (remotehost, remoteport) = s.accept() + print('connection from', remotehost, remoteport) + request = b'' + while 1: + data = conn.recv(BUFSIZE) + if not data: + break + request += data + reply = execute(request.decode()) + conn.send(reply.encode()) + conn.close() + +def execute(request): + stdout = sys.stdout + stderr = sys.stderr + sys.stdout = sys.stderr = fakefile = io.StringIO() + try: + try: + exec(request, {}, {}) + except: + print() + traceback.print_exc(100) + finally: + sys.stderr = stderr + sys.stdout = stdout + return fakefile.getvalue() + +try: + main() +except KeyboardInterrupt: + pass diff --git a/Tools/demo/sortvisu.py b/Tools/demo/sortvisu.py new file mode 100644 index 0000000..4173121 --- /dev/null +++ b/Tools/demo/sortvisu.py @@ -0,0 +1,636 @@ +#! /usr/bin/env python3 + +"""Sorting algorithms visualizer using Tkinter. + +This module is comprised of three ``components'': + +- an array visualizer with methods that implement basic sorting +operations (compare, swap) as well as methods for ``annotating'' the +sorting algorithm (e.g. to show the pivot element); + +- a number of sorting algorithms (currently quicksort, insertion sort, +selection sort and bubble sort, as well as a randomization function), +all using the array visualizer for its basic operations and with calls +to its annotation methods; + +- and a ``driver'' class which can be used as a Grail applet or as a +stand-alone application. + +""" + +from tkinter import * +import random + + +XGRID = 10 +YGRID = 10 +WIDTH = 6 + + +class Array: + + class Cancelled(BaseException): + pass + + def __init__(self, master, data=None): + self.master = master + self.frame = Frame(self.master) + self.frame.pack(fill=X) + self.label = Label(self.frame) + self.label.pack() + self.canvas = Canvas(self.frame) + self.canvas.pack() + self.report = Label(self.frame) + self.report.pack() + self.left = self.canvas.create_line(0, 0, 0, 0) + self.right = self.canvas.create_line(0, 0, 0, 0) + self.pivot = self.canvas.create_line(0, 0, 0, 0) + self.items = [] + self.size = self.maxvalue = 0 + if data: + self.setdata(data) + + def setdata(self, data): + olditems = self.items + self.items = [] + for item in olditems: + item.delete() + self.size = len(data) + self.maxvalue = max(data) + self.canvas.config(width=(self.size+1)*XGRID, + height=(self.maxvalue+1)*YGRID) + for i in range(self.size): + self.items.append(ArrayItem(self, i, data[i])) + self.reset("Sort demo, size %d" % self.size) + + speed = "normal" + + def setspeed(self, speed): + self.speed = speed + + def destroy(self): + self.frame.destroy() + + in_mainloop = 0 + stop_mainloop = 0 + + def cancel(self): + self.stop_mainloop = 1 + if self.in_mainloop: + self.master.quit() + + def step(self): + if self.in_mainloop: + self.master.quit() + + def wait(self, msecs): + if self.speed == "fastest": + msecs = 0 + elif self.speed == "fast": + msecs = msecs//10 + elif self.speed == "single-step": + msecs = 1000000000 + if not self.stop_mainloop: + self.master.update() + id = self.master.after(msecs, self.master.quit) + self.in_mainloop = 1 + self.master.mainloop() + self.master.after_cancel(id) + self.in_mainloop = 0 + if self.stop_mainloop: + self.stop_mainloop = 0 + self.message("Cancelled") + raise Array.Cancelled + + def getsize(self): + return self.size + + def show_partition(self, first, last): + for i in range(self.size): + item = self.items[i] + if first <= i < last: + self.canvas.itemconfig(item, fill='red') + else: + self.canvas.itemconfig(item, fill='orange') + self.hide_left_right_pivot() + + def hide_partition(self): + for i in range(self.size): + item = self.items[i] + self.canvas.itemconfig(item, fill='red') + self.hide_left_right_pivot() + + def show_left(self, left): + if not 0 <= left < self.size: + self.hide_left() + return + x1, y1, x2, y2 = self.items[left].position() +## top, bot = HIRO + self.canvas.coords(self.left, (x1 - 2, 0, x1 - 2, 9999)) + self.master.update() + + def show_right(self, right): + if not 0 <= right < self.size: + self.hide_right() + return + x1, y1, x2, y2 = self.items[right].position() + self.canvas.coords(self.right, (x2 + 2, 0, x2 + 2, 9999)) + self.master.update() + + def hide_left_right_pivot(self): + self.hide_left() + self.hide_right() + self.hide_pivot() + + def hide_left(self): + self.canvas.coords(self.left, (0, 0, 0, 0)) + + def hide_right(self): + self.canvas.coords(self.right, (0, 0, 0, 0)) + + def show_pivot(self, pivot): + x1, y1, x2, y2 = self.items[pivot].position() + self.canvas.coords(self.pivot, (0, y1 - 2, 9999, y1 - 2)) + + def hide_pivot(self): + self.canvas.coords(self.pivot, (0, 0, 0, 0)) + + def swap(self, i, j): + if i == j: return + self.countswap() + item = self.items[i] + other = self.items[j] + self.items[i], self.items[j] = other, item + item.swapwith(other) + + def compare(self, i, j): + self.countcompare() + item = self.items[i] + other = self.items[j] + return item.compareto(other) + + def reset(self, msg): + self.ncompares = 0 + self.nswaps = 0 + self.message(msg) + self.updatereport() + self.hide_partition() + + def message(self, msg): + self.label.config(text=msg) + + def countswap(self): + self.nswaps = self.nswaps + 1 + self.updatereport() + + def countcompare(self): + self.ncompares = self.ncompares + 1 + self.updatereport() + + def updatereport(self): + text = "%d cmps, %d swaps" % (self.ncompares, self.nswaps) + self.report.config(text=text) + + +class ArrayItem: + + def __init__(self, array, index, value): + self.array = array + self.index = index + self.value = value + self.canvas = array.canvas + x1, y1, x2, y2 = self.position() + self.item_id = array.canvas.create_rectangle(x1, y1, x2, y2, + fill='red', outline='black', width=1) + self.canvas.tag_bind(self.item_id, '', self.mouse_down) + self.canvas.tag_bind(self.item_id, '', self.mouse_move) + self.canvas.tag_bind(self.item_id, '', self.mouse_up) + + def delete(self): + item_id = self.item_id + self.array = None + self.item_id = None + self.canvas.delete(item_id) + + def mouse_down(self, event): + self.lastx = event.x + self.lasty = event.y + self.origx = event.x + self.origy = event.y + self.canvas.tag_raise(self.item_id) + + def mouse_move(self, event): + self.canvas.move(self.item_id, + event.x - self.lastx, event.y - self.lasty) + self.lastx = event.x + self.lasty = event.y + + def mouse_up(self, event): + i = self.nearestindex(event.x) + if i >= self.array.getsize(): + i = self.array.getsize() - 1 + if i < 0: + i = 0 + other = self.array.items[i] + here = self.index + self.array.items[here], self.array.items[i] = other, self + self.index = i + x1, y1, x2, y2 = self.position() + self.canvas.coords(self.item_id, (x1, y1, x2, y2)) + other.setindex(here) + + def setindex(self, index): + nsteps = steps(self.index, index) + if not nsteps: return + if self.array.speed == "fastest": + nsteps = 0 + oldpts = self.position() + self.index = index + newpts = self.position() + trajectory = interpolate(oldpts, newpts, nsteps) + self.canvas.tag_raise(self.item_id) + for pts in trajectory: + self.canvas.coords(self.item_id, pts) + self.array.wait(50) + + def swapwith(self, other): + nsteps = steps(self.index, other.index) + if not nsteps: return + if self.array.speed == "fastest": + nsteps = 0 + myoldpts = self.position() + otheroldpts = other.position() + self.index, other.index = other.index, self.index + mynewpts = self.position() + othernewpts = other.position() + myfill = self.canvas.itemcget(self.item_id, 'fill') + otherfill = self.canvas.itemcget(other.item_id, 'fill') + self.canvas.itemconfig(self.item_id, fill='green') + self.canvas.itemconfig(other.item_id, fill='yellow') + self.array.master.update() + if self.array.speed == "single-step": + self.canvas.coords(self.item_id, mynewpts) + self.canvas.coords(other.item_id, othernewpts) + self.array.master.update() + self.canvas.itemconfig(self.item_id, fill=myfill) + self.canvas.itemconfig(other.item_id, fill=otherfill) + self.array.wait(0) + return + mytrajectory = interpolate(myoldpts, mynewpts, nsteps) + othertrajectory = interpolate(otheroldpts, othernewpts, nsteps) + if self.value > other.value: + self.canvas.tag_raise(self.item_id) + self.canvas.tag_raise(other.item_id) + else: + self.canvas.tag_raise(other.item_id) + self.canvas.tag_raise(self.item_id) + try: + for i in range(len(mytrajectory)): + mypts = mytrajectory[i] + otherpts = othertrajectory[i] + self.canvas.coords(self.item_id, mypts) + self.canvas.coords(other.item_id, otherpts) + self.array.wait(50) + finally: + mypts = mytrajectory[-1] + otherpts = othertrajectory[-1] + self.canvas.coords(self.item_id, mypts) + self.canvas.coords(other.item_id, otherpts) + self.canvas.itemconfig(self.item_id, fill=myfill) + self.canvas.itemconfig(other.item_id, fill=otherfill) + + def compareto(self, other): + myfill = self.canvas.itemcget(self.item_id, 'fill') + otherfill = self.canvas.itemcget(other.item_id, 'fill') + if self.value < other.value: + myflash = 'white' + otherflash = 'black' + outcome = -1 + elif self.value > other.value: + myflash = 'black' + otherflash = 'white' + outcome = 1 + else: + myflash = otherflash = 'grey' + outcome = 0 + try: + self.canvas.itemconfig(self.item_id, fill=myflash) + self.canvas.itemconfig(other.item_id, fill=otherflash) + self.array.wait(500) + finally: + self.canvas.itemconfig(self.item_id, fill=myfill) + self.canvas.itemconfig(other.item_id, fill=otherfill) + return outcome + + def position(self): + x1 = (self.index+1)*XGRID - WIDTH//2 + x2 = x1+WIDTH + y2 = (self.array.maxvalue+1)*YGRID + y1 = y2 - (self.value)*YGRID + return x1, y1, x2, y2 + + def nearestindex(self, x): + return int(round(float(x)/XGRID)) - 1 + + +# Subroutines that don't need an object + +def steps(here, there): + nsteps = abs(here - there) + if nsteps <= 3: + nsteps = nsteps * 3 + elif nsteps <= 5: + nsteps = nsteps * 2 + elif nsteps > 10: + nsteps = 10 + return nsteps + +def interpolate(oldpts, newpts, n): + if len(oldpts) != len(newpts): + raise ValueError("can't interpolate arrays of different length") + pts = [0]*len(oldpts) + res = [tuple(oldpts)] + for i in range(1, n): + for k in range(len(pts)): + pts[k] = oldpts[k] + (newpts[k] - oldpts[k])*i//n + res.append(tuple(pts)) + res.append(tuple(newpts)) + return res + + +# Various (un)sorting algorithms + +def uniform(array): + size = array.getsize() + array.setdata([(size+1)//2] * size) + array.reset("Uniform data, size %d" % size) + +def distinct(array): + size = array.getsize() + array.setdata(range(1, size+1)) + array.reset("Distinct data, size %d" % size) + +def randomize(array): + array.reset("Randomizing") + n = array.getsize() + for i in range(n): + j = random.randint(0, n-1) + array.swap(i, j) + array.message("Randomized") + +def insertionsort(array): + size = array.getsize() + array.reset("Insertion sort") + for i in range(1, size): + j = i-1 + while j >= 0: + if array.compare(j, j+1) <= 0: + break + array.swap(j, j+1) + j = j-1 + array.message("Sorted") + +def selectionsort(array): + size = array.getsize() + array.reset("Selection sort") + try: + for i in range(size): + array.show_partition(i, size) + for j in range(i+1, size): + if array.compare(i, j) > 0: + array.swap(i, j) + array.message("Sorted") + finally: + array.hide_partition() + +def bubblesort(array): + size = array.getsize() + array.reset("Bubble sort") + for i in range(size): + for j in range(1, size): + if array.compare(j-1, j) > 0: + array.swap(j-1, j) + array.message("Sorted") + +def quicksort(array): + size = array.getsize() + array.reset("Quicksort") + try: + stack = [(0, size)] + while stack: + first, last = stack[-1] + del stack[-1] + array.show_partition(first, last) + if last-first < 5: + array.message("Insertion sort") + for i in range(first+1, last): + j = i-1 + while j >= first: + if array.compare(j, j+1) <= 0: + break + array.swap(j, j+1) + j = j-1 + continue + array.message("Choosing pivot") + j, i, k = first, (first+last) // 2, last-1 + if array.compare(k, i) < 0: + array.swap(k, i) + if array.compare(k, j) < 0: + array.swap(k, j) + if array.compare(j, i) < 0: + array.swap(j, i) + pivot = j + array.show_pivot(pivot) + array.message("Pivot at left of partition") + array.wait(1000) + left = first + right = last + while 1: + array.message("Sweep right pointer") + right = right-1 + array.show_right(right) + while right > first and array.compare(right, pivot) >= 0: + right = right-1 + array.show_right(right) + array.message("Sweep left pointer") + left = left+1 + array.show_left(left) + while left < last and array.compare(left, pivot) <= 0: + left = left+1 + array.show_left(left) + if left > right: + array.message("End of partition") + break + array.message("Swap items") + array.swap(left, right) + array.message("Swap pivot back") + array.swap(pivot, right) + n1 = right-first + n2 = last-left + if n1 > 1: stack.append((first, right)) + if n2 > 1: stack.append((left, last)) + array.message("Sorted") + finally: + array.hide_partition() + +def demosort(array): + while 1: + for alg in [quicksort, insertionsort, selectionsort, bubblesort]: + randomize(array) + alg(array) + + +# Sort demo class -- usable as a Grail applet + +class SortDemo: + + def __init__(self, master, size=15): + self.master = master + self.size = size + self.busy = 0 + self.array = Array(self.master) + + self.botframe = Frame(master) + self.botframe.pack(side=BOTTOM) + self.botleftframe = Frame(self.botframe) + self.botleftframe.pack(side=LEFT, fill=Y) + self.botrightframe = Frame(self.botframe) + self.botrightframe.pack(side=RIGHT, fill=Y) + + self.b_qsort = Button(self.botleftframe, + text="Quicksort", command=self.c_qsort) + self.b_qsort.pack(fill=X) + self.b_isort = Button(self.botleftframe, + text="Insertion sort", command=self.c_isort) + self.b_isort.pack(fill=X) + self.b_ssort = Button(self.botleftframe, + text="Selection sort", command=self.c_ssort) + self.b_ssort.pack(fill=X) + self.b_bsort = Button(self.botleftframe, + text="Bubble sort", command=self.c_bsort) + self.b_bsort.pack(fill=X) + + # Terrible hack to overcome limitation of OptionMenu... + class MyIntVar(IntVar): + def __init__(self, master, demo): + self.demo = demo + IntVar.__init__(self, master) + def set(self, value): + IntVar.set(self, value) + if str(value) != '0': + self.demo.resize(value) + + self.v_size = MyIntVar(self.master, self) + self.v_size.set(size) + sizes = [1, 2, 3, 4] + list(range(5, 55, 5)) + if self.size not in sizes: + sizes.append(self.size) + sizes.sort() + self.m_size = OptionMenu(self.botleftframe, self.v_size, *sizes) + self.m_size.pack(fill=X) + + self.v_speed = StringVar(self.master) + self.v_speed.set("normal") + self.m_speed = OptionMenu(self.botleftframe, self.v_speed, + "single-step", "normal", "fast", "fastest") + self.m_speed.pack(fill=X) + + self.b_step = Button(self.botleftframe, + text="Step", command=self.c_step) + self.b_step.pack(fill=X) + + self.b_randomize = Button(self.botrightframe, + text="Randomize", command=self.c_randomize) + self.b_randomize.pack(fill=X) + self.b_uniform = Button(self.botrightframe, + text="Uniform", command=self.c_uniform) + self.b_uniform.pack(fill=X) + self.b_distinct = Button(self.botrightframe, + text="Distinct", command=self.c_distinct) + self.b_distinct.pack(fill=X) + self.b_demo = Button(self.botrightframe, + text="Demo", command=self.c_demo) + self.b_demo.pack(fill=X) + self.b_cancel = Button(self.botrightframe, + text="Cancel", command=self.c_cancel) + self.b_cancel.pack(fill=X) + self.b_cancel.config(state=DISABLED) + self.b_quit = Button(self.botrightframe, + text="Quit", command=self.c_quit) + self.b_quit.pack(fill=X) + + def resize(self, newsize): + if self.busy: + self.master.bell() + return + self.size = newsize + self.array.setdata(range(1, self.size+1)) + + def c_qsort(self): + self.run(quicksort) + + def c_isort(self): + self.run(insertionsort) + + def c_ssort(self): + self.run(selectionsort) + + def c_bsort(self): + self.run(bubblesort) + + def c_demo(self): + self.run(demosort) + + def c_randomize(self): + self.run(randomize) + + def c_uniform(self): + self.run(uniform) + + def c_distinct(self): + self.run(distinct) + + def run(self, func): + if self.busy: + self.master.bell() + return + self.busy = 1 + self.array.setspeed(self.v_speed.get()) + self.b_cancel.config(state=NORMAL) + try: + func(self.array) + except Array.Cancelled: + pass + self.b_cancel.config(state=DISABLED) + self.busy = 0 + + def c_cancel(self): + if not self.busy: + self.master.bell() + return + self.array.cancel() + + def c_step(self): + if not self.busy: + self.master.bell() + return + self.v_speed.set("single-step") + self.array.setspeed("single-step") + self.array.step() + + def c_quit(self): + if self.busy: + self.array.cancel() + self.master.after_idle(self.master.quit) + + +# Main program -- for stand-alone operation outside Grail + +def main(): + root = Tk() + demo = SortDemo(root) + root.protocol('WM_DELETE_WINDOW', demo.c_quit) + root.mainloop() + +if __name__ == '__main__': + main() diff --git a/Tools/demo/ss1.py b/Tools/demo/ss1.py new file mode 100644 index 0000000..8b07489 --- /dev/null +++ b/Tools/demo/ss1.py @@ -0,0 +1,842 @@ +"""SS1 -- a spreadsheet.""" + +import os +import re +import sys +import html +from xml.parsers import expat + +LEFT, CENTER, RIGHT = "LEFT", "CENTER", "RIGHT" + +def ljust(x, n): + return x.ljust(n) +def center(x, n): + return x.center(n) +def rjust(x, n): + return x.rjust(n) +align2action = {LEFT: ljust, CENTER: center, RIGHT: rjust} + +align2xml = {LEFT: "left", CENTER: "center", RIGHT: "right"} +xml2align = {"left": LEFT, "center": CENTER, "right": RIGHT} + +align2anchor = {LEFT: "w", CENTER: "center", RIGHT: "e"} + +def sum(seq): + total = 0 + for x in seq: + if x is not None: + total += x + return total + +class Sheet: + + def __init__(self): + self.cells = {} # {(x, y): cell, ...} + self.ns = dict( + cell = self.cellvalue, + cells = self.multicellvalue, + sum = sum, + ) + + def cellvalue(self, x, y): + cell = self.getcell(x, y) + if hasattr(cell, 'recalc'): + return cell.recalc(self.ns) + else: + return cell + + def multicellvalue(self, x1, y1, x2, y2): + if x1 > x2: + x1, x2 = x2, x1 + if y1 > y2: + y1, y2 = y2, y1 + seq = [] + for y in range(y1, y2+1): + for x in range(x1, x2+1): + seq.append(self.cellvalue(x, y)) + return seq + + def getcell(self, x, y): + return self.cells.get((x, y)) + + def setcell(self, x, y, cell): + assert x > 0 and y > 0 + assert isinstance(cell, BaseCell) + self.cells[x, y] = cell + + def clearcell(self, x, y): + try: + del self.cells[x, y] + except KeyError: + pass + + def clearcells(self, x1, y1, x2, y2): + for xy in self.selectcells(x1, y1, x2, y2): + del self.cells[xy] + + def clearrows(self, y1, y2): + self.clearcells(0, y1, sys.maxint, y2) + + def clearcolumns(self, x1, x2): + self.clearcells(x1, 0, x2, sys.maxint) + + def selectcells(self, x1, y1, x2, y2): + if x1 > x2: + x1, x2 = x2, x1 + if y1 > y2: + y1, y2 = y2, y1 + return [(x, y) for x, y in self.cells + if x1 <= x <= x2 and y1 <= y <= y2] + + def movecells(self, x1, y1, x2, y2, dx, dy): + if dx == 0 and dy == 0: + return + if x1 > x2: + x1, x2 = x2, x1 + if y1 > y2: + y1, y2 = y2, y1 + assert x1+dx > 0 and y1+dy > 0 + new = {} + for x, y in self.cells: + cell = self.cells[x, y] + if hasattr(cell, 'renumber'): + cell = cell.renumber(x1, y1, x2, y2, dx, dy) + if x1 <= x <= x2 and y1 <= y <= y2: + x += dx + y += dy + new[x, y] = cell + self.cells = new + + def insertrows(self, y, n): + assert n > 0 + self.movecells(0, y, sys.maxint, sys.maxint, 0, n) + + def deleterows(self, y1, y2): + if y1 > y2: + y1, y2 = y2, y1 + self.clearrows(y1, y2) + self.movecells(0, y2+1, sys.maxint, sys.maxint, 0, y1-y2-1) + + def insertcolumns(self, x, n): + assert n > 0 + self.movecells(x, 0, sys.maxint, sys.maxint, n, 0) + + def deletecolumns(self, x1, x2): + if x1 > x2: + x1, x2 = x2, x1 + self.clearcells(x1, x2) + self.movecells(x2+1, 0, sys.maxint, sys.maxint, x1-x2-1, 0) + + def getsize(self): + maxx = maxy = 0 + for x, y in self.cells: + maxx = max(maxx, x) + maxy = max(maxy, y) + return maxx, maxy + + def reset(self): + for cell in self.cells.values(): + if hasattr(cell, 'reset'): + cell.reset() + + def recalc(self): + self.reset() + for cell in self.cells.values(): + if hasattr(cell, 'recalc'): + cell.recalc(self.ns) + + def display(self): + maxx, maxy = self.getsize() + width, height = maxx+1, maxy+1 + colwidth = [1] * width + full = {} + # Add column heading labels in row 0 + for x in range(1, width): + full[x, 0] = text, alignment = colnum2name(x), RIGHT + colwidth[x] = max(colwidth[x], len(text)) + # Add row labels in column 0 + for y in range(1, height): + full[0, y] = text, alignment = str(y), RIGHT + colwidth[0] = max(colwidth[0], len(text)) + # Add sheet cells in columns with x>0 and y>0 + for (x, y), cell in self.cells.items(): + if x <= 0 or y <= 0: + continue + if hasattr(cell, 'recalc'): + cell.recalc(self.ns) + if hasattr(cell, 'format'): + text, alignment = cell.format() + assert isinstance(text, str) + assert alignment in (LEFT, CENTER, RIGHT) + else: + text = str(cell) + if isinstance(cell, str): + alignment = LEFT + else: + alignment = RIGHT + full[x, y] = (text, alignment) + colwidth[x] = max(colwidth[x], len(text)) + # Calculate the horizontal separator line (dashes and dots) + sep = "" + for x in range(width): + if sep: + sep += "+" + sep += "-"*colwidth[x] + # Now print The full grid + for y in range(height): + line = "" + for x in range(width): + text, alignment = full.get((x, y)) or ("", LEFT) + text = align2action[alignment](text, colwidth[x]) + if line: + line += '|' + line += text + print(line) + if y == 0: + print(sep) + + def xml(self): + out = [''] + for (x, y), cell in self.cells.items(): + if hasattr(cell, 'xml'): + cellxml = cell.xml() + else: + cellxml = '%s' % html.escape(cell) + out.append('\n %s\n' % + (y, x, cellxml)) + out.append('') + return '\n'.join(out) + + def save(self, filename): + text = self.xml() + f = open(filename, "w") + f.write(text) + if text and not text.endswith('\n'): + f.write('\n') + f.close() + + def load(self, filename): + f = open(filename, 'rb') + SheetParser(self).parsefile(f) + f.close() + +class SheetParser: + + def __init__(self, sheet): + self.sheet = sheet + + def parsefile(self, f): + parser = expat.ParserCreate() + parser.StartElementHandler = self.startelement + parser.EndElementHandler = self.endelement + parser.CharacterDataHandler = self.data + parser.ParseFile(f) + + def startelement(self, tag, attrs): + method = getattr(self, 'start_'+tag, None) + if method: + for key, value in attrs.items(): + attrs[key] = str(value) # XXX Convert Unicode to 8-bit + method(attrs) + self.texts = [] + + def data(self, text): + text = str(text) # XXX Convert Unicode to 8-bit + self.texts.append(text) + + def endelement(self, tag): + method = getattr(self, 'end_'+tag, None) + if method: + method("".join(self.texts)) + + def start_cell(self, attrs): + self.y = int(attrs.get("row")) + self.x = int(attrs.get("col")) + + def start_value(self, attrs): + self.fmt = attrs.get('format') + self.alignment = xml2align.get(attrs.get('align')) + + start_formula = start_value + + def end_int(self, text): + try: + self.value = int(text) + except: + self.value = None + + def end_long(self, text): + try: + self.value = int(text) + except: + self.value = None + + def end_double(self, text): + try: + self.value = float(text) + except: + self.value = None + + def end_complex(self, text): + try: + self.value = complex(text) + except: + self.value = None + + def end_string(self, text): + try: + self.value = text + except: + self.value = None + + def end_value(self, text): + if isinstance(self.value, BaseCell): + self.cell = self.value + elif isinstance(self.value, str): + self.cell = StringCell(self.value, + self.fmt or "%s", + self.alignment or LEFT) + else: + self.cell = NumericCell(self.value, + self.fmt or "%s", + self.alignment or RIGHT) + + def end_formula(self, text): + self.cell = FormulaCell(text, + self.fmt or "%s", + self.alignment or RIGHT) + + def end_cell(self, text): + self.sheet.setcell(self.x, self.y, self.cell) + +class BaseCell: + __init__ = None # Must provide + """Abstract base class for sheet cells. + + Subclasses may but needn't provide the following APIs: + + cell.reset() -- prepare for recalculation + cell.recalc(ns) -> value -- recalculate formula + cell.format() -> (value, alignment) -- return formatted value + cell.xml() -> string -- return XML + """ + +class NumericCell(BaseCell): + + def __init__(self, value, fmt="%s", alignment=RIGHT): + assert isinstance(value, (int, int, float, complex)) + assert alignment in (LEFT, CENTER, RIGHT) + self.value = value + self.fmt = fmt + self.alignment = alignment + + def recalc(self, ns): + return self.value + + def format(self): + try: + text = self.fmt % self.value + except: + text = str(self.value) + return text, self.alignment + + def xml(self): + method = getattr(self, '_xml_' + type(self.value).__name__) + return '%s' % ( + align2xml[self.alignment], + self.fmt, + method()) + + def _xml_int(self): + if -2**31 <= self.value < 2**31: + return '%s' % self.value + else: + return self._xml_long() + + def _xml_long(self): + return '%s' % self.value + + def _xml_float(self): + return '%s' % repr(self.value) + + def _xml_complex(self): + return '%s' % repr(self.value) + +class StringCell(BaseCell): + + def __init__(self, text, fmt="%s", alignment=LEFT): + assert isinstance(text, (str, str)) + assert alignment in (LEFT, CENTER, RIGHT) + self.text = text + self.fmt = fmt + self.alignment = alignment + + def recalc(self, ns): + return self.text + + def format(self): + return self.text, self.alignment + + def xml(self): + s = '%s' + return s % ( + align2xml[self.alignment], + self.fmt, + html.escape(self.text)) + +class FormulaCell(BaseCell): + + def __init__(self, formula, fmt="%s", alignment=RIGHT): + assert alignment in (LEFT, CENTER, RIGHT) + self.formula = formula + self.translated = translate(self.formula) + self.fmt = fmt + self.alignment = alignment + self.reset() + + def reset(self): + self.value = None + + def recalc(self, ns): + if self.value is None: + try: + # A hack to evaluate expressions using true division + self.value = eval(self.translated, ns) + except: + exc = sys.exc_info()[0] + if hasattr(exc, "__name__"): + self.value = exc.__name__ + else: + self.value = str(exc) + return self.value + + def format(self): + try: + text = self.fmt % self.value + except: + text = str(self.value) + return text, self.alignment + + def xml(self): + return '%s' % ( + align2xml[self.alignment], + self.fmt, + self.formula) + + def renumber(self, x1, y1, x2, y2, dx, dy): + out = [] + for part in re.split('(\w+)', self.formula): + m = re.match('^([A-Z]+)([1-9][0-9]*)$', part) + if m is not None: + sx, sy = m.groups() + x = colname2num(sx) + y = int(sy) + if x1 <= x <= x2 and y1 <= y <= y2: + part = cellname(x+dx, y+dy) + out.append(part) + return FormulaCell("".join(out), self.fmt, self.alignment) + +def translate(formula): + """Translate a formula containing fancy cell names to valid Python code. + + Examples: + B4 -> cell(2, 4) + B4:Z100 -> cells(2, 4, 26, 100) + """ + out = [] + for part in re.split(r"(\w+(?::\w+)?)", formula): + m = re.match(r"^([A-Z]+)([1-9][0-9]*)(?::([A-Z]+)([1-9][0-9]*))?$", part) + if m is None: + out.append(part) + else: + x1, y1, x2, y2 = m.groups() + x1 = colname2num(x1) + if x2 is None: + s = "cell(%s, %s)" % (x1, y1) + else: + x2 = colname2num(x2) + s = "cells(%s, %s, %s, %s)" % (x1, y1, x2, y2) + out.append(s) + return "".join(out) + +def cellname(x, y): + "Translate a cell coordinate to a fancy cell name (e.g. (1, 1)->'A1')." + assert x > 0 # Column 0 has an empty name, so can't use that + return colnum2name(x) + str(y) + +def colname2num(s): + "Translate a column name to number (e.g. 'A'->1, 'Z'->26, 'AA'->27)." + s = s.upper() + n = 0 + for c in s: + assert 'A' <= c <= 'Z' + n = n*26 + ord(c) - ord('A') + 1 + return n + +def colnum2name(n): + "Translate a column number to name (e.g. 1->'A', etc.)." + assert n > 0 + s = "" + while n: + n, m = divmod(n-1, 26) + s = chr(m+ord('A')) + s + return s + +import tkinter as Tk + +class SheetGUI: + + """Beginnings of a GUI for a spreadsheet. + + TO DO: + - clear multiple cells + - Insert, clear, remove rows or columns + - Show new contents while typing + - Scroll bars + - Grow grid when window is grown + - Proper menus + - Undo, redo + - Cut, copy and paste + - Formatting and alignment + """ + + def __init__(self, filename="sheet1.xml", rows=10, columns=5): + """Constructor. + + Load the sheet from the filename argument. + Set up the Tk widget tree. + """ + # Create and load the sheet + self.filename = filename + self.sheet = Sheet() + if os.path.isfile(filename): + self.sheet.load(filename) + # Calculate the needed grid size + maxx, maxy = self.sheet.getsize() + rows = max(rows, maxy) + columns = max(columns, maxx) + # Create the widgets + self.root = Tk.Tk() + self.root.wm_title("Spreadsheet: %s" % self.filename) + self.beacon = Tk.Label(self.root, text="A1", + font=('helvetica', 16, 'bold')) + self.entry = Tk.Entry(self.root) + self.savebutton = Tk.Button(self.root, text="Save", + command=self.save) + self.cellgrid = Tk.Frame(self.root) + # Configure the widget lay-out + self.cellgrid.pack(side="bottom", expand=1, fill="both") + self.beacon.pack(side="left") + self.savebutton.pack(side="right") + self.entry.pack(side="left", expand=1, fill="x") + # Bind some events + self.entry.bind("", self.return_event) + self.entry.bind("", self.shift_return_event) + self.entry.bind("", self.tab_event) + self.entry.bind("", self.shift_tab_event) + self.entry.bind("", self.delete_event) + self.entry.bind("", self.escape_event) + # Now create the cell grid + self.makegrid(rows, columns) + # Select the top-left cell + self.currentxy = None + self.cornerxy = None + self.setcurrent(1, 1) + # Copy the sheet cells to the GUI cells + self.sync() + + def delete_event(self, event): + if self.cornerxy != self.currentxy and self.cornerxy is not None: + self.sheet.clearcells(*(self.currentxy + self.cornerxy)) + else: + self.sheet.clearcell(*self.currentxy) + self.sync() + self.entry.delete(0, 'end') + return "break" + + def escape_event(self, event): + x, y = self.currentxy + self.load_entry(x, y) + + def load_entry(self, x, y): + cell = self.sheet.getcell(x, y) + if cell is None: + text = "" + elif isinstance(cell, FormulaCell): + text = '=' + cell.formula + else: + text, alignment = cell.format() + self.entry.delete(0, 'end') + self.entry.insert(0, text) + self.entry.selection_range(0, 'end') + + def makegrid(self, rows, columns): + """Helper to create the grid of GUI cells. + + The edge (x==0 or y==0) is filled with labels; the rest is real cells. + """ + self.rows = rows + self.columns = columns + self.gridcells = {} + # Create the top left corner cell (which selects all) + cell = Tk.Label(self.cellgrid, relief='raised') + cell.grid_configure(column=0, row=0, sticky='NSWE') + cell.bind("", self.selectall) + # Create the top row of labels, and confiure the grid columns + for x in range(1, columns+1): + self.cellgrid.grid_columnconfigure(x, minsize=64) + cell = Tk.Label(self.cellgrid, text=colnum2name(x), relief='raised') + cell.grid_configure(column=x, row=0, sticky='WE') + self.gridcells[x, 0] = cell + cell.__x = x + cell.__y = 0 + cell.bind("", self.selectcolumn) + cell.bind("", self.extendcolumn) + cell.bind("", self.extendcolumn) + cell.bind("", self.extendcolumn) + # Create the leftmost column of labels + for y in range(1, rows+1): + cell = Tk.Label(self.cellgrid, text=str(y), relief='raised') + cell.grid_configure(column=0, row=y, sticky='WE') + self.gridcells[0, y] = cell + cell.__x = 0 + cell.__y = y + cell.bind("", self.selectrow) + cell.bind("", self.extendrow) + cell.bind("", self.extendrow) + cell.bind("", self.extendrow) + # Create the real cells + for x in range(1, columns+1): + for y in range(1, rows+1): + cell = Tk.Label(self.cellgrid, relief='sunken', + bg='white', fg='black') + cell.grid_configure(column=x, row=y, sticky='NSWE') + self.gridcells[x, y] = cell + cell.__x = x + cell.__y = y + # Bind mouse events + cell.bind("", self.press) + cell.bind("", self.motion) + cell.bind("", self.release) + cell.bind("", self.release) + + def selectall(self, event): + self.setcurrent(1, 1) + self.setcorner(sys.maxint, sys.maxint) + + def selectcolumn(self, event): + x, y = self.whichxy(event) + self.setcurrent(x, 1) + self.setcorner(x, sys.maxint) + + def extendcolumn(self, event): + x, y = self.whichxy(event) + if x > 0: + self.setcurrent(self.currentxy[0], 1) + self.setcorner(x, sys.maxint) + + def selectrow(self, event): + x, y = self.whichxy(event) + self.setcurrent(1, y) + self.setcorner(sys.maxint, y) + + def extendrow(self, event): + x, y = self.whichxy(event) + if y > 0: + self.setcurrent(1, self.currentxy[1]) + self.setcorner(sys.maxint, y) + + def press(self, event): + x, y = self.whichxy(event) + if x > 0 and y > 0: + self.setcurrent(x, y) + + def motion(self, event): + x, y = self.whichxy(event) + if x > 0 and y > 0: + self.setcorner(x, y) + + release = motion + + def whichxy(self, event): + w = self.cellgrid.winfo_containing(event.x_root, event.y_root) + if w is not None and isinstance(w, Tk.Label): + try: + return w.__x, w.__y + except AttributeError: + pass + return 0, 0 + + def save(self): + self.sheet.save(self.filename) + + def setcurrent(self, x, y): + "Make (x, y) the current cell." + if self.currentxy is not None: + self.change_cell() + self.clearfocus() + self.beacon['text'] = cellname(x, y) + self.load_entry(x, y) + self.entry.focus_set() + self.currentxy = x, y + self.cornerxy = None + gridcell = self.gridcells.get(self.currentxy) + if gridcell is not None: + gridcell['bg'] = 'yellow' + + def setcorner(self, x, y): + if self.currentxy is None or self.currentxy == (x, y): + self.setcurrent(x, y) + return + self.clearfocus() + self.cornerxy = x, y + x1, y1 = self.currentxy + x2, y2 = self.cornerxy or self.currentxy + if x1 > x2: + x1, x2 = x2, x1 + if y1 > y2: + y1, y2 = y2, y1 + for (x, y), cell in self.gridcells.items(): + if x1 <= x <= x2 and y1 <= y <= y2: + cell['bg'] = 'lightBlue' + gridcell = self.gridcells.get(self.currentxy) + if gridcell is not None: + gridcell['bg'] = 'yellow' + self.setbeacon(x1, y1, x2, y2) + + def setbeacon(self, x1, y1, x2, y2): + if x1 == y1 == 1 and x2 == y2 == sys.maxint: + name = ":" + elif (x1, x2) == (1, sys.maxint): + if y1 == y2: + name = "%d" % y1 + else: + name = "%d:%d" % (y1, y2) + elif (y1, y2) == (1, sys.maxint): + if x1 == x2: + name = "%s" % colnum2name(x1) + else: + name = "%s:%s" % (colnum2name(x1), colnum2name(x2)) + else: + name1 = cellname(*self.currentxy) + name2 = cellname(*self.cornerxy) + name = "%s:%s" % (name1, name2) + self.beacon['text'] = name + + + def clearfocus(self): + if self.currentxy is not None: + x1, y1 = self.currentxy + x2, y2 = self.cornerxy or self.currentxy + if x1 > x2: + x1, x2 = x2, x1 + if y1 > y2: + y1, y2 = y2, y1 + for (x, y), cell in self.gridcells.items(): + if x1 <= x <= x2 and y1 <= y <= y2: + cell['bg'] = 'white' + + def return_event(self, event): + "Callback for the Return key." + self.change_cell() + x, y = self.currentxy + self.setcurrent(x, y+1) + return "break" + + def shift_return_event(self, event): + "Callback for the Return key with Shift modifier." + self.change_cell() + x, y = self.currentxy + self.setcurrent(x, max(1, y-1)) + return "break" + + def tab_event(self, event): + "Callback for the Tab key." + self.change_cell() + x, y = self.currentxy + self.setcurrent(x+1, y) + return "break" + + def shift_tab_event(self, event): + "Callback for the Tab key with Shift modifier." + self.change_cell() + x, y = self.currentxy + self.setcurrent(max(1, x-1), y) + return "break" + + def change_cell(self): + "Set the current cell from the entry widget." + x, y = self.currentxy + text = self.entry.get() + cell = None + if text.startswith('='): + cell = FormulaCell(text[1:]) + else: + for cls in int, int, float, complex: + try: + value = cls(text) + except: + continue + else: + cell = NumericCell(value) + break + if cell is None and text: + cell = StringCell(text) + if cell is None: + self.sheet.clearcell(x, y) + else: + self.sheet.setcell(x, y, cell) + self.sync() + + def sync(self): + "Fill the GUI cells from the sheet cells." + self.sheet.recalc() + for (x, y), gridcell in self.gridcells.items(): + if x == 0 or y == 0: + continue + cell = self.sheet.getcell(x, y) + if cell is None: + gridcell['text'] = "" + else: + if hasattr(cell, 'format'): + text, alignment = cell.format() + else: + text, alignment = str(cell), LEFT + gridcell['text'] = text + gridcell['anchor'] = align2anchor[alignment] + + +def test_basic(): + "Basic non-gui self-test." + import os + a = Sheet() + for x in range(1, 11): + for y in range(1, 11): + if x == 1: + cell = NumericCell(y) + elif y == 1: + cell = NumericCell(x) + else: + c1 = cellname(x, 1) + c2 = cellname(1, y) + formula = "%s*%s" % (c1, c2) + cell = FormulaCell(formula) + a.setcell(x, y, cell) +## if os.path.isfile("sheet1.xml"): +## print "Loading from sheet1.xml" +## a.load("sheet1.xml") + a.display() + a.save("sheet1.xml") + +def test_gui(): + "GUI test." + if sys.argv[1:]: + filename = sys.argv[1] + else: + filename = "sheet1.xml" + g = SheetGUI(filename) + g.root.mainloop() + +if __name__ == '__main__': + #test_basic() + test_gui() diff --git a/Tools/test2to3/README b/Tools/test2to3/README new file mode 100644 index 0000000..9365593 --- /dev/null +++ b/Tools/test2to3/README @@ -0,0 +1,3 @@ +This project demonstrates how a distutils package +can support Python 2.x and Python 3.x from a single +source, using lib2to3. \ No newline at end of file diff --git a/Tools/test2to3/maintest.py b/Tools/test2to3/maintest.py new file mode 100644 index 0000000..036dd4f --- /dev/null +++ b/Tools/test2to3/maintest.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python3 + +# The above line should get replaced with the path to the Python +# interpreter; the block below should get 2to3-converted. + +try: + from test2to3.hello import hello +except ImportError, e: + print "Import failed", e +hello() diff --git a/Tools/test2to3/setup.py b/Tools/test2to3/setup.py new file mode 100644 index 0000000..a0f9024 --- /dev/null +++ b/Tools/test2to3/setup.py @@ -0,0 +1,26 @@ +# -*- coding: iso-8859-1 -*- +from distutils.core import setup + +try: + from distutils.command.build_py import build_py_2to3 as build_py +except ImportError: + from distutils.command.build_py import build_py + +try: + from distutils.command.build_scripts import build_scripts_2to3 as build_scripts +except ImportError: + from distutils.command.build_scripts import build_scripts + +setup( + name = "test2to3", + version = "1.0", + description = "2to3 distutils test package", + author = "Martin v. Löwis", + author_email = "python-dev@python.org", + license = "PSF license", + packages = ["test2to3"], + scripts = ["maintest.py"], + cmdclass = {'build_py': build_py, + 'build_scripts': build_scripts, + } +) diff --git a/Tools/test2to3/test/runtests.py b/Tools/test2to3/test/runtests.py new file mode 100644 index 0000000..1730f0d --- /dev/null +++ b/Tools/test2to3/test/runtests.py @@ -0,0 +1,19 @@ +# Fictitious test runner for the project + +import sys, os + +if sys.version_info > (3,): + # copy test suite over to "build/lib" and convert it + from distutils.util import copydir_run_2to3 + testroot = os.path.dirname(__file__) + newroot = os.path.join(testroot, '..', 'build/lib/test') + copydir_run_2to3(testroot, newroot) + # in the following imports, pick up the converted modules + sys.path[0] = newroot + +# run the tests here... + +from test_foo import FooTest + +import unittest +unittest.main() diff --git a/Tools/test2to3/test/test_foo.py b/Tools/test2to3/test/test_foo.py new file mode 100644 index 0000000..ec8f26a --- /dev/null +++ b/Tools/test2to3/test/test_foo.py @@ -0,0 +1,8 @@ +import sys +import unittest + +class FooTest(unittest.TestCase): + def test_foo(self): + # use 2.6 syntax to demonstrate conversion + print 'In test_foo, using Python %s...' % (sys.version_info,) + self.assertTrue(False) diff --git a/Tools/test2to3/test2to3/__init__.py b/Tools/test2to3/test2to3/__init__.py new file mode 100644 index 0000000..1bb8bf6 --- /dev/null +++ b/Tools/test2to3/test2to3/__init__.py @@ -0,0 +1 @@ +# empty diff --git a/Tools/test2to3/test2to3/hello.py b/Tools/test2to3/test2to3/hello.py new file mode 100644 index 0000000..f52926b --- /dev/null +++ b/Tools/test2to3/test2to3/hello.py @@ -0,0 +1,5 @@ +def hello(): + try: + print "Hello, world" + except IOError, e: + print e.errno -- cgit v0.12