summaryrefslogtreecommitdiffstats
path: root/Demo/tkinter/guido
diff options
context:
space:
mode:
Diffstat (limited to 'Demo/tkinter/guido')
-rw-r--r--Demo/tkinter/guido/attr_dialog.py460
-rw-r--r--Demo/tkinter/guido/brownian.py50
-rw-r--r--Demo/tkinter/guido/brownian2.py55
-rw-r--r--Demo/tkinter/guido/canvasevents.py264
-rwxr-xr-xDemo/tkinter/guido/dialog.py108
-rwxr-xr-xDemo/tkinter/guido/electrons.py91
-rw-r--r--Demo/tkinter/guido/hanoi.py154
-rw-r--r--Demo/tkinter/guido/hello.py17
-rw-r--r--Demo/tkinter/guido/imagedraw.py23
-rw-r--r--Demo/tkinter/guido/imageview.py12
-rwxr-xr-xDemo/tkinter/guido/kill.py96
-rw-r--r--Demo/tkinter/guido/listtree.py34
-rw-r--r--Demo/tkinter/guido/manpage.py215
-rwxr-xr-xDemo/tkinter/guido/mbox.py286
-rwxr-xr-xDemo/tkinter/guido/mimeviewer.py159
-rw-r--r--Demo/tkinter/guido/newmenubardemo.py47
-rw-r--r--Demo/tkinter/guido/optionmenu.py27
-rw-r--r--Demo/tkinter/guido/paint.py60
-rwxr-xr-xDemo/tkinter/guido/rmt.py159
-rw-r--r--Demo/tkinter/guido/shell_window.py146
-rwxr-xr-xDemo/tkinter/guido/solitaire.py626
-rw-r--r--Demo/tkinter/guido/sortvisu.py636
-rw-r--r--Demo/tkinter/guido/ss1.py842
-rwxr-xr-xDemo/tkinter/guido/svkill.py124
-rw-r--r--Demo/tkinter/guido/switch.py55
-rwxr-xr-xDemo/tkinter/guido/tkman.py267
-rw-r--r--Demo/tkinter/guido/wish.py34
27 files changed, 0 insertions, 5047 deletions
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('<Return>', 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('<Any-Double-1>', 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('<Double-1>', 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('<B1-Motion>', self.motionhandler)
- self.group.bind('<ButtonRelease-1>', 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 <Return>, if there's a default,
- # set a grab, and claim the focus too.
-
- if default >= 0:
- w.bind('<Return>',
- 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('<Button-1>', 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('<Motion>', self.do_motion)
- self.frame.list.bind('<Leave>', 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('<ButtonRelease-3>', folder_unpost)
-
- folderbox['yscrollcommand'] = (folderbar, 'set')
- folderbar['command'] = (folderbox, 'yview')
- folderbox.bind('<Double-1>', 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('<ButtonRelease-3>', scan_unpost)
-
- scanbox['yscrollcommand'] = (scanbar, 'set')
- scanbar['command'] = (scanbox, 'yview')
- scanbox.bind('<Double-1>', 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 <davem@magnet.com>
-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>", motion)
- drawing_area.bind("<ButtonPress-1>", b1down)
- drawing_area.bind("<ButtonRelease-1>", 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('<Double-1>', double1)
-
-def triple1(e):
- x = e.x
- y = e.y
- t.setvar('tk_priv(selectMode)', 'line')
- t.tk_textSelectTo(At(x, y))
-t.bind('<Triple-1>', triple1)
-
-def returnkey(e):
- t.insert(AtInsert(), '\n')
- invoke()
-t.bind('<Return>', returnkey)
-
-def controlv(e):
- t.insert(AtInsert(), t.selection_get())
- t.yview_pickplace(AtInsert())
- if t.index(AtInsert())[-2:] == '.0':
- invoke()
-t.bind('<Control-v>', 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>', backspace)
-t.bind('<Control-h>', backspace)
-t.bind('<Delete>', 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('<Return>', self.inputhandler)
- self.bind('<Control-c>', self.sigint)
- self.bind('<Control-t>', self.sigterm)
- self.bind('<Control-k>', self.sigkill)
- self.bind('<Control-d>', 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('<Double-1>', self.doubleclickhandler)
- self.group.bind('<B1-Motion>', self.motionhandler)
- self.group.bind('<ButtonRelease-1>', 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, '<Button-1>', self.mouse_down)
- self.canvas.tag_bind(self.item_id, '<Button1-Motion>', self.mouse_move)
- self.canvas.tag_bind(self.item_id, '<ButtonRelease-1>', 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 = ['<spreadsheet>']
- for (x, y), cell in self.cells.items():
- if hasattr(cell, 'xml'):
- cellxml = cell.xml()
- else:
- cellxml = '<value>%s</value>' % html.escape(cell)
- out.append('<cell row="%s" col="%s">\n %s\n</cell>' %
- (y, x, cellxml))
- out.append('</spreadsheet>')
- 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 '<value align="%s" format="%s">%s</value>' % (
- align2xml[self.alignment],
- self.fmt,
- method())
-
- def _xml_int(self):
- if -2**31 <= self.value < 2**31:
- return '<int>%s</int>' % self.value
- else:
- return self._xml_long()
-
- def _xml_long(self):
- return '<long>%s</long>' % self.value
-
- def _xml_float(self):
- return '<double>%s</double>' % repr(self.value)
-
- def _xml_complex(self):
- return '<complex>%s</double>' % 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 = '<value align="%s" format="%s"><string>%s</string></value>'
- 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 '<formula align="%s" format="%s">%s</formula>' % (
- 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("<Return>", self.return_event)
- self.entry.bind("<Shift-Return>", self.shift_return_event)
- self.entry.bind("<Tab>", self.tab_event)
- self.entry.bind("<Shift-Tab>", self.shift_tab_event)
- self.entry.bind("<Delete>", self.delete_event)
- self.entry.bind("<Escape>", 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("<ButtonPress-1>", 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("<ButtonPress-1>", self.selectcolumn)
- cell.bind("<B1-Motion>", self.extendcolumn)
- cell.bind("<ButtonRelease-1>", self.extendcolumn)
- cell.bind("<Shift-Button-1>", 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("<ButtonPress-1>", self.selectrow)
- cell.bind("<B1-Motion>", self.extendrow)
- cell.bind("<ButtonRelease-1>", self.extendrow)
- cell.bind("<Shift-Button-1>", 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("<ButtonPress-1>", self.press)
- cell.bind("<B1-Motion>", self.motion)
- cell.bind("<ButtonRelease-1>", self.release)
- cell.bind("<Shift-Button-1>", 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('<Motion>', self.do_motion)
- self.frame.list.bind('<Leave>', 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('<Return>', self.entry_cb)
- self.search.bind('<Return>', self.search_cb)
- self.listbox.bind('<Double-1>', self.listbox_cb)
-
- self.entry.bind('<Tab>', self.entry_tab)
- self.search.bind('<Tab>', self.search_tab)
- self.text.bind('<Tab>', 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 = ''