summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xDemo/tkinter/guido/MimeViewer.py143
-rwxr-xr-xDemo/tkinter/guido/dialog.py119
-rwxr-xr-xDemo/tkinter/guido/mbox.py288
-rwxr-xr-xDemo/tkinter/guido/rmt.py152
-rwxr-xr-xDemo/tkinter/guido/tst.py81
-rwxr-xr-xDemo/tkinter/guido/wish.py26
-rw-r--r--Lib/lib-tk/Canvas.py115
-rw-r--r--Lib/lib-tk/ScrolledText.py35
-rw-r--r--Lib/lib-tk/Tkinter.py874
-rwxr-xr-xLib/tkinter/Canvas.py115
-rwxr-xr-xLib/tkinter/ScrolledText.py35
-rwxr-xr-xLib/tkinter/Tkinter.py874
-rw-r--r--Modules/_tkinter.c1056
13 files changed, 3913 insertions, 0 deletions
diff --git a/Demo/tkinter/guido/MimeViewer.py b/Demo/tkinter/guido/MimeViewer.py
new file mode 100755
index 0000000..5bf194a
--- /dev/null
+++ b/Demo/tkinter/guido/MimeViewer.py
@@ -0,0 +1,143 @@
+#! /ufs/guido/bin/sgi/tkpython
+
+# View a single MIME multipart message.
+# Display each part as a box.
+
+import string
+from types import *
+from Tkinter import *
+from ScrolledText import ScrolledText
+
+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 = msg.getheadertext(
+ lambda x: x != 'received' and x[:5] != 'x400-')
+ 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.getbody()
+ if type(body) == StringType:
+ 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 = string.find(str, '\n', i)
+ if i < 0: break
+ n = n+1
+ i = i+1
+ return n
+
+def main():
+ import sys
+ import getopt
+ import mhlib
+ 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 = string.atoi(arg)
+
+ mh = mhlib.MH()
+ f = mh.openfolder(folder)
+ if not message:
+ message = f.getcurrent()
+ m = f.openmessage(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/dialog.py b/Demo/tkinter/guido/dialog.py
new file mode 100755
index 0000000..31f5340
--- /dev/null
+++ b/Demo/tkinter/guido/dialog.py
@@ -0,0 +1,119 @@
+#! /ufs/guido/bin/sgi/tkpython
+
+# 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 *
+
+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.tk.call('global', 'button')
+ w.title(title)
+ w.iconname('Dialog')
+
+ top = Frame(w, {'relief': 'raised', 'bd': 1,
+ Pack: {'side': 'top', 'fill': 'both'}})
+ bot = Frame(w, {'relief': 'raised', 'bd': 1,
+ Pack: {'side': 'bottom', 'fill': 'both'}})
+
+ # 2. Fill the top part with the bitmap and message.
+
+ msg = Message(top,
+ {'width': '3i',
+ 'text': text,
+ 'font': '-Adobe-Times-Medium-R-Normal-*-180-*',
+ Pack: {'side': 'right', 'expand': 1,
+ 'fill': 'both',
+ 'padx': '3m', 'pady': '3m'}})
+ if bitmap:
+ bm = Label(top, {'bitmap': bitmap,
+ Pack: {'side': 'left',
+ 'padx': '3m', 'pady': '3m'}})
+
+ # 3. Create a row of buttons at the bottom of the dialog.
+
+ buttons = []
+ i = 0
+ for but in args:
+ b = Button(bot, {'text': but,
+ 'command': ('set', 'button', i)})
+ buttons.append(b)
+ if i == default:
+ bd = Frame(bot, {'relief': 'sunken', 'bd': 1,
+ Pack: {'side': 'left', 'expand': 1,
+ 'padx': '3m', 'pady': '2m'}})
+ w.tk.call('raise', b)
+ 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',
+ 'ipady': '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 b=buttons[default], i=default:
+ (b.cmd('flash'),
+ b.tk.call('set', 'button', i)))
+
+ oldFocus = w.tk.call('focus')
+ w.tk.call('grab', 'set', w)
+ w.tk.call('focus', w)
+
+ # 5. Wait for the user to respond, then restore the focus
+ # and return the index of the selected button.
+
+ w.tk.call('tkwait', 'variable', 'button')
+ w.tk.call('destroy', w)
+ w.tk.call('focus', oldFocus)
+ return w.tk.call('set', 'button')
+
+# 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': 'exit',
+ Pack: {'fill' : 'both'}})
+ mainWidget.tk.mainloop()
+
+if __name__ == '__main__':
+ test()
diff --git a/Demo/tkinter/guido/mbox.py b/Demo/tkinter/guido/mbox.py
new file mode 100755
index 0000000..a4e86da
--- /dev/null
+++ b/Demo/tkinter/guido/mbox.py
@@ -0,0 +1,288 @@
+#! /ufs/guido/bin/sgi/tkpython
+
+# Scan MH folder, display results in window
+
+import os
+import sys
+import regex
+import getopt
+import string
+import mhlib
+
+from Tkinter import *
+
+from dialog import dialog
+
+mailbox = 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, msg:
+ print msg
+ sys.exit(2)
+ for arg in args:
+ if arg[:1] == '+':
+ folder = arg[1:]
+ else:
+ seq = arg
+
+ # Initialize MH
+
+ mh = mhlib.MH()
+ mhf = mh.openfolder(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)
+ 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 = regex.compile('^ *\([0-9]+\)')
+
+def open_folder(*e):
+ 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.openfolder(folder)
+ rescan()
+
+def open_message(*e):
+ 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)
+ if scanparser.match(line) >= 0:
+ num = string.atoi(scanparser.group(1))
+ m = mhf.openmessage(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():
+ 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)
+ if scanparser.match(line) >= 0:
+ todo.append(string.atoi(scanparser.group(1)))
+ mhf.removemessages(todo)
+ rescan()
+ fixfocus(min(todo), itop)
+
+lastrefile = ''
+tofolder = None
+def refile_message():
+ 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)
+ if scanparser.match(line) >= 0:
+ todo.append(string.atoi(scanparser.group(1)))
+ print 'refile', todo, tofolder
+ if lastrefile != refileto or not tofolder:
+ print 'new folder'
+ lastrefile = refileto
+ tofolder = None
+ tofolder = mh.openfolder(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(`i`)
+ if scanparser.match(line) >= 0:
+ num = string.atoi(scanparser.group(1))
+ if num >= near:
+ break
+ else:
+ i = 'end'
+ scanbox.select_from(i)
+ print 'yview', `itop`
+ scanbox.yview(itop)
+
+def setfolders():
+ folderbox.delete(0, 'end')
+ for fn in mh.listallfolders():
+ 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 map(
+ lambda line: line[:-1],
+ os.popen('scan +%s %s' % (folder, sequence), 'r').readlines())
+
+main()
diff --git a/Demo/tkinter/guido/rmt.py b/Demo/tkinter/guido/rmt.py
new file mode 100755
index 0000000..2ac2408
--- /dev/null
+++ b/Demo/tkinter/guido/rmt.py
@@ -0,0 +1,152 @@
+#! /ufs/guido/bin/sgi/tkpython
+
+# 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.
+
+from Tkinter import *
+
+# 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', 'bd': 2,
+ Pack: {'side': 'top', 'fill': 'x'}})
+f = Frame(root)
+f.pack({'expand': 1, 'fill': 'both'})
+s = Scrollbar(f, {'relief': 'flat',
+ Pack: {'side': 'right', 'fill': 'y'}})
+t = Text(f, {'relief': 'raised', 'bd': 2, 'yscrollcommand': (s, 'set'),
+ 'setgrid': 1,
+ Pack: {'side': 'left', 'fill': 'both', 'expand': 1}})
+
+t.tag_config('bold', {'font': '-Adobe-Courier-Bold-R-Normal-*-120-*'})
+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,
+ Pack: {'side': 'left'}})
+file_m = Menu(file)
+file['menu'] = file_m
+file_m_apps = Menu(file_m)
+file_m.add('cascade', {'label': 'Select Application', 'underline': 0,
+ 'menu': file_m_apps})
+file_m.add('command', {'label': 'Quit', 'underline': 0, 'command': '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
+ tk.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
+ tk.setvar('tk_priv(selectMode)', 'word')
+ tk.call('tk_textSelectTo', t, At(x, y))
+t.bind('<Double-1>', double1)
+
+def triple1(e):
+ x = e.x
+ y = e.y
+ tk.setvar('tk_priv(selectMode)', 'line')
+ tk.call('tk_textSelectTo', t, At(x, y))
+t.bind('<Triple-1>', triple1)
+
+def returnkey(e):
+ t.insert('insert', '\n')
+ invoke()
+t.bind('<Return>', returnkey)
+
+def controlv(e):
+ t.insert('insert', tk.call('selection', 'get'))
+ t.yview_pickplace('insert')
+ if t.index('insert')[-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', 'insert')
+ t.yview_pickplace('insert')
+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', 'insert')
+ if tk.getboolean(tk.call('info', 'complete', cmd)):
+ if app == tk.call('winfo', 'name', '.'):
+ msg = tk.call('eval', cmd)
+ else:
+ msg = tk.call('send', app, cmd)
+ if msg:
+ t.insert('insert', msg + '\n')
+ prompt()
+ t.yview_pickplace('insert')
+
+def prompt():
+ t.insert('insert', 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')
+
+newApp_tcl = `id(newApp)`
+tk.createcommand(newApp_tcl, newApp)
+
+def fillAppsMenu():
+ file_m_apps.add('command')
+ file_m_apps.delete(0, 'last')
+ names = tk.splitlist(tk.call('winfo', 'interps'))
+ names = map(None, names) # convert tuple to list
+ names.sort()
+ for name in names:
+ file_m_apps.add('command', {'label': name,
+ 'command': (newApp_tcl, name)})
+
+file_m_apps['postcommand'] = fillAppsMenu
+mBar.tk_menuBar(file)
+
+# 7. Miscellaneous initialization.
+
+app = tk.call('winfo', 'name', '.')
+prompt()
+tk.call('focus', t)
+
+root.mainloop()
diff --git a/Demo/tkinter/guido/tst.py b/Demo/tkinter/guido/tst.py
new file mode 100755
index 0000000..ea573d2
--- /dev/null
+++ b/Demo/tkinter/guido/tst.py
@@ -0,0 +1,81 @@
+# tst.py
+from Tkinter import *
+import sys
+
+def do_hello():
+ print 'Hello world!'
+
+class Quit(Button):
+ def action(self):
+ self.quit()
+ def __init__(self, master=None, cnf={}):
+ Button.__init__(self, master,
+ {'text': 'Quit',
+ 'command': self.action})
+ Button.config(self, cnf)
+
+class Stuff(Canvas):
+ def enter(self, e):
+ print 'Enter'
+ self.itemconfig('current', {'fill': 'red'})
+ def leave(self, e):
+ print 'Leave'
+ self.itemconfig('current', {'fill': 'blue'})
+ def __init__(self, master=None, cnf={}):
+ Canvas.__init__(self, master,
+ {'width': 100, 'height': 100})
+ Canvas.config(self, cnf)
+ self.create_rectangle(30, 30, 70, 70,
+ {'fill': 'red', 'tags': 'box'})
+ Canvas.bind(self, 'box', '<Enter>', self.enter)
+ Canvas.bind(self, 'box', '<Leave>', self.leave)
+
+class Test(Frame):
+ text = 'Testing'
+ num = 1
+ def do_xy(self, e):
+ print (e.x, e.y)
+ def do_test(self):
+ if not self.num % 10:
+ self.text = 'Testing 1 ...'
+ self.text = self.text + ' ' + `self.num`
+ self.num = self.num + 1
+ self.testing['text'] = self.text
+ def do_err(self):
+ 1/0
+ def do_after(self):
+ self.testing.invoke()
+ self.after(10000, self.do_after)
+ def __init__(self, master=None):
+ Frame.__init__(self, master)
+ self['bd'] = 30
+ Pack.config(self)
+ self.bind('<Motion>', self.do_xy)
+ self.hello = Button(self, {'name': 'hello',
+ 'text': 'Hello',
+ 'command': do_hello,
+ Pack: {'fill': 'both'}})
+ self.testing = Button(self)
+ self.testing['text'] = self.text
+ self.testing['command'] = self.do_test
+ Pack.config(self.testing, {'fill': 'both'})
+ self.err = Button(self, {'text': 'Error',
+ 'command': self.do_err,
+ Pack: {'fill': 'both'}})
+ self.quit = Quit(self, {Pack: {'fill': 'both'}})
+ self.exit = Button(self,
+ {'text': 'Exit',
+ 'command': lambda: sys.exit(0),
+ Pack: {'fill': 'both'}})
+ self.stuff = Stuff(self, {Pack: {'padx': 2, 'pady': 2}})
+ self.do_after()
+
+test = Test()
+test.master.title('Tkinter Test')
+test.master.iconname('Test')
+test.master.maxsize(500, 500)
+test.testing.invoke()
+
+# Use the -i option and type ^C to get a prompt
+test.mainloop()
+
diff --git a/Demo/tkinter/guido/wish.py b/Demo/tkinter/guido/wish.py
new file mode 100755
index 0000000..16cacde
--- /dev/null
+++ b/Demo/tkinter/guido/wish.py
@@ -0,0 +1,26 @@
+# This is about all it requires to write a wish shell in Python!
+
+import tkinter
+
+tk = tkinter.create(':0', 'wish', 'Tk', 1)
+tk.call('update')
+
+cmd = ''
+
+while 1:
+ if cmd: prompt = ''
+ else: prompt = '% '
+ try:
+ line = raw_input(prompt)
+ except EOFError:
+ break
+ cmd = cmd + (line + '\n')
+ tk.record(line)
+ if tk.getboolean(tk.call('info', 'complete', cmd)):
+ try:
+ result = tk.call('eval', cmd)
+ except tkinter.TclError, msg:
+ print 'TclError:', msg
+ else:
+ if result: print result
+ cmd = ''
diff --git a/Lib/lib-tk/Canvas.py b/Lib/lib-tk/Canvas.py
new file mode 100644
index 0000000..4d21928
--- /dev/null
+++ b/Lib/lib-tk/Canvas.py
@@ -0,0 +1,115 @@
+# This module exports classes for the various canvas item types
+
+# vi:set tabsize=4:
+
+from Tkinter import Canvas, _isfunctype
+
+class CanvasItem:
+ def __init__(self, canvas, itemType, args = (), cnf={}):
+ self.canvas = canvas
+ self.id = canvas._create(itemType, args + (cnf,))
+ def __str__(self):
+ return str(self.id)
+ def __repr__(self):
+ return '<%s, id=%d>' % (self.__class__.__name__, self.id)
+ def __del__(self):
+ self.canvas.delete(self.id)
+ delete = __del__
+ def __getitem__(self, key):
+ v = self.canvas.tk.split(self.canvas.tk.call(self.canvas.pathName,
+ 'itemconfigure',
+ str(self.id),
+ '-' + key))
+ return v[4]
+ def __setitem__(self, key, value):
+ self.canvas._itemconfig(self.id, {key: value})
+ def keys(self):
+ if not hasattr(self, '_keys'):
+ self._keys = map(lambda x, tk=self.canvas.tk:
+ tk.splitlist(x)[0][1:],
+ self.canvas._splitlist(
+ self.canvas.cmd('itemconfigure', self.id)))
+ return self._keys
+ def has_key(self, key):
+ return key in self.keys()
+ def addtag(self, tag, option='withtag'):
+ self.canvas.addtag(tag, option, self.id)
+ def bbox(self):
+ x1, y1, x2, y2 = self.canvas.bbox(self.id)
+ return (x1, y1), (x2, y2)
+ def bind(self, sequence=None, command=None):
+ return self.canvas.bind(self.id, sequence, command)
+ def coords(self, pts = ()):
+ flat = ()
+ for x, y in pts: flat = flat + (x, y)
+ return apply(self.canvas.coords, (self.id,) + flat)
+ def dchars(self, first, last=None):
+ self.canvas.dchars(self.id, first, last)
+ def dtag(self, ttd):
+ self.canvas.dtag(self.id, ttd)
+ def focus(self):
+ self.canvas.focus(self.id)
+ def gettags(self):
+ return self.canvas.gettags(self.id)
+ def icursor(self):
+ self.canvas.icursor(self.id)
+ def index(self):
+ return self.canvas.index(self.id)
+ def insert(self, beforethis, string):
+ self.canvas.insert(self.id, beforethis, string)
+ def lower(self, belowthis=None):
+ self.canvas.lower(self.id, belowthis)
+ def move(self, xamount, yamount):
+ self.canvas.move(self.id, xamount, yamount)
+ def raise_(self, abovethis=None):
+ self.canvas.raise_(self.id, abovethis)
+ def scale(self, xorigin, yorigin, xscale, yscale):
+ self.canvas.scale(self.id, xorigin, yorigin, xscale, yscale)
+ def type(self):
+ return self.canvas.type(self.id)
+
+class Arc(CanvasItem):
+ def __init__(self, canvas, (x1, y1), (x2, y2), cnf={}):
+ CanvasItem.__init__(self, canvas, 'arc',
+ (str(x1), str(y1), str(x2), str(y2)), cnf)
+
+class Bitmap(CanvasItem):
+ def __init__(self, canvas, (x1, y1), cnf={}):
+ CanvasItem.__init__(self, canvas, 'bitmap', (str(x1), str(y1)), cnf)
+
+class Line(CanvasItem):
+ def __init__(self, canvas, pts, cnf={}):
+ pts = reduce(lambda a, b: a+b,
+ map(lambda pt: (str(pt[0]), str(pt[1])), pts))
+ CanvasItem.__init__(self, canvas, 'line', pts, cnf)
+
+class Oval(CanvasItem):
+ def __init__(self, canvas, (x1, y1), (x2, y2), cnf={}):
+ CanvasItem.__init__(self, canvas, 'oval',
+ (str(x1), str(y1), str(x2), str(y2)), cnf)
+
+class Polygon(CanvasItem):
+ def __init__(self, canvas, pts, cnf={}):
+ pts = reduce(lambda a, b: a+b,
+ map(lambda pt: (str(pt[0]), str(pt[1])), pts))
+ CanvasItem.__init__(self, canvas, 'polygon', pts, cnf)
+
+class Curve(Polygon):
+ def __init__(self, canvas, pts, cnf={}):
+ cnf['smooth'] = 'yes'
+ Polygon.__init__(self, canvas, pts, cnf)
+
+class Rectangle(CanvasItem):
+ def __init__(self, canvas, (x1, y1), (x2, y2), cnf={}):
+ CanvasItem.__init__(self, canvas, 'rectangle',
+ (str(x1), str(y1), str(x2), str(y2)), cnf)
+
+# XXX Can't use name "Text" since that is already taken by the Text widget...
+class String(CanvasItem):
+ def __init__(self, canvas, (x1, y1), cnf={}):
+ CanvasItem.__init__(self, canvas, 'text', (str(x1), str(y1)), cnf)
+
+class Window(CanvasItem):
+ def __init__(self, canvas, where, cnf={}):
+ CanvasItem.__init__(self, canvas, 'window',
+ (str(where[0]), str(where[1])), cnf)
diff --git a/Lib/lib-tk/ScrolledText.py b/Lib/lib-tk/ScrolledText.py
new file mode 100644
index 0000000..9effae0
--- /dev/null
+++ b/Lib/lib-tk/ScrolledText.py
@@ -0,0 +1,35 @@
+# A ScrolledText widget feels like a text widget but also has a
+# vertical scroll bar on its right. (Later, options may be added to
+# add a horizontal bar as well, to make the bars disappear
+# automatically when not needed, to move them to the other side of the
+# window, etc.)
+#
+# Configuration options are passed to the Text widget.
+# A Frame widget is inserted between the master and the text, to hold
+# the Scrollbar widget.
+# Most methods calls are passed to the Text widget; the pack command
+# is redirected to the Frame widget however.
+
+from Tkinter import *
+
+class ScrolledText(Pack, Place):
+ def __init__(self, master=None, cnf={}):
+ fcnf = {}
+ self.frame = Frame(master, {})
+ if cnf.has_key(Pack):
+ self.frame.pack(cnf[Pack])
+ del cnf[Pack]
+ self.vbar = Scrollbar(self.frame, {})
+ self.vbar.pack({'side': 'right', 'fill': 'y'})
+ cnf[Pack] = {'side': 'left', 'fill': 'both',
+ 'expand': 'yes'}
+ self.text = Text(self.frame, cnf)
+ self.text['yscrollcommand'] = (self.vbar, 'set')
+ self.vbar['command'] = (self.text, 'yview')
+ self.insert = self.text.insert
+ # XXX should do all Text methods...
+ self.pack = self.frame.pack
+ self.forget = self.frame.forget
+ self.tk = master.tk
+ def __str__(self):
+ return str(self.frame)
diff --git a/Lib/lib-tk/Tkinter.py b/Lib/lib-tk/Tkinter.py
new file mode 100644
index 0000000..e9e641c
--- /dev/null
+++ b/Lib/lib-tk/Tkinter.py
@@ -0,0 +1,874 @@
+# Tkinter.py -- Tk/Tcl widget wrappers
+import tkinter
+from tkinter import TclError
+
+class _Dummy:
+ def meth(self): return
+
+def _isfunctype(func):
+ return type(func) in (type(_Dummy.meth), type(_isfunctype))
+
+FunctionType = type(_isfunctype)
+ClassType = type(_Dummy)
+MethodType = type(_Dummy.meth)
+
+def tkerror(err):
+ pass
+
+class Event:
+ pass
+
+class Misc:
+ def tk_strictMotif(self, boolean=None):
+ self.tk.getboolean(self.tk.call(
+ 'set', 'tk_strictMotif', boolean))
+ def waitvar(self, name='VAR'):
+ self.tk.call('tkwait', 'variable', name)
+ def setvar(self, name='VAR', value='1'):
+ self.tk.setvar(name, value)
+ def focus(self):
+ self.tk.call('focus', self._w)
+ def focus_default(self):
+ self.tk.call('focus', 'default', self._w)
+ def focus_none(self):
+ self.tk.call('focus', 'none')
+ #XXX focus_get?
+ def after(self, ms, func=None, *args):
+ if not func:
+ self.tk.call('after', ms)
+ else:
+ name = self._register(func)
+ apply(self.tk.call, ('after', ms, name) + args)
+ #XXX grab_current
+ def grab_release(self):
+ self.tk.call('grab', 'release', self._w)
+ def grab_set(self):
+ self.tk.call('grab', 'set', self._w)
+ def grab_set_global(self):
+ self.tk.call('grab', 'set', '-global', self._w)
+ def grab_status(self):
+ self.tk.call('grab', 'status', self._w)
+ def lower(self, belowThis=None):
+ self.tk.call('lower', self._w, belowThis)
+ def selection_clear(self):
+ self.tk.call('selection', 'clear', self._w)
+ def selection_get(self, type=None):
+ self.tk.call('selection', 'get', type)
+ def selection_handle(self, func, type=None, format=None):
+ name = self._register(func)
+ self.tk.call('selection', 'handle',
+ self._w, name, type, format)
+ #XXX def selection_own(self):
+ # self.tk.call('selection', 'own', self._w)
+ def send(self, interp, cmd, *args): #XXX
+ return apply(self.tk.call, ('send', interp, cmd) + args)
+ def colormodel(self, value=None):
+ return self.tk.call('tk', 'colormodel', self._w, value)
+ def winfo_atom(self, name):
+ return self.tk.getint(self.tk.call('winfo', 'atom', name))
+ def winfo_atomname(self, id):
+ return self.tk.call('winfo', 'atomname', id)
+ def winfo_cells(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'cells', self._w))
+ #XXX winfo_children
+ def winfo_class(self):
+ return self.tk.call('winfo', 'class', self._w)
+ def winfo_containing(self, rootX, rootY):
+ return self.tk.call('winfo', 'containing', rootx, rootY)
+ def winfo_depth(self):
+ return self.tk.getint(self.tk.call('winfo', 'depth', self._w))
+ def winfo_exists(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'exists', self._w))
+ def winfo_fpixels(self, number):
+ return self.tk.getdouble(self.tk.call(
+ 'winfo', 'fpixels', self._w, number))
+ def winfo_geometry(self):
+ return self.tk.call('winfo', 'geometry', self._w)
+ def winfo_height(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'height', self._w))
+ def winfo_id(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'id', self._w))
+ def winfo_interps(self):
+ return self.tk.splitlist(
+ self.tk.call('winfo', 'interps'))
+ def winfo_ismapped(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'ismapped', self._w))
+ def winfo_name(self):
+ return self.tk.call('winfo', 'name', self._w)
+ def winfo_parent(self):
+ return self.tk.call('winfo', 'parent', self._w)
+ def winfo_pathname(self, id):
+ return self.tk.call('winfo', 'pathname', id)
+ def winfo_pixels(self, number):
+ return self.tk.getint(
+ self.tk.call('winfo', 'pixels', self._w, number))
+ def winfo_reqheight(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'reqheight', self._w))
+ def winfo_reqwidth(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'reqwidth', self._w))
+ def winfo_rgb(self, color):
+ return self._getints(
+ self.tk.call('winfo', 'rgb', self._w, color))
+ def winfo_rootx(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'rootx', self._w))
+ def winfo_rooty(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'rooty', self._w))
+ def winfo_screen(self):
+ return self.tk.call('winfo', 'screen', self._w)
+ def winfo_screencells(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'screencells', self._w))
+ def winfo_screendepth(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'screendepth', self._w))
+ def winfo_screenheight(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'screenheight', self._w))
+ def winfo_screenmmheight(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'screenmmheight', self._w))
+ def winfo_screenmmwidth(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'screenmmwidth', self._w))
+ def winfo_screenvisual(self):
+ return self.tk.call('winfo', 'screenvisual', self._w)
+ def winfo_screenwidth(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'screenwidth', self._w))
+ def winfo_toplevel(self):
+ return self.tk.call('winfo', 'toplevel', self._w)
+ def winfo_visual(self):
+ return self.tk.call('winfo', 'visual', self._w)
+ def winfo_vrootheight(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'vrootheight', self._w))
+ def winfo_vrootwidth(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'vrootwidth', self._w))
+ def winfo_vrootx(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'vrootx', self._w))
+ def winfo_vrooty(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'vrooty', self._w))
+ def winfo_width(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'width', self._w))
+ def winfo_x(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'x', self._w))
+ def winfo_y(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'y', self._w))
+ def update(self):
+ self.tk.call('update')
+ def update_idletasks(self):
+ self.tk.call('update', 'idletasks')
+ def bind(self, sequence, func, add=''):
+ global _substitute, _subst_prefix
+ if add: add = '+'
+ name = self._register(func, _substitute)
+ self.tk.call('bind', self._w, sequence,
+ (add + name,) + _subst_prefix)
+ def bind_all(self, sequence, func, add=''):
+ global _substitute, _subst_prefix
+ if add: add = '+'
+ name = self._register(func, _substitute)
+ self.tk.call('bind', 'all' , sequence,
+ (add + `name`,) + _subst_prefix)
+ def bind_class(self, className, sequence, func, add=''):
+ global _substitute, _subst_prefix
+ if add: add = '+'
+ name = self._register(func, _substitute)
+ self.tk.call('bind', className , sequence,
+ (add + name,) + _subst_prefix)
+ def mainloop(self):
+ self.tk.mainloop()
+ def quit(self):
+ self.tk.quit()
+ # Utilities
+ def _getints(self, string):
+ if string:
+ res = ()
+ for v in self.tk.split(string):
+ res = res + (self.tk.getint(v),)
+ return res
+ else:
+ return string
+ def _getboolean(self, string):
+ if string:
+ return self.tk.getboolean(string)
+ else:
+ return string
+ def _options(self, cnf):
+ res = ()
+ for k, v in cnf.items():
+ if _isfunctype(v):
+ v = self._register(v)
+ res = res + ('-'+k, v)
+ return res
+ def _register(self, func, subst=None):
+ f = func
+ f = _CallSafely(func, subst).__call__
+ name = `id(f)`
+ if hasattr(func, 'im_func'):
+ func = func.im_func
+ if hasattr(func, 'func_name') and \
+ type(func.func_name) == type(''):
+ name = name + func.func_name
+ self.tk.createcommand(name, f)
+ return name
+
+_subst_prefix = ('%#', '%b', '%f', '%h', '%k',
+ '%s', '%t', '%w', '%x', '%y',
+ '%A', '%E', '%K', '%N', '%T', '%X', '%Y')
+
+def _substitute(*args):
+ global default_root
+ global _subst_prefix
+ tk = default_root.tk
+ if len(args) != len(_subst_prefix): return args
+ nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, T, X, Y = args
+ # Missing: (a, c, d, m, o, v, B, R, W)
+ #XXX Convert %W (_w) to class instance?
+ e = Event()
+ e.serial = tk.getint(nsign)
+ e.num = tk.getint(b)
+ try: e.focus = tk.getboolean(f)
+ except TclError: pass
+ e.height = tk.getint(h)
+ e.keycode = tk.getint(k)
+ e.state = tk.getint(s)
+ e.time = tk.getint(t)
+ e.width = tk.getint(w)
+ e.x = tk.getint(x)
+ e.y = tk.getint(y)
+ e.char = A
+ try: e.send_event = tk.getboolean(E)
+ except TclError: pass
+ e.keysym = K
+ e.keysym_num = tk.getint(N)
+ e.type = T
+ #XXX %W stuff
+ e.x_root = tk.getint(X)
+ e.y_root = tk.getint(Y)
+ return (e,)
+
+class _CallSafely:
+ def __init__(self, func, subst=None):
+ self.func = func
+ self.subst = subst
+ def __call__(self, *args):
+ if self.subst:
+ args = self.apply_func(self.subst, args)
+ args = self.apply_func(self.func, args)
+ def apply_func(self, func, args):
+ import sys
+ try:
+ return apply(func, args)
+ except:
+ try:
+ try:
+ t = sys.exc_traceback
+ while t:
+ sys.stderr.write(
+ ' %s, line %s\n' %
+ (t.tb_frame.f_code,
+ t.tb_lineno))
+ t = t.tb_next
+ finally:
+ sys.stderr.write('%s: %s\n' %
+ (sys.exc_type,
+ sys.exc_value))
+ except:
+ print '*** Error in error handling ***'
+ print sys.exc_type, ':', sys.exc_value
+
+class Wm:
+ def aspect(self,
+ minNumer=None, minDenom=None,
+ maxNumer=None, maxDenom=None):
+ return self._getints(
+ self.tk.call('wm', 'aspect', self._w,
+ minNumer, minDenom,
+ maxNumer, maxDenom))
+ def client(self, name=None):
+ return self.tk.call('wm', 'client', self._w, name)
+ def command(self, value=None):
+ return self.tk.call('wm', 'command', self._w, value)
+ def deiconify(self):
+ return self.tk.call('wm', 'deiconify', self._w)
+ def focusmodel(self, model=None):
+ return self.tk.call('wm', 'focusmodel', self._w, model)
+ def frame(self):
+ return self.tk.call('wm', 'frame', self._w)
+ def geometry(self, newGeometry=None):
+ return self.tk.call('wm', 'geometry', self._w, newGeometry)
+ def grid(self,
+ baseWidht=None, baseHeight=None,
+ widthInc=None, heightInc=None):
+ return self._getints(self.tk.call(
+ 'wm', 'grid', self._w,
+ baseWidht, baseHeight, widthInc, heightInc))
+ def group(self, pathName=None):
+ return self.tk.call('wm', 'group', self._w, pathName)
+ def iconbitmap(self, bitmap=None):
+ return self.tk.call('wm', 'iconbitmap', self._w, bitmap)
+ def iconify(self):
+ return self.tk.call('wm', 'iconify', self._w)
+ def iconmask(self, bitmap=None):
+ return self.tk.call('wm', 'iconmask', self._w, bitmap)
+ def iconname(self, newName=None):
+ return self.tk.call('wm', 'iconname', self._w, newName)
+ def iconposition(self, x=None, y=None):
+ return self._getints(self.tk.call(
+ 'wm', 'iconposition', self._w, x, y))
+ def iconwindow(self, pathName=None):
+ return self.tk.call('wm', 'iconwindow', self._w, pathName)
+ def maxsize(self, width=None, height=None):
+ return self._getints(self.tk.call(
+ 'wm', 'maxsize', self._w, width, height))
+ def minsize(self, width=None, height=None):
+ return self._getints(self.tk.call(
+ 'wm', 'minsize', self._w, width, height))
+ def overrideredirect(self, boolean=None):
+ return self._getboolean(self.tk.call(
+ 'wm', 'overrideredirect', self._w, boolean))
+ def positionfrom(self, who=None):
+ return self.tk.call('wm', 'positionfrom', self._w, who)
+ def protocol(self, name=None, func=None):
+ if _isfunctype(func):
+ command = self._register(func)
+ else:
+ command = func
+ return self.tk.call(
+ 'wm', 'protocol', self._w, name, command)
+ def sizefrom(self, who=None):
+ return self.tk.call('wm', 'sizefrom', self._w, who)
+ def state(self):
+ return self.tk.call('wm', 'state', self._w)
+ def title(self, string=None):
+ return self.tk.call('wm', 'title', self._w, string)
+ def transient(self, master=None):
+ return self.tk.call('wm', 'transient', self._w, master)
+ def withdraw(self):
+ return self.tk.call('wm', 'withdraw', self._w)
+
+class Tk(Misc, Wm):
+ _w = '.'
+ def __init__(self, screenName=None, baseName=None, className='Tk'):
+ if baseName is None:
+ import sys, os
+ baseName = os.path.basename(sys.argv[0])
+ if baseName[-3:] == '.py': baseName = baseName[:-3]
+ self.tk = tkinter.create(screenName, baseName, className)
+ self.tk.createcommand('tkerror', tkerror)
+ def __del__(self):
+ self.tk.call('destroy', '.')
+ def __str__(self):
+ return '.'
+
+class Pack:
+ def config(self, cnf={}):
+ apply(self.tk.call,
+ ('pack', 'configure', self._w)
+ + self._options(cnf))
+ pack = config
+ def __setitem__(self, key, value):
+ Pack.config({key: value})
+ def forget(self):
+ self.tk.call('pack', 'forget', self._w)
+ def newinfo(self):
+ return self.tk.call('pack', 'newinfo', self._w)
+ info = newinfo
+ def propagate(self, boolean=None):
+ if boolean:
+ self.tk.call('pack', 'propagate', self._w)
+ else:
+ return self._getboolean(self.tk.call(
+ 'pack', 'propagate', self._w))
+ def slaves(self):
+ return self.tk.splitlist(self.tk.call(
+ 'pack', 'slaves', self._w))
+
+class Place:
+ def config(self, cnf={}):
+ apply(self.tk.call,
+ ('place', 'configure', self._w)
+ + self._options(cnf))
+ place = config
+ def __setitem__(self, key, value):
+ Place.config({key: value})
+ def forget(self):
+ self.tk.call('place', 'forget', self._w)
+ def info(self):
+ return self.tk.call('place', 'info', self._w)
+ def slaves(self):
+ return self.tk.splitlist(self.tk.call(
+ 'place', 'slaves', self._w))
+
+default_root = None
+
+class Widget(Misc, Pack, Place):
+ def __init__(self, master, widgetName, cnf={}, extra=()):
+ global default_root
+ if not master:
+ if not default_root:
+ default_root = Tk()
+ master = default_root
+ if not default_root:
+ default_root = master
+ self.master = master
+ self.tk = master.tk
+ if cnf.has_key('name'):
+ name = cnf['name']
+ del cnf['name']
+ else:
+ name = `id(self)`
+ if master._w=='.':
+ self._w = '.' + name
+ else:
+ self._w = master._w + '.' + name
+ self.widgetName = widgetName
+ apply(self.tk.call, (widgetName, self._w) + extra)
+ Widget.config(self, cnf)
+ def config(self, cnf={}):
+ for k in cnf.keys():
+ if type(k) == ClassType:
+ k.config(self, cnf[k])
+ del cnf[k]
+ apply(self.tk.call, (self._w, 'configure')
+ + self._options(cnf))
+ def __getitem__(self, key):
+ v = self.tk.split(self.tk.call(
+ self._w, 'configure', '-' + key))
+ return v[4]
+ def __setitem__(self, key, value):
+ Widget.config(self, {key: value})
+ def __str__(self):
+ return self._w
+ def __del__(self):
+ self.tk.call('destroy', self._w)
+ destroy = __del__
+ def _do(self, name, args=()):
+ apply(self.tk.call, (self._w, name) + args)
+
+class Toplevel(Widget, Wm):
+ def __init__(self, master=None, cnf={}):
+ extra = ()
+ if cnf.has_key('screen'):
+ extra = ('-screen', cnf['screen'])
+ del cnf['screen']
+ if cnf.has_key('class'):
+ extra = extra + ('-class', cnf['class'])
+ del cnf['class']
+ Widget.__init__(self, master, 'toplevel', cnf, extra)
+ self.iconname(self.tk.call('wm', 'iconname', '.'))
+ self.title(self.tk.call('wm', 'title', '.'))
+
+class Button(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'button', cnf)
+ def tk_butEnter(self):
+ self.tk.call('tk_butEnter', self._w)
+ def tk_butLeave(self):
+ self.tk.call('tk_butLeave', self._w)
+ def tk_butDown(self):
+ self.tk.call('tk_butDown', self._w)
+ def tk_butUp(self):
+ self.tk.call('tk_butUp', self._w)
+ def flash(self):
+ self.tk.call(self._w, 'flash')
+ def invoke(self):
+ self.tk.call(self._w, 'invoke')
+
+# Indices:
+def AtEnd():
+ return 'end'
+def AtInsert():
+ return 'insert'
+def AtSelFirst():
+ return 'sel.first'
+def AtSelLast():
+ return 'sel.last'
+def At(x, y=None):
+ if y:
+ return '@' + `x` + ',' + `y`
+ else:
+ return '@' + `x`
+
+class Canvas(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'canvas', cnf)
+ def addtag(self, *args):
+ self._do('addtag', args)
+ def bbox(self, *args):
+ return self._getints(self._do('bbox', args))
+ def bind(self, tagOrId, sequence, func, add=''):
+ global _substitute, _subst_prefix
+ if add: add='+'
+ name = self._register(func, _substitute)
+ self.tk.call(self._w, 'bind', tagOrId, sequence,
+ (add + name,) + _subst_prefix)
+ def canvasx(self, screenx, gridspacing=None):
+ return self.tk.getint(self.tk.call(
+ self._w, 'canvasx', screenx, gridspacing))
+ def canvasy(self, screeny, gridspacing=None):
+ return self.tk.getint(self.tk.call(
+ self._w, 'canvasy', screeny, gridspacing))
+ def coords(self, *args):
+ return self._do('coords', args)
+ def _create(self, itemType, args): # Args: (value, value, ..., cnf={})
+ cnf = args[-1]
+ if type(cnf) == type({}):
+ args = args[:-1]
+ else:
+ cnf = {}
+ v = (self._w, 'create', itemType) + args
+ for k in cnf.keys():
+ v = v + ('-' + k, cnf[k])
+ return self.tk.getint(apply(self.tk.call, v))
+ def create_arc(self, *args):
+ Canvas._create(self, 'arc', args)
+ def create_bitmap(self, *args):
+ Canvas._create(self, 'bitmap', args)
+ def create_line(self, *args):
+ Canvas._create(self, 'line', args)
+ def create_oval(self, *args):
+ Canvas._create(self, 'oval', args)
+ def create_polygon(self, *args):
+ Canvas._create(self, 'polygon', args)
+ def create_rectangle(self, *args):
+ Canvas._create(self, 'rectangle', args)
+ def create_text(self, *args):
+ Canvas._create(self, 'text', args)
+ def create_window(self, *args):
+ Canvas._create(self, 'window', args)
+ def dchars(self, *args):
+ self._do('dchars', args)
+ def delete(self, *args):
+ self._do('delete', args)
+ def dtag(self, *args):
+ self._do('dtag', args)
+ def find(self, *args):
+ self.tk.splitlist(self._do('find', args))
+ def focus(self, *args):
+ return self._do('focus', args)
+ def gettags(self, *args):
+ return self.tk.splitlist(self._do('gettags', args))
+ def icursor(self, *args):
+ self._do('icursor', args)
+ def index(self, *args):
+ return self.tk.getint(self._do('index', args))
+ def insert(self, *args):
+ self._do('insert', args)
+ def itemconfig(self, tagOrId, cnf={}):
+ self._do('itemconfigure', (tagOrId,) + self._options(cnf))
+ def lower(self, *args):
+ self._do('lower', args)
+ def move(self, *args):
+ self._do('move', args)
+ def postscript(self, cnf={}):
+ return self._do('postscript', self._options(cnf))
+ def tkraise(self, *args):
+ self._do('raise', args)
+ def scale(self, *args):
+ self._do('scale', args)
+ def scan_mark(self, x, y):
+ self.tk.call(self._w, 'scan', 'mark', x, y)
+ def scan_dragto(self, x, y):
+ self.tk.call(self._w, 'scan', 'dragto', x, y)
+ def select_adjust(self, tagOrId, index):
+ self.tk.call(
+ self._w, 'select', 'adjust', tagOrId, index)
+ def select_clear(self):
+ self.tk.call(self._w, 'select', 'clear')
+ def select_from(self, tagOrId, index):
+ self.tk.call(
+ self._w, 'select', 'from', tagOrId, index)
+ def select_item(self):
+ self.tk.call(self._w, 'select', 'item')
+ def select_to(self, tagOrId, index):
+ self.tk.call(
+ self._w, 'select', 'to', tagOrId, index)
+ def type(self, tagOrId):
+ return self.tk.splitlist(self.tk.call(
+ self._w, 'type', tagOrId))
+ def xview(self, index):
+ self.tk.call(self._w, 'xview', index)
+ def yview(self, index):
+ self.tk.call(self._w, 'yview', index)
+
+class Checkbutton(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'checkbutton', cnf)
+ def deselect(self):
+ self.tk.call(self._w, 'deselect')
+ def flash(self):
+ self.tk.call(self._w, 'flash')
+ def invoke(self):
+ self.tk.call(self._w, 'invoke')
+ def select(self):
+ self.tk.call(self._w, 'select')
+ def toggle(self):
+ self.tk.call(self._w, 'toggle')
+
+class Entry(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'entry', cnf)
+ def tk_entryBackspace(self):
+ self.tk.call('tk_entryBackspace', self._w)
+ def tk_entryBackword(self):
+ self.tk.call('tk_entryBackword', self._w)
+ def tk_entrySeeCaret(self):
+ self.tk.call('tk_entrySeeCaret', self._w)
+ def delete(self, first, last=None):
+ self.tk.call(self._w, 'delete', first, last)
+ def get(self):
+ return self.tk.call(self._w, 'get')
+ def icursor(self, index):
+ self.tk.call(self._w, 'icursor', index)
+ def index(self, index):
+ return self.tk.getint(self.tk.call(
+ self._w, 'index', index))
+ def insert(self, index, string):
+ self.tk.call(self._w, 'insert', index, string)
+ def scan_mark(self, x):
+ self.tk.call(self._w, 'scan', 'mark', x)
+ def scan_dragto(self, x):
+ self.tk.call(self._w, 'scan', 'dragto', x)
+ def select_adjust(self, index):
+ self.tk.call(self._w, 'select', 'adjust', index)
+ def select_clear(self):
+ self.tk.call(self._w, 'select', 'clear')
+ def select_from(self, index):
+ self.tk.call(self._w, 'select', 'from', index)
+ def select_to(self, index):
+ self.tk.call(self._w, 'select', 'to', index)
+ def select_view(self, index):
+ self.tk.call(self._w, 'select', 'view', index)
+
+class Frame(Widget):
+ def __init__(self, master=None, cnf={}):
+ extra = ()
+ if cnf.has_key('class'):
+ extra = ('-class', cnf['class'])
+ del cnf['class']
+ Widget.__init__(self, master, 'frame', cnf, extra)
+ def tk_menuBar(self, *args):
+ apply(self.tk.call, ('tk_menuBar', self._w) + args)
+
+class Label(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'label', cnf)
+
+class Listbox(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'listbox', cnf)
+ def tk_listboxSingleSelect(self):
+ self.tk.call('tk_listboxSingleSelect', self._w)
+ def curselection(self):
+ return self.tk.splitlist(self.tk.call(
+ self._w, 'curselection'))
+ def delete(self, first, last=None):
+ self.tk.call(self._w, 'delete', first, last)
+ def get(self, index):
+ return self.tk.call(self._w, 'get', index)
+ def insert(self, index, *elements):
+ apply(self.tk.call,
+ (self._w, 'insert', index) + elements)
+ def nearest(self, y):
+ return self.tk.getint(self.tk.call(
+ self._w, 'nearest', y))
+ def scan_mark(self, x, y):
+ self.tk.call(self._w, 'scan', 'mark', x, y)
+ def scan_dragto(self, x, y):
+ self.tk.call(self._w, 'scan', 'dragto', x, y)
+ def select_adjust(self, index):
+ self.tk.call(self._w, 'select', 'adjust', index)
+ def select_clear(self):
+ self.tk.call(self._w, 'select', 'clear')
+ def select_from(self, index):
+ self.tk.call(self._w, 'select', 'from', index)
+ def select_to(self, index):
+ self.tk.call(self._w, 'select', 'to', index)
+ def size(self):
+ return self.tk.getint(self.tk.call(self._w, 'size'))
+ def xview(self, index):
+ self.tk.call(self._w, 'xview', index)
+ def yview(self, index):
+ self.tk.call(self._w, 'yview', index)
+
+class Menu(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'menu', cnf)
+ def tk_menuBar(self, *args):
+ apply(self.tk.call, ('tk_menuBar', self._w) + args)
+ def tk_bindForTraversal(self):
+ self.tk.call('tk_bindForTraversal', self._w)
+ def tk_mbPost(self):
+ self.tk.call('tk_mbPost', self._w)
+ def tk_mbUnpost(self):
+ self.tk.call('tk_mbUnpost')
+ def tk_traverseToMenu(self, char):
+ self.tk.call('tk_traverseToMenu', self._w, char)
+ def tk_traverseWithinMenu(self, char):
+ self.tk.call('tk_traverseWithinMenu', self._w, char)
+ def tk_getMenuButtons(self):
+ return self.tk.call('tk_getMenuButtons', self._w)
+ def tk_nextMenu(self, count):
+ self.tk.call('tk_nextMenu', count)
+ def tk_nextMenuEntry(self, count):
+ self.tk.call('tk_nextMenuEntry', count)
+ def tk_invokeMenu(self):
+ self.tk.call('tk_invokeMenu', self._w)
+ def tk_firstMenu(self):
+ self.tk.call('tk_firstMenu', self._w)
+ def tk_mbButtonDown(self):
+ self.tk.call('tk_mbButtonDown', self._w)
+ def activate(self, index):
+ self.tk.call(self._w, 'activate', index)
+ def add(self, itemType, cnf={}):
+ apply(self.tk.call, (self._w, 'add', itemType)
+ + self._options(cnf))
+ def delete(self, index1, index2=None):
+ self.tk.call(self._w, 'delete', index1, index2)
+ def entryconfig(self, index, cnf={}):
+ apply(self.tk.call, (self._w, 'entryconfigure', index)
+ + self._options(cnf))
+ def index(self, index):
+ return self.tk.call(self._w, 'index', index)
+ def invoke(self, index):
+ return self.tk.call(self._w, 'invoke', index)
+ def post(self, x, y):
+ self.tk.call(self._w, 'post', x, y)
+ def unpost(self):
+ self.tk.call(self._w, 'unpost')
+ def yposition(self, index):
+ return self.tk.getint(self.tk.call(
+ self._w, 'yposition', index))
+
+class Menubutton(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'menubutton', cnf)
+
+class Message(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'message', cnf)
+
+class Radiobutton(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'radiobutton', cnf)
+ def deselect(self):
+ self.tk.call(self._w, 'deselect')
+ def flash(self):
+ self.tk.call(self._w, 'flash')
+ def invoke(self):
+ self.tk.call(self._w, 'invoke')
+ def select(self):
+ self.tk.call(self._w, 'select')
+
+class Scale(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'scale', cnf)
+ def get(self):
+ return self.tk.getint(self.tk.call(self._w, 'get'))
+ def set(self, value):
+ self.tk.call(self._w, 'set', value)
+
+class Scrollbar(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'scrollbar', cnf)
+ def get(self):
+ return self.tk.getints(self.tk.call(self._w, 'get'))
+ def set(self, totalUnits, windowUnits, firstUnit, lastUnit):
+ self.tk.call(self._w, 'set',
+ totalUnits, windowUnits, firstUnit, lastUnit)
+
+class Text(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'text', cnf)
+ def tk_textSelectTo(self, index):
+ self.tk.call('tk_textSelectTo', self._w, index)
+ def tk_textBackspace(self):
+ self.tk.call('tk_textBackspace', self._w)
+ def tk_textIndexCloser(self, a, b, c):
+ self.tk.call('tk_textIndexCloser', self._w, a, b, c)
+ def tk_textResetAnchor(self, index):
+ self.tk.call('tk_textResetAnchor', self._w, index)
+ def compare(self, index1, op, index2):
+ return self.tk.getboolean(self.tk.call(
+ self._w, 'compare', index1, op, index2))
+ def debug(self, boolean=None):
+ return self.tk.getboolean(self.tk.call(
+ self._w, 'debug', boolean))
+ def delete(self, index1, index2=None):
+ self.tk.call(self._w, 'delete', index1, index2)
+ def get(self, index1, index2=None):
+ return self.tk.call(self._w, 'get', index1, index2)
+ def index(self, index):
+ return self.tk.call(self._w, 'index', index)
+ def insert(self, index, chars):
+ self.tk.call(self._w, 'insert', index, chars)
+ def mark_names(self):
+ return self.tk.splitlist(self.tk.call(
+ self._w, 'mark', 'names'))
+ def mark_set(self, markName, index):
+ self.tk.call(self._w, 'mark', 'set', markName, index)
+ def mark_unset(self, markNames):
+ apply(self.tk.call, (self._w, 'mark', 'unset') + markNames)
+ def scan_mark(self, y):
+ self.tk.call(self._w, 'scan', 'mark', y)
+ def scan_dragto(self, y):
+ self.tk.call(self._w, 'scan', 'dragto', y)
+ def tag_add(self, tagName, index1, index2=None):
+ self.tk.call(
+ self._w, 'tag', 'add', tagName, index1, index2)
+ def tag_bind(self, tagName, sequence, func, add=''):
+ global _substitute, _subst_prefix
+ if add: add='+'
+ name = self._register(func, _substitute)
+ self.tk.call(self._w, 'tag', 'bind',
+ tagName, sequence,
+ (add + name,) + _subst_prefix)
+ def tag_config(self, tagName, cnf={}):
+ apply(self.tk.call,
+ (self._w, 'tag', 'configure', tagName)
+ + self._options(cnf))
+ def tag_delete(self, tagNames):
+ apply(self.tk.call, (self._w, 'tag', 'delete')
+ + tagNames)
+ def tag_lower(self, tagName, belowThis=None):
+ self.tk.call(self._w, 'tag', 'lower',
+ tagName, belowThis)
+ def tag_names(self, index=None):
+ return self.tk.splitlist(
+ self.tk.call(self._w, 'tag', 'names', index))
+ def tag_nextrange(self, tagName, index1, index2=None):
+ return self.tk.splitlist(self.tk.call(
+ self._w, 'tag', 'nextrange', index1, index2))
+ def tag_raise(self, tagName, aboveThis=None):
+ self.tk.call(
+ self._w, 'tag', 'raise', tagName, aboveThis)
+ def tag_ranges(self, tagName):
+ return self.tk.splitlist(self.tk.call(
+ self._w, 'tag', 'ranges', tagName))
+ def tag_remove(self, tagName, index1, index2=None):
+ self.tk.call(
+ self._w, 'tag', 'remove', index1, index2)
+ def yview(self, what):
+ self.tk.call(self._w, 'yview', what)
+ def yview_pickplace(self, what):
+ self.tk.call(self._w, 'yview', '-pickplace', what)
+
+#class Dialog:
+
diff --git a/Lib/tkinter/Canvas.py b/Lib/tkinter/Canvas.py
new file mode 100755
index 0000000..4d21928
--- /dev/null
+++ b/Lib/tkinter/Canvas.py
@@ -0,0 +1,115 @@
+# This module exports classes for the various canvas item types
+
+# vi:set tabsize=4:
+
+from Tkinter import Canvas, _isfunctype
+
+class CanvasItem:
+ def __init__(self, canvas, itemType, args = (), cnf={}):
+ self.canvas = canvas
+ self.id = canvas._create(itemType, args + (cnf,))
+ def __str__(self):
+ return str(self.id)
+ def __repr__(self):
+ return '<%s, id=%d>' % (self.__class__.__name__, self.id)
+ def __del__(self):
+ self.canvas.delete(self.id)
+ delete = __del__
+ def __getitem__(self, key):
+ v = self.canvas.tk.split(self.canvas.tk.call(self.canvas.pathName,
+ 'itemconfigure',
+ str(self.id),
+ '-' + key))
+ return v[4]
+ def __setitem__(self, key, value):
+ self.canvas._itemconfig(self.id, {key: value})
+ def keys(self):
+ if not hasattr(self, '_keys'):
+ self._keys = map(lambda x, tk=self.canvas.tk:
+ tk.splitlist(x)[0][1:],
+ self.canvas._splitlist(
+ self.canvas.cmd('itemconfigure', self.id)))
+ return self._keys
+ def has_key(self, key):
+ return key in self.keys()
+ def addtag(self, tag, option='withtag'):
+ self.canvas.addtag(tag, option, self.id)
+ def bbox(self):
+ x1, y1, x2, y2 = self.canvas.bbox(self.id)
+ return (x1, y1), (x2, y2)
+ def bind(self, sequence=None, command=None):
+ return self.canvas.bind(self.id, sequence, command)
+ def coords(self, pts = ()):
+ flat = ()
+ for x, y in pts: flat = flat + (x, y)
+ return apply(self.canvas.coords, (self.id,) + flat)
+ def dchars(self, first, last=None):
+ self.canvas.dchars(self.id, first, last)
+ def dtag(self, ttd):
+ self.canvas.dtag(self.id, ttd)
+ def focus(self):
+ self.canvas.focus(self.id)
+ def gettags(self):
+ return self.canvas.gettags(self.id)
+ def icursor(self):
+ self.canvas.icursor(self.id)
+ def index(self):
+ return self.canvas.index(self.id)
+ def insert(self, beforethis, string):
+ self.canvas.insert(self.id, beforethis, string)
+ def lower(self, belowthis=None):
+ self.canvas.lower(self.id, belowthis)
+ def move(self, xamount, yamount):
+ self.canvas.move(self.id, xamount, yamount)
+ def raise_(self, abovethis=None):
+ self.canvas.raise_(self.id, abovethis)
+ def scale(self, xorigin, yorigin, xscale, yscale):
+ self.canvas.scale(self.id, xorigin, yorigin, xscale, yscale)
+ def type(self):
+ return self.canvas.type(self.id)
+
+class Arc(CanvasItem):
+ def __init__(self, canvas, (x1, y1), (x2, y2), cnf={}):
+ CanvasItem.__init__(self, canvas, 'arc',
+ (str(x1), str(y1), str(x2), str(y2)), cnf)
+
+class Bitmap(CanvasItem):
+ def __init__(self, canvas, (x1, y1), cnf={}):
+ CanvasItem.__init__(self, canvas, 'bitmap', (str(x1), str(y1)), cnf)
+
+class Line(CanvasItem):
+ def __init__(self, canvas, pts, cnf={}):
+ pts = reduce(lambda a, b: a+b,
+ map(lambda pt: (str(pt[0]), str(pt[1])), pts))
+ CanvasItem.__init__(self, canvas, 'line', pts, cnf)
+
+class Oval(CanvasItem):
+ def __init__(self, canvas, (x1, y1), (x2, y2), cnf={}):
+ CanvasItem.__init__(self, canvas, 'oval',
+ (str(x1), str(y1), str(x2), str(y2)), cnf)
+
+class Polygon(CanvasItem):
+ def __init__(self, canvas, pts, cnf={}):
+ pts = reduce(lambda a, b: a+b,
+ map(lambda pt: (str(pt[0]), str(pt[1])), pts))
+ CanvasItem.__init__(self, canvas, 'polygon', pts, cnf)
+
+class Curve(Polygon):
+ def __init__(self, canvas, pts, cnf={}):
+ cnf['smooth'] = 'yes'
+ Polygon.__init__(self, canvas, pts, cnf)
+
+class Rectangle(CanvasItem):
+ def __init__(self, canvas, (x1, y1), (x2, y2), cnf={}):
+ CanvasItem.__init__(self, canvas, 'rectangle',
+ (str(x1), str(y1), str(x2), str(y2)), cnf)
+
+# XXX Can't use name "Text" since that is already taken by the Text widget...
+class String(CanvasItem):
+ def __init__(self, canvas, (x1, y1), cnf={}):
+ CanvasItem.__init__(self, canvas, 'text', (str(x1), str(y1)), cnf)
+
+class Window(CanvasItem):
+ def __init__(self, canvas, where, cnf={}):
+ CanvasItem.__init__(self, canvas, 'window',
+ (str(where[0]), str(where[1])), cnf)
diff --git a/Lib/tkinter/ScrolledText.py b/Lib/tkinter/ScrolledText.py
new file mode 100755
index 0000000..9effae0
--- /dev/null
+++ b/Lib/tkinter/ScrolledText.py
@@ -0,0 +1,35 @@
+# A ScrolledText widget feels like a text widget but also has a
+# vertical scroll bar on its right. (Later, options may be added to
+# add a horizontal bar as well, to make the bars disappear
+# automatically when not needed, to move them to the other side of the
+# window, etc.)
+#
+# Configuration options are passed to the Text widget.
+# A Frame widget is inserted between the master and the text, to hold
+# the Scrollbar widget.
+# Most methods calls are passed to the Text widget; the pack command
+# is redirected to the Frame widget however.
+
+from Tkinter import *
+
+class ScrolledText(Pack, Place):
+ def __init__(self, master=None, cnf={}):
+ fcnf = {}
+ self.frame = Frame(master, {})
+ if cnf.has_key(Pack):
+ self.frame.pack(cnf[Pack])
+ del cnf[Pack]
+ self.vbar = Scrollbar(self.frame, {})
+ self.vbar.pack({'side': 'right', 'fill': 'y'})
+ cnf[Pack] = {'side': 'left', 'fill': 'both',
+ 'expand': 'yes'}
+ self.text = Text(self.frame, cnf)
+ self.text['yscrollcommand'] = (self.vbar, 'set')
+ self.vbar['command'] = (self.text, 'yview')
+ self.insert = self.text.insert
+ # XXX should do all Text methods...
+ self.pack = self.frame.pack
+ self.forget = self.frame.forget
+ self.tk = master.tk
+ def __str__(self):
+ return str(self.frame)
diff --git a/Lib/tkinter/Tkinter.py b/Lib/tkinter/Tkinter.py
new file mode 100755
index 0000000..e9e641c
--- /dev/null
+++ b/Lib/tkinter/Tkinter.py
@@ -0,0 +1,874 @@
+# Tkinter.py -- Tk/Tcl widget wrappers
+import tkinter
+from tkinter import TclError
+
+class _Dummy:
+ def meth(self): return
+
+def _isfunctype(func):
+ return type(func) in (type(_Dummy.meth), type(_isfunctype))
+
+FunctionType = type(_isfunctype)
+ClassType = type(_Dummy)
+MethodType = type(_Dummy.meth)
+
+def tkerror(err):
+ pass
+
+class Event:
+ pass
+
+class Misc:
+ def tk_strictMotif(self, boolean=None):
+ self.tk.getboolean(self.tk.call(
+ 'set', 'tk_strictMotif', boolean))
+ def waitvar(self, name='VAR'):
+ self.tk.call('tkwait', 'variable', name)
+ def setvar(self, name='VAR', value='1'):
+ self.tk.setvar(name, value)
+ def focus(self):
+ self.tk.call('focus', self._w)
+ def focus_default(self):
+ self.tk.call('focus', 'default', self._w)
+ def focus_none(self):
+ self.tk.call('focus', 'none')
+ #XXX focus_get?
+ def after(self, ms, func=None, *args):
+ if not func:
+ self.tk.call('after', ms)
+ else:
+ name = self._register(func)
+ apply(self.tk.call, ('after', ms, name) + args)
+ #XXX grab_current
+ def grab_release(self):
+ self.tk.call('grab', 'release', self._w)
+ def grab_set(self):
+ self.tk.call('grab', 'set', self._w)
+ def grab_set_global(self):
+ self.tk.call('grab', 'set', '-global', self._w)
+ def grab_status(self):
+ self.tk.call('grab', 'status', self._w)
+ def lower(self, belowThis=None):
+ self.tk.call('lower', self._w, belowThis)
+ def selection_clear(self):
+ self.tk.call('selection', 'clear', self._w)
+ def selection_get(self, type=None):
+ self.tk.call('selection', 'get', type)
+ def selection_handle(self, func, type=None, format=None):
+ name = self._register(func)
+ self.tk.call('selection', 'handle',
+ self._w, name, type, format)
+ #XXX def selection_own(self):
+ # self.tk.call('selection', 'own', self._w)
+ def send(self, interp, cmd, *args): #XXX
+ return apply(self.tk.call, ('send', interp, cmd) + args)
+ def colormodel(self, value=None):
+ return self.tk.call('tk', 'colormodel', self._w, value)
+ def winfo_atom(self, name):
+ return self.tk.getint(self.tk.call('winfo', 'atom', name))
+ def winfo_atomname(self, id):
+ return self.tk.call('winfo', 'atomname', id)
+ def winfo_cells(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'cells', self._w))
+ #XXX winfo_children
+ def winfo_class(self):
+ return self.tk.call('winfo', 'class', self._w)
+ def winfo_containing(self, rootX, rootY):
+ return self.tk.call('winfo', 'containing', rootx, rootY)
+ def winfo_depth(self):
+ return self.tk.getint(self.tk.call('winfo', 'depth', self._w))
+ def winfo_exists(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'exists', self._w))
+ def winfo_fpixels(self, number):
+ return self.tk.getdouble(self.tk.call(
+ 'winfo', 'fpixels', self._w, number))
+ def winfo_geometry(self):
+ return self.tk.call('winfo', 'geometry', self._w)
+ def winfo_height(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'height', self._w))
+ def winfo_id(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'id', self._w))
+ def winfo_interps(self):
+ return self.tk.splitlist(
+ self.tk.call('winfo', 'interps'))
+ def winfo_ismapped(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'ismapped', self._w))
+ def winfo_name(self):
+ return self.tk.call('winfo', 'name', self._w)
+ def winfo_parent(self):
+ return self.tk.call('winfo', 'parent', self._w)
+ def winfo_pathname(self, id):
+ return self.tk.call('winfo', 'pathname', id)
+ def winfo_pixels(self, number):
+ return self.tk.getint(
+ self.tk.call('winfo', 'pixels', self._w, number))
+ def winfo_reqheight(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'reqheight', self._w))
+ def winfo_reqwidth(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'reqwidth', self._w))
+ def winfo_rgb(self, color):
+ return self._getints(
+ self.tk.call('winfo', 'rgb', self._w, color))
+ def winfo_rootx(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'rootx', self._w))
+ def winfo_rooty(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'rooty', self._w))
+ def winfo_screen(self):
+ return self.tk.call('winfo', 'screen', self._w)
+ def winfo_screencells(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'screencells', self._w))
+ def winfo_screendepth(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'screendepth', self._w))
+ def winfo_screenheight(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'screenheight', self._w))
+ def winfo_screenmmheight(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'screenmmheight', self._w))
+ def winfo_screenmmwidth(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'screenmmwidth', self._w))
+ def winfo_screenvisual(self):
+ return self.tk.call('winfo', 'screenvisual', self._w)
+ def winfo_screenwidth(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'screenwidth', self._w))
+ def winfo_toplevel(self):
+ return self.tk.call('winfo', 'toplevel', self._w)
+ def winfo_visual(self):
+ return self.tk.call('winfo', 'visual', self._w)
+ def winfo_vrootheight(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'vrootheight', self._w))
+ def winfo_vrootwidth(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'vrootwidth', self._w))
+ def winfo_vrootx(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'vrootx', self._w))
+ def winfo_vrooty(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'vrooty', self._w))
+ def winfo_width(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'width', self._w))
+ def winfo_x(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'x', self._w))
+ def winfo_y(self):
+ return self.tk.getint(
+ self.tk.call('winfo', 'y', self._w))
+ def update(self):
+ self.tk.call('update')
+ def update_idletasks(self):
+ self.tk.call('update', 'idletasks')
+ def bind(self, sequence, func, add=''):
+ global _substitute, _subst_prefix
+ if add: add = '+'
+ name = self._register(func, _substitute)
+ self.tk.call('bind', self._w, sequence,
+ (add + name,) + _subst_prefix)
+ def bind_all(self, sequence, func, add=''):
+ global _substitute, _subst_prefix
+ if add: add = '+'
+ name = self._register(func, _substitute)
+ self.tk.call('bind', 'all' , sequence,
+ (add + `name`,) + _subst_prefix)
+ def bind_class(self, className, sequence, func, add=''):
+ global _substitute, _subst_prefix
+ if add: add = '+'
+ name = self._register(func, _substitute)
+ self.tk.call('bind', className , sequence,
+ (add + name,) + _subst_prefix)
+ def mainloop(self):
+ self.tk.mainloop()
+ def quit(self):
+ self.tk.quit()
+ # Utilities
+ def _getints(self, string):
+ if string:
+ res = ()
+ for v in self.tk.split(string):
+ res = res + (self.tk.getint(v),)
+ return res
+ else:
+ return string
+ def _getboolean(self, string):
+ if string:
+ return self.tk.getboolean(string)
+ else:
+ return string
+ def _options(self, cnf):
+ res = ()
+ for k, v in cnf.items():
+ if _isfunctype(v):
+ v = self._register(v)
+ res = res + ('-'+k, v)
+ return res
+ def _register(self, func, subst=None):
+ f = func
+ f = _CallSafely(func, subst).__call__
+ name = `id(f)`
+ if hasattr(func, 'im_func'):
+ func = func.im_func
+ if hasattr(func, 'func_name') and \
+ type(func.func_name) == type(''):
+ name = name + func.func_name
+ self.tk.createcommand(name, f)
+ return name
+
+_subst_prefix = ('%#', '%b', '%f', '%h', '%k',
+ '%s', '%t', '%w', '%x', '%y',
+ '%A', '%E', '%K', '%N', '%T', '%X', '%Y')
+
+def _substitute(*args):
+ global default_root
+ global _subst_prefix
+ tk = default_root.tk
+ if len(args) != len(_subst_prefix): return args
+ nsign, b, f, h, k, s, t, w, x, y, A, E, K, N, T, X, Y = args
+ # Missing: (a, c, d, m, o, v, B, R, W)
+ #XXX Convert %W (_w) to class instance?
+ e = Event()
+ e.serial = tk.getint(nsign)
+ e.num = tk.getint(b)
+ try: e.focus = tk.getboolean(f)
+ except TclError: pass
+ e.height = tk.getint(h)
+ e.keycode = tk.getint(k)
+ e.state = tk.getint(s)
+ e.time = tk.getint(t)
+ e.width = tk.getint(w)
+ e.x = tk.getint(x)
+ e.y = tk.getint(y)
+ e.char = A
+ try: e.send_event = tk.getboolean(E)
+ except TclError: pass
+ e.keysym = K
+ e.keysym_num = tk.getint(N)
+ e.type = T
+ #XXX %W stuff
+ e.x_root = tk.getint(X)
+ e.y_root = tk.getint(Y)
+ return (e,)
+
+class _CallSafely:
+ def __init__(self, func, subst=None):
+ self.func = func
+ self.subst = subst
+ def __call__(self, *args):
+ if self.subst:
+ args = self.apply_func(self.subst, args)
+ args = self.apply_func(self.func, args)
+ def apply_func(self, func, args):
+ import sys
+ try:
+ return apply(func, args)
+ except:
+ try:
+ try:
+ t = sys.exc_traceback
+ while t:
+ sys.stderr.write(
+ ' %s, line %s\n' %
+ (t.tb_frame.f_code,
+ t.tb_lineno))
+ t = t.tb_next
+ finally:
+ sys.stderr.write('%s: %s\n' %
+ (sys.exc_type,
+ sys.exc_value))
+ except:
+ print '*** Error in error handling ***'
+ print sys.exc_type, ':', sys.exc_value
+
+class Wm:
+ def aspect(self,
+ minNumer=None, minDenom=None,
+ maxNumer=None, maxDenom=None):
+ return self._getints(
+ self.tk.call('wm', 'aspect', self._w,
+ minNumer, minDenom,
+ maxNumer, maxDenom))
+ def client(self, name=None):
+ return self.tk.call('wm', 'client', self._w, name)
+ def command(self, value=None):
+ return self.tk.call('wm', 'command', self._w, value)
+ def deiconify(self):
+ return self.tk.call('wm', 'deiconify', self._w)
+ def focusmodel(self, model=None):
+ return self.tk.call('wm', 'focusmodel', self._w, model)
+ def frame(self):
+ return self.tk.call('wm', 'frame', self._w)
+ def geometry(self, newGeometry=None):
+ return self.tk.call('wm', 'geometry', self._w, newGeometry)
+ def grid(self,
+ baseWidht=None, baseHeight=None,
+ widthInc=None, heightInc=None):
+ return self._getints(self.tk.call(
+ 'wm', 'grid', self._w,
+ baseWidht, baseHeight, widthInc, heightInc))
+ def group(self, pathName=None):
+ return self.tk.call('wm', 'group', self._w, pathName)
+ def iconbitmap(self, bitmap=None):
+ return self.tk.call('wm', 'iconbitmap', self._w, bitmap)
+ def iconify(self):
+ return self.tk.call('wm', 'iconify', self._w)
+ def iconmask(self, bitmap=None):
+ return self.tk.call('wm', 'iconmask', self._w, bitmap)
+ def iconname(self, newName=None):
+ return self.tk.call('wm', 'iconname', self._w, newName)
+ def iconposition(self, x=None, y=None):
+ return self._getints(self.tk.call(
+ 'wm', 'iconposition', self._w, x, y))
+ def iconwindow(self, pathName=None):
+ return self.tk.call('wm', 'iconwindow', self._w, pathName)
+ def maxsize(self, width=None, height=None):
+ return self._getints(self.tk.call(
+ 'wm', 'maxsize', self._w, width, height))
+ def minsize(self, width=None, height=None):
+ return self._getints(self.tk.call(
+ 'wm', 'minsize', self._w, width, height))
+ def overrideredirect(self, boolean=None):
+ return self._getboolean(self.tk.call(
+ 'wm', 'overrideredirect', self._w, boolean))
+ def positionfrom(self, who=None):
+ return self.tk.call('wm', 'positionfrom', self._w, who)
+ def protocol(self, name=None, func=None):
+ if _isfunctype(func):
+ command = self._register(func)
+ else:
+ command = func
+ return self.tk.call(
+ 'wm', 'protocol', self._w, name, command)
+ def sizefrom(self, who=None):
+ return self.tk.call('wm', 'sizefrom', self._w, who)
+ def state(self):
+ return self.tk.call('wm', 'state', self._w)
+ def title(self, string=None):
+ return self.tk.call('wm', 'title', self._w, string)
+ def transient(self, master=None):
+ return self.tk.call('wm', 'transient', self._w, master)
+ def withdraw(self):
+ return self.tk.call('wm', 'withdraw', self._w)
+
+class Tk(Misc, Wm):
+ _w = '.'
+ def __init__(self, screenName=None, baseName=None, className='Tk'):
+ if baseName is None:
+ import sys, os
+ baseName = os.path.basename(sys.argv[0])
+ if baseName[-3:] == '.py': baseName = baseName[:-3]
+ self.tk = tkinter.create(screenName, baseName, className)
+ self.tk.createcommand('tkerror', tkerror)
+ def __del__(self):
+ self.tk.call('destroy', '.')
+ def __str__(self):
+ return '.'
+
+class Pack:
+ def config(self, cnf={}):
+ apply(self.tk.call,
+ ('pack', 'configure', self._w)
+ + self._options(cnf))
+ pack = config
+ def __setitem__(self, key, value):
+ Pack.config({key: value})
+ def forget(self):
+ self.tk.call('pack', 'forget', self._w)
+ def newinfo(self):
+ return self.tk.call('pack', 'newinfo', self._w)
+ info = newinfo
+ def propagate(self, boolean=None):
+ if boolean:
+ self.tk.call('pack', 'propagate', self._w)
+ else:
+ return self._getboolean(self.tk.call(
+ 'pack', 'propagate', self._w))
+ def slaves(self):
+ return self.tk.splitlist(self.tk.call(
+ 'pack', 'slaves', self._w))
+
+class Place:
+ def config(self, cnf={}):
+ apply(self.tk.call,
+ ('place', 'configure', self._w)
+ + self._options(cnf))
+ place = config
+ def __setitem__(self, key, value):
+ Place.config({key: value})
+ def forget(self):
+ self.tk.call('place', 'forget', self._w)
+ def info(self):
+ return self.tk.call('place', 'info', self._w)
+ def slaves(self):
+ return self.tk.splitlist(self.tk.call(
+ 'place', 'slaves', self._w))
+
+default_root = None
+
+class Widget(Misc, Pack, Place):
+ def __init__(self, master, widgetName, cnf={}, extra=()):
+ global default_root
+ if not master:
+ if not default_root:
+ default_root = Tk()
+ master = default_root
+ if not default_root:
+ default_root = master
+ self.master = master
+ self.tk = master.tk
+ if cnf.has_key('name'):
+ name = cnf['name']
+ del cnf['name']
+ else:
+ name = `id(self)`
+ if master._w=='.':
+ self._w = '.' + name
+ else:
+ self._w = master._w + '.' + name
+ self.widgetName = widgetName
+ apply(self.tk.call, (widgetName, self._w) + extra)
+ Widget.config(self, cnf)
+ def config(self, cnf={}):
+ for k in cnf.keys():
+ if type(k) == ClassType:
+ k.config(self, cnf[k])
+ del cnf[k]
+ apply(self.tk.call, (self._w, 'configure')
+ + self._options(cnf))
+ def __getitem__(self, key):
+ v = self.tk.split(self.tk.call(
+ self._w, 'configure', '-' + key))
+ return v[4]
+ def __setitem__(self, key, value):
+ Widget.config(self, {key: value})
+ def __str__(self):
+ return self._w
+ def __del__(self):
+ self.tk.call('destroy', self._w)
+ destroy = __del__
+ def _do(self, name, args=()):
+ apply(self.tk.call, (self._w, name) + args)
+
+class Toplevel(Widget, Wm):
+ def __init__(self, master=None, cnf={}):
+ extra = ()
+ if cnf.has_key('screen'):
+ extra = ('-screen', cnf['screen'])
+ del cnf['screen']
+ if cnf.has_key('class'):
+ extra = extra + ('-class', cnf['class'])
+ del cnf['class']
+ Widget.__init__(self, master, 'toplevel', cnf, extra)
+ self.iconname(self.tk.call('wm', 'iconname', '.'))
+ self.title(self.tk.call('wm', 'title', '.'))
+
+class Button(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'button', cnf)
+ def tk_butEnter(self):
+ self.tk.call('tk_butEnter', self._w)
+ def tk_butLeave(self):
+ self.tk.call('tk_butLeave', self._w)
+ def tk_butDown(self):
+ self.tk.call('tk_butDown', self._w)
+ def tk_butUp(self):
+ self.tk.call('tk_butUp', self._w)
+ def flash(self):
+ self.tk.call(self._w, 'flash')
+ def invoke(self):
+ self.tk.call(self._w, 'invoke')
+
+# Indices:
+def AtEnd():
+ return 'end'
+def AtInsert():
+ return 'insert'
+def AtSelFirst():
+ return 'sel.first'
+def AtSelLast():
+ return 'sel.last'
+def At(x, y=None):
+ if y:
+ return '@' + `x` + ',' + `y`
+ else:
+ return '@' + `x`
+
+class Canvas(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'canvas', cnf)
+ def addtag(self, *args):
+ self._do('addtag', args)
+ def bbox(self, *args):
+ return self._getints(self._do('bbox', args))
+ def bind(self, tagOrId, sequence, func, add=''):
+ global _substitute, _subst_prefix
+ if add: add='+'
+ name = self._register(func, _substitute)
+ self.tk.call(self._w, 'bind', tagOrId, sequence,
+ (add + name,) + _subst_prefix)
+ def canvasx(self, screenx, gridspacing=None):
+ return self.tk.getint(self.tk.call(
+ self._w, 'canvasx', screenx, gridspacing))
+ def canvasy(self, screeny, gridspacing=None):
+ return self.tk.getint(self.tk.call(
+ self._w, 'canvasy', screeny, gridspacing))
+ def coords(self, *args):
+ return self._do('coords', args)
+ def _create(self, itemType, args): # Args: (value, value, ..., cnf={})
+ cnf = args[-1]
+ if type(cnf) == type({}):
+ args = args[:-1]
+ else:
+ cnf = {}
+ v = (self._w, 'create', itemType) + args
+ for k in cnf.keys():
+ v = v + ('-' + k, cnf[k])
+ return self.tk.getint(apply(self.tk.call, v))
+ def create_arc(self, *args):
+ Canvas._create(self, 'arc', args)
+ def create_bitmap(self, *args):
+ Canvas._create(self, 'bitmap', args)
+ def create_line(self, *args):
+ Canvas._create(self, 'line', args)
+ def create_oval(self, *args):
+ Canvas._create(self, 'oval', args)
+ def create_polygon(self, *args):
+ Canvas._create(self, 'polygon', args)
+ def create_rectangle(self, *args):
+ Canvas._create(self, 'rectangle', args)
+ def create_text(self, *args):
+ Canvas._create(self, 'text', args)
+ def create_window(self, *args):
+ Canvas._create(self, 'window', args)
+ def dchars(self, *args):
+ self._do('dchars', args)
+ def delete(self, *args):
+ self._do('delete', args)
+ def dtag(self, *args):
+ self._do('dtag', args)
+ def find(self, *args):
+ self.tk.splitlist(self._do('find', args))
+ def focus(self, *args):
+ return self._do('focus', args)
+ def gettags(self, *args):
+ return self.tk.splitlist(self._do('gettags', args))
+ def icursor(self, *args):
+ self._do('icursor', args)
+ def index(self, *args):
+ return self.tk.getint(self._do('index', args))
+ def insert(self, *args):
+ self._do('insert', args)
+ def itemconfig(self, tagOrId, cnf={}):
+ self._do('itemconfigure', (tagOrId,) + self._options(cnf))
+ def lower(self, *args):
+ self._do('lower', args)
+ def move(self, *args):
+ self._do('move', args)
+ def postscript(self, cnf={}):
+ return self._do('postscript', self._options(cnf))
+ def tkraise(self, *args):
+ self._do('raise', args)
+ def scale(self, *args):
+ self._do('scale', args)
+ def scan_mark(self, x, y):
+ self.tk.call(self._w, 'scan', 'mark', x, y)
+ def scan_dragto(self, x, y):
+ self.tk.call(self._w, 'scan', 'dragto', x, y)
+ def select_adjust(self, tagOrId, index):
+ self.tk.call(
+ self._w, 'select', 'adjust', tagOrId, index)
+ def select_clear(self):
+ self.tk.call(self._w, 'select', 'clear')
+ def select_from(self, tagOrId, index):
+ self.tk.call(
+ self._w, 'select', 'from', tagOrId, index)
+ def select_item(self):
+ self.tk.call(self._w, 'select', 'item')
+ def select_to(self, tagOrId, index):
+ self.tk.call(
+ self._w, 'select', 'to', tagOrId, index)
+ def type(self, tagOrId):
+ return self.tk.splitlist(self.tk.call(
+ self._w, 'type', tagOrId))
+ def xview(self, index):
+ self.tk.call(self._w, 'xview', index)
+ def yview(self, index):
+ self.tk.call(self._w, 'yview', index)
+
+class Checkbutton(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'checkbutton', cnf)
+ def deselect(self):
+ self.tk.call(self._w, 'deselect')
+ def flash(self):
+ self.tk.call(self._w, 'flash')
+ def invoke(self):
+ self.tk.call(self._w, 'invoke')
+ def select(self):
+ self.tk.call(self._w, 'select')
+ def toggle(self):
+ self.tk.call(self._w, 'toggle')
+
+class Entry(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'entry', cnf)
+ def tk_entryBackspace(self):
+ self.tk.call('tk_entryBackspace', self._w)
+ def tk_entryBackword(self):
+ self.tk.call('tk_entryBackword', self._w)
+ def tk_entrySeeCaret(self):
+ self.tk.call('tk_entrySeeCaret', self._w)
+ def delete(self, first, last=None):
+ self.tk.call(self._w, 'delete', first, last)
+ def get(self):
+ return self.tk.call(self._w, 'get')
+ def icursor(self, index):
+ self.tk.call(self._w, 'icursor', index)
+ def index(self, index):
+ return self.tk.getint(self.tk.call(
+ self._w, 'index', index))
+ def insert(self, index, string):
+ self.tk.call(self._w, 'insert', index, string)
+ def scan_mark(self, x):
+ self.tk.call(self._w, 'scan', 'mark', x)
+ def scan_dragto(self, x):
+ self.tk.call(self._w, 'scan', 'dragto', x)
+ def select_adjust(self, index):
+ self.tk.call(self._w, 'select', 'adjust', index)
+ def select_clear(self):
+ self.tk.call(self._w, 'select', 'clear')
+ def select_from(self, index):
+ self.tk.call(self._w, 'select', 'from', index)
+ def select_to(self, index):
+ self.tk.call(self._w, 'select', 'to', index)
+ def select_view(self, index):
+ self.tk.call(self._w, 'select', 'view', index)
+
+class Frame(Widget):
+ def __init__(self, master=None, cnf={}):
+ extra = ()
+ if cnf.has_key('class'):
+ extra = ('-class', cnf['class'])
+ del cnf['class']
+ Widget.__init__(self, master, 'frame', cnf, extra)
+ def tk_menuBar(self, *args):
+ apply(self.tk.call, ('tk_menuBar', self._w) + args)
+
+class Label(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'label', cnf)
+
+class Listbox(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'listbox', cnf)
+ def tk_listboxSingleSelect(self):
+ self.tk.call('tk_listboxSingleSelect', self._w)
+ def curselection(self):
+ return self.tk.splitlist(self.tk.call(
+ self._w, 'curselection'))
+ def delete(self, first, last=None):
+ self.tk.call(self._w, 'delete', first, last)
+ def get(self, index):
+ return self.tk.call(self._w, 'get', index)
+ def insert(self, index, *elements):
+ apply(self.tk.call,
+ (self._w, 'insert', index) + elements)
+ def nearest(self, y):
+ return self.tk.getint(self.tk.call(
+ self._w, 'nearest', y))
+ def scan_mark(self, x, y):
+ self.tk.call(self._w, 'scan', 'mark', x, y)
+ def scan_dragto(self, x, y):
+ self.tk.call(self._w, 'scan', 'dragto', x, y)
+ def select_adjust(self, index):
+ self.tk.call(self._w, 'select', 'adjust', index)
+ def select_clear(self):
+ self.tk.call(self._w, 'select', 'clear')
+ def select_from(self, index):
+ self.tk.call(self._w, 'select', 'from', index)
+ def select_to(self, index):
+ self.tk.call(self._w, 'select', 'to', index)
+ def size(self):
+ return self.tk.getint(self.tk.call(self._w, 'size'))
+ def xview(self, index):
+ self.tk.call(self._w, 'xview', index)
+ def yview(self, index):
+ self.tk.call(self._w, 'yview', index)
+
+class Menu(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'menu', cnf)
+ def tk_menuBar(self, *args):
+ apply(self.tk.call, ('tk_menuBar', self._w) + args)
+ def tk_bindForTraversal(self):
+ self.tk.call('tk_bindForTraversal', self._w)
+ def tk_mbPost(self):
+ self.tk.call('tk_mbPost', self._w)
+ def tk_mbUnpost(self):
+ self.tk.call('tk_mbUnpost')
+ def tk_traverseToMenu(self, char):
+ self.tk.call('tk_traverseToMenu', self._w, char)
+ def tk_traverseWithinMenu(self, char):
+ self.tk.call('tk_traverseWithinMenu', self._w, char)
+ def tk_getMenuButtons(self):
+ return self.tk.call('tk_getMenuButtons', self._w)
+ def tk_nextMenu(self, count):
+ self.tk.call('tk_nextMenu', count)
+ def tk_nextMenuEntry(self, count):
+ self.tk.call('tk_nextMenuEntry', count)
+ def tk_invokeMenu(self):
+ self.tk.call('tk_invokeMenu', self._w)
+ def tk_firstMenu(self):
+ self.tk.call('tk_firstMenu', self._w)
+ def tk_mbButtonDown(self):
+ self.tk.call('tk_mbButtonDown', self._w)
+ def activate(self, index):
+ self.tk.call(self._w, 'activate', index)
+ def add(self, itemType, cnf={}):
+ apply(self.tk.call, (self._w, 'add', itemType)
+ + self._options(cnf))
+ def delete(self, index1, index2=None):
+ self.tk.call(self._w, 'delete', index1, index2)
+ def entryconfig(self, index, cnf={}):
+ apply(self.tk.call, (self._w, 'entryconfigure', index)
+ + self._options(cnf))
+ def index(self, index):
+ return self.tk.call(self._w, 'index', index)
+ def invoke(self, index):
+ return self.tk.call(self._w, 'invoke', index)
+ def post(self, x, y):
+ self.tk.call(self._w, 'post', x, y)
+ def unpost(self):
+ self.tk.call(self._w, 'unpost')
+ def yposition(self, index):
+ return self.tk.getint(self.tk.call(
+ self._w, 'yposition', index))
+
+class Menubutton(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'menubutton', cnf)
+
+class Message(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'message', cnf)
+
+class Radiobutton(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'radiobutton', cnf)
+ def deselect(self):
+ self.tk.call(self._w, 'deselect')
+ def flash(self):
+ self.tk.call(self._w, 'flash')
+ def invoke(self):
+ self.tk.call(self._w, 'invoke')
+ def select(self):
+ self.tk.call(self._w, 'select')
+
+class Scale(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'scale', cnf)
+ def get(self):
+ return self.tk.getint(self.tk.call(self._w, 'get'))
+ def set(self, value):
+ self.tk.call(self._w, 'set', value)
+
+class Scrollbar(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'scrollbar', cnf)
+ def get(self):
+ return self.tk.getints(self.tk.call(self._w, 'get'))
+ def set(self, totalUnits, windowUnits, firstUnit, lastUnit):
+ self.tk.call(self._w, 'set',
+ totalUnits, windowUnits, firstUnit, lastUnit)
+
+class Text(Widget):
+ def __init__(self, master=None, cnf={}):
+ Widget.__init__(self, master, 'text', cnf)
+ def tk_textSelectTo(self, index):
+ self.tk.call('tk_textSelectTo', self._w, index)
+ def tk_textBackspace(self):
+ self.tk.call('tk_textBackspace', self._w)
+ def tk_textIndexCloser(self, a, b, c):
+ self.tk.call('tk_textIndexCloser', self._w, a, b, c)
+ def tk_textResetAnchor(self, index):
+ self.tk.call('tk_textResetAnchor', self._w, index)
+ def compare(self, index1, op, index2):
+ return self.tk.getboolean(self.tk.call(
+ self._w, 'compare', index1, op, index2))
+ def debug(self, boolean=None):
+ return self.tk.getboolean(self.tk.call(
+ self._w, 'debug', boolean))
+ def delete(self, index1, index2=None):
+ self.tk.call(self._w, 'delete', index1, index2)
+ def get(self, index1, index2=None):
+ return self.tk.call(self._w, 'get', index1, index2)
+ def index(self, index):
+ return self.tk.call(self._w, 'index', index)
+ def insert(self, index, chars):
+ self.tk.call(self._w, 'insert', index, chars)
+ def mark_names(self):
+ return self.tk.splitlist(self.tk.call(
+ self._w, 'mark', 'names'))
+ def mark_set(self, markName, index):
+ self.tk.call(self._w, 'mark', 'set', markName, index)
+ def mark_unset(self, markNames):
+ apply(self.tk.call, (self._w, 'mark', 'unset') + markNames)
+ def scan_mark(self, y):
+ self.tk.call(self._w, 'scan', 'mark', y)
+ def scan_dragto(self, y):
+ self.tk.call(self._w, 'scan', 'dragto', y)
+ def tag_add(self, tagName, index1, index2=None):
+ self.tk.call(
+ self._w, 'tag', 'add', tagName, index1, index2)
+ def tag_bind(self, tagName, sequence, func, add=''):
+ global _substitute, _subst_prefix
+ if add: add='+'
+ name = self._register(func, _substitute)
+ self.tk.call(self._w, 'tag', 'bind',
+ tagName, sequence,
+ (add + name,) + _subst_prefix)
+ def tag_config(self, tagName, cnf={}):
+ apply(self.tk.call,
+ (self._w, 'tag', 'configure', tagName)
+ + self._options(cnf))
+ def tag_delete(self, tagNames):
+ apply(self.tk.call, (self._w, 'tag', 'delete')
+ + tagNames)
+ def tag_lower(self, tagName, belowThis=None):
+ self.tk.call(self._w, 'tag', 'lower',
+ tagName, belowThis)
+ def tag_names(self, index=None):
+ return self.tk.splitlist(
+ self.tk.call(self._w, 'tag', 'names', index))
+ def tag_nextrange(self, tagName, index1, index2=None):
+ return self.tk.splitlist(self.tk.call(
+ self._w, 'tag', 'nextrange', index1, index2))
+ def tag_raise(self, tagName, aboveThis=None):
+ self.tk.call(
+ self._w, 'tag', 'raise', tagName, aboveThis)
+ def tag_ranges(self, tagName):
+ return self.tk.splitlist(self.tk.call(
+ self._w, 'tag', 'ranges', tagName))
+ def tag_remove(self, tagName, index1, index2=None):
+ self.tk.call(
+ self._w, 'tag', 'remove', index1, index2)
+ def yview(self, what):
+ self.tk.call(self._w, 'yview', what)
+ def yview_pickplace(self, what):
+ self.tk.call(self._w, 'yview', '-pickplace', what)
+
+#class Dialog:
+
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
new file mode 100644
index 0000000..2bb7060
--- /dev/null
+++ b/Modules/_tkinter.c
@@ -0,0 +1,1056 @@
+/* tkintermodule.c -- Interface to libtk.a and libtcl.a.
+ Copyright (C) 1994 Steen Lumholt */
+
+#if 0
+#include <Py/Python.h>
+#else
+
+#include "allobjects.h"
+#include "pythonrun.h"
+#include "intrcheck.h"
+#include "modsupport.h"
+#include "sysmodule.h"
+
+#define PyObject object
+typedef struct methodlist PyMethodDef;
+#define PyInit_tkinter inittkinter
+
+#undef Py_True
+#define Py_True ((object *) &TrueObject)
+#undef True
+
+#undef Py_False
+#define Py_False ((object *) &FalseObject)
+#undef False
+
+#undef Py_None
+#define Py_None (&NoObject)
+#undef None
+
+#endif /* 0 */
+
+#include <tcl.h>
+#include <tk.h>
+
+extern char *getprogramname ();
+extern int tk_NumMainWindows;
+
+/**** Tkapp Object Declaration ****/
+
+staticforward PyTypeObject Tkapp_Type;
+
+typedef struct
+ {
+ PyObject_HEAD
+ Tcl_Interp *interp;
+ Tk_Window tkwin;
+ }
+TkappObject;
+
+#define Tkapp_Check(v) ((v)->ob_type == &Tkapp_Type)
+#define Tkapp_Tkwin(v) (((TkappObject *) (v))->tkwin)
+#define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
+#define Tkapp_Result(v) (((TkappObject *) (v))->interp->result)
+
+#define DEBUG_REFCNT(v) (printf ("DEBUG: id=%p, refcnt=%i\n", \
+ (void *) v, ((PyObject *) v)->ob_refcnt))
+
+/**** Error Handling ****/
+
+static PyObject *Tkinter_TclError;
+static int errorInCmd = 0;
+static PyObject *excInCmd;
+static PyObject *valInCmd;
+
+static PyObject *
+Tkinter_Error (v)
+ PyObject *v;
+{
+ if (Tkapp_Check (v))
+ PyErr_BadInternalCall ();
+ PyErr_SetString (Tkinter_TclError, Tkapp_Result (v));
+ return NULL;
+}
+
+int
+PythonCmd_Error (interp)
+ Tcl_Interp *interp;
+{
+ errorInCmd = 1;
+ PyErr_GetAndClear (&excInCmd, &valInCmd);
+ return TCL_ERROR;
+}
+
+/**** Utils ****/
+
+static char *
+AsString (value, tmp)
+ PyObject *value;
+ PyObject *tmp;
+{
+ if (PyString_Check (value))
+ return PyString_AsString (value);
+ else
+ {
+ PyObject *v;
+
+ v = strobject (value);
+ PyList_Append (tmp, v);
+ Py_DECREF (v);
+ return PyString_AsString (v);
+ }
+}
+
+#define ARGSZ 64
+
+static char *
+Merge (args)
+ PyObject *args;
+{
+ PyObject *tmp;
+ char *argvStore[ARGSZ];
+ char **argv;
+ int fvStore[ARGSZ];
+ int *fv;
+ int argc;
+ char *res;
+ int i;
+
+ tmp = PyList_New (0);
+ argv = argvStore;
+ fv = fvStore;
+
+ if (!PyTuple_Check (args))
+ {
+ argc = 1;
+ fv[0] = 0;
+ argv[0] = AsString (args, tmp);
+ }
+ else
+ {
+ PyObject *v;
+
+ if (PyTuple_Size (args) > ARGSZ)
+ {
+ argv = malloc (PyTuple_Size (args) * sizeof (char *));
+ fv = malloc (PyTuple_Size (args) * sizeof (int));
+ if (argv == NULL || fv == NULL)
+ PyErr_NoMemory ();
+ }
+
+ argc = PyTuple_Size (args);
+ for (i = 0; i < argc; i++)
+ {
+ v = PyTuple_GetItem (args, i);
+ if (PyTuple_Check (v))
+ {
+ fv[i] = 1;
+ argv[i] = Merge (v);
+ }
+ else if (v == Py_None)
+ {
+ argc = i;
+ break;
+ }
+ else
+ {
+ fv[i] = 0;
+ argv[i] = AsString (v, tmp);
+ }
+ }
+ }
+
+ res = Tcl_Merge (argc, argv);
+
+ Py_DECREF (tmp);
+ for (i = 0; i < argc; i++)
+ if (fv[i]) free (argv[i]);
+ if (argv != argvStore)
+ free (argv);
+ if (fv != fvStore)
+ free (fv);
+
+ return res;
+}
+
+static PyObject *
+Split (self, list)
+ PyObject *self;
+ char *list;
+{
+ int argc;
+ char **argv;
+ PyObject *v;
+
+ if (list == NULL)
+ {
+ Py_INCREF (Py_None);
+ return Py_None;
+ }
+
+ if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
+ return Tkinter_Error (self);
+
+ if (argc == 0)
+ v = PyString_FromString ("");
+ else if (argc == 1)
+ v = PyString_FromString (argv[0]);
+ else
+ {
+ int i;
+
+ v = PyTuple_New (argc);
+ for (i = 0; i < argc; i++)
+ PyTuple_SetItem (v, i, Split (self, argv[i]));
+ }
+
+ free (argv);
+ return v;
+}
+
+/**** Tkapp Object ****/
+
+#ifndef WITH_APPINIT
+int
+Tcl_AppInit (interp)
+ Tcl_Interp *interp;
+{
+ if (Tcl_Init (interp) == TCL_ERROR)
+ return TCL_ERROR;
+ if (Tk_Init (interp) == TCL_ERROR)
+ return TCL_ERROR;
+ return TCL_OK;
+}
+#endif /* !WITH_APPINIT */
+
+/* Initialize the Tk application; see the `main' function in
+ `tkMain.c'. */
+static TkappObject *
+Tkapp_New (screenName, baseName, className, interactive)
+ char *screenName;
+ char *baseName;
+ char *className;
+ int interactive;
+{
+ TkappObject *v;
+
+ v = PyObject_NEW (TkappObject, &Tkapp_Type);
+ if (v == NULL)
+ return NULL;
+
+ v->interp = Tcl_CreateInterp ();
+ v->tkwin = Tk_CreateMainWindow (v->interp, screenName,
+ baseName, className);
+ if (v->tkwin == NULL)
+ return (TkappObject *) Tkinter_Error ((PyObject *) v);
+
+ Tk_GeometryRequest (v->tkwin, 200, 200);
+
+ if (screenName != NULL)
+ Tcl_SetVar2 (v->interp, "env", "DISPLAY", screenName, TCL_GLOBAL_ONLY);
+
+ if (interactive)
+ Tcl_SetVar (v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
+ else
+ Tcl_SetVar (v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
+
+#ifndef WITH_APPINIT
+ if (Tcl_AppInit (v->interp) != TCL_OK)
+ {
+ PyErr_SetString (Tkinter_TclError, "Tcl_AppInit failed"); /* XXX */
+ return NULL;
+ }
+#endif /* !WITH_APPINIT */
+
+ return v;
+}
+
+/** Tcl Eval **/
+
+static PyObject *
+Tkapp_Call (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *cmd;
+
+ cmd = Merge (args);
+ if (Tcl_Eval (Tkapp_Interp (self), cmd) == TCL_ERROR)
+ {
+ free (cmd);
+ return Tkinter_Error (self);
+ }
+
+ free (cmd);
+ return PyString_FromString (Tkapp_Result (self));
+}
+
+static PyObject *
+Tkapp_GlobalCall (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *cmd;
+
+ cmd = Merge (args);
+ if (Tcl_GlobalEval (Tkapp_Interp (self), cmd) == TCL_ERROR)
+ {
+ free (cmd);
+ return Tkinter_Error (self);
+ }
+
+ free (cmd);
+ return PyString_FromString (Tkapp_Result (self));
+}
+
+static PyObject *
+Tkapp_Eval (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *script;
+
+ if (!PyArg_Parse (args, "s", &script))
+ return NULL;
+
+ if (Tcl_Eval (Tkapp_Interp (self), script) == TCL_ERROR)
+ return Tkinter_Error (self);
+
+ return PyString_FromString (Tkapp_Result (self));
+}
+
+static PyObject *
+Tkapp_GlobalEval (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *script;
+
+ if (!PyArg_Parse (args, "s", &script))
+ return NULL;
+
+ if (Tcl_GlobalEval (Tkapp_Interp (self), script) == TCL_ERROR)
+ return Tkinter_Error (self);
+
+ return PyString_FromString (Tkapp_Result (self));
+}
+
+static PyObject *
+Tkapp_EvalFile (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *fileName;
+
+ if (!PyArg_Parse (args, "s", &fileName))
+ return NULL;
+
+ if (Tcl_EvalFile (Tkapp_Interp (self), fileName) == TCL_ERROR)
+ return Tkinter_Error (self);
+
+ return PyString_FromString (Tkapp_Result (self));
+}
+
+static PyObject *
+Tkapp_Record (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *script;
+
+ if (!PyArg_Parse (args, "s", &script))
+ return NULL;
+
+ if (Tcl_RecordAndEval (Tkapp_Interp (self),
+ script, TCL_NO_EVAL) == TCL_ERROR)
+ return Tkinter_Error (self);
+
+ return PyString_FromString (Tkapp_Result (self));
+}
+
+static PyObject *
+Tkapp_AddErrorInfo (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *msg;
+
+ if (!PyArg_Parse (args, "s", &msg))
+ return NULL;
+ Tcl_AddErrorInfo (Tkapp_Interp (self), msg);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/** Tcl Variable **/
+
+static PyObject *
+SetVar (self, args, flags)
+ PyObject *self;
+ PyObject *args;
+ int flags;
+{
+ char *name1, *name2, *ok;
+ PyObject *newValue;
+ PyObject *tmp;
+
+ tmp = PyList_New (0);
+
+ if (PyArg_Parse (args, "(sO)", &name1, &newValue))
+ ok = Tcl_SetVar (Tkapp_Interp (self), name1,
+ AsString (newValue, tmp), flags); /* XXX Merge? */
+ else if (PyArg_Parse (args, "(ssO)", &name1, &name2, &newValue))
+ ok = Tcl_SetVar2 (Tkapp_Interp (self), name1, name2,
+ AsString (newValue, tmp), flags);
+ else
+ {
+ Py_DECREF (tmp);
+ return NULL;
+ }
+ Py_DECREF (tmp);
+
+ if (!ok)
+ return Tkinter_Error (self);
+
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+static PyObject *
+Tkapp_SetVar (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ return SetVar (self, args, TCL_LEAVE_ERR_MSG);
+}
+
+static PyObject *
+Tkapp_GlobalSetVar (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ return SetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+}
+
+static PyObject *
+GetVar (self, args, flags)
+ PyObject *self;
+ PyObject *args;
+ int flags;
+{
+ char *name1, *name2, *s;
+
+ if (PyArg_Parse (args, "s", &name1))
+ s = Tcl_GetVar (Tkapp_Interp (self), name1, flags);
+ else if (PyArg_Parse (args, "(ss)", &name1, &name2))
+ s = Tcl_GetVar2 (Tkapp_Interp (self), name1, name2, flags);
+ else
+ return NULL;
+
+ if (s == NULL)
+ return Tkinter_Error (self);
+
+ return PyString_FromString (s);
+}
+
+static PyObject *
+Tkapp_GetVar (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ return GetVar (self, args, TCL_LEAVE_ERR_MSG);
+}
+
+static PyObject *
+Tkapp_GlobalGetVar (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ return GetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+}
+
+static PyObject *
+UnsetVar (self, args, flags)
+ PyObject *self;
+ PyObject *args;
+ int flags;
+{
+ char *name1, *name2;
+ int code;
+
+ if (PyArg_Parse (args, "s", &name1))
+ code = Tcl_UnsetVar (Tkapp_Interp (self), name1, flags);
+ else if (PyArg_Parse (args, "(ss)", &name1, &name2))
+ code = Tcl_UnsetVar2 (Tkapp_Interp (self), name1, name2, flags);
+ else
+ return NULL;
+
+ if (code == TCL_ERROR)
+ return Tkinter_Error (self);
+
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+static PyObject *
+Tkapp_UnsetVar (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ return UnsetVar (self, args, TCL_LEAVE_ERR_MSG);
+}
+
+static PyObject *
+Tkapp_GlobalUnsetVar (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ return UnsetVar (self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+}
+
+/** Tcl to Python **/
+
+static PyObject *
+Tkapp_GetInt (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *s;
+ int v;
+
+ if (!PyArg_Parse (args, "s", &s))
+ return NULL;
+ if (Tcl_GetInt (Tkapp_Interp (self), s, &v) == TCL_ERROR)
+ return Tkinter_Error (self);
+ return Py_BuildValue ("i", v);
+}
+
+static PyObject *
+Tkapp_GetDouble (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *s;
+ double v;
+
+ if (!PyArg_Parse (args, "s", &s))
+ return NULL;
+ if (Tcl_GetDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
+ return Tkinter_Error (self);
+ return Py_BuildValue ("d", v);
+}
+
+static PyObject *
+Tkapp_GetBoolean (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *s;
+ int v;
+
+ if (!PyArg_Parse (args, "s", &s))
+ return NULL;
+ if (Tcl_GetBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
+ return Tkinter_Error (self);
+ return Py_BuildValue ("i", v);
+}
+
+static PyObject *
+Tkapp_ExprString (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *s;
+
+ if (!PyArg_Parse (args, "s", &s))
+ return NULL;
+ if (Tcl_ExprString (Tkapp_Interp (self), s) == TCL_ERROR)
+ return Tkinter_Error (self);
+ return Py_BuildValue ("s", Tkapp_Result (self));
+}
+
+static PyObject *
+Tkapp_ExprLong (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *s;
+ long v;
+
+ if (!PyArg_Parse (args, "s", &s))
+ return NULL;
+ if (Tcl_ExprLong (Tkapp_Interp (self), s, &v) == TCL_ERROR)
+ return Tkinter_Error (self);
+ return Py_BuildValue ("l", v);
+}
+
+static PyObject *
+Tkapp_ExprDouble (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *s;
+ double v;
+
+ if (!PyArg_Parse (args, "s", &s))
+ return NULL;
+ if (Tcl_ExprDouble (Tkapp_Interp (self), s, &v) == TCL_ERROR)
+ return Tkinter_Error (self);
+ return Py_BuildValue ("d", v);
+}
+
+static PyObject *
+Tkapp_ExprBoolean (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *s;
+ int v;
+
+ if (!PyArg_Parse (args, "s", &s))
+ return NULL;
+ if (Tcl_ExprBoolean (Tkapp_Interp (self), s, &v) == TCL_ERROR)
+ return Tkinter_Error (self);
+ return Py_BuildValue ("i", v);
+}
+
+static PyObject *
+Tkapp_SplitList (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *list;
+ int argc;
+ char **argv;
+ PyObject *v;
+ int i;
+
+ if (!PyArg_Parse (args, "s", &list))
+ return NULL;
+
+ if (Tcl_SplitList (Tkapp_Interp (self), list, &argc, &argv) == TCL_ERROR)
+ return Tkinter_Error (self);
+
+ v = PyTuple_New (argc);
+ for (i = 0; i < argc; i++)
+ PyTuple_SetItem (v, i, PyString_FromString (argv[i]));
+
+ free (argv);
+ return v;
+}
+
+static PyObject *
+Tkapp_Split (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *list;
+
+ if (!PyArg_Parse (args, "s", &list))
+ return NULL;
+ return Split (self, list);
+}
+
+static PyObject *
+Tkapp_Merge (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *s;
+ PyObject *v;
+
+ s = Merge (args);
+ v = PyString_FromString (s);
+ free (s);
+ return v;
+}
+
+/** Tcl Command **/
+
+/* This is the Tcl command that acts as a wrapper for Python
+ function or method. */
+static int
+PythonCmd (clientData, interp, argc, argv)
+ ClientData clientData; /* Is (self, func) */
+ Tcl_Interp *interp;
+ int argc;
+ char *argv[];
+{
+ PyObject *self, *func, *arg, *res, *tmp;
+ int i;
+
+ self = PyTuple_GetItem ((PyObject *) clientData, 0);
+ func = PyTuple_GetItem ((PyObject *) clientData, 1);
+
+ /* Create argument list (argv1, ..., argvN) */
+ arg = PyTuple_New (argc - 1);
+ for (i = 0; i < (argc - 1); i++)
+ PyTuple_SetItem (arg, i, PyString_FromString (argv[i + 1]));
+
+ res = PyEval_CallObject (func, arg);
+ Py_DECREF (arg);
+ if (res == NULL)
+ return PythonCmd_Error (interp);
+
+ tmp = PyList_New (0);
+ Tcl_SetResult (Tkapp_Interp (self), AsString (res, tmp), TCL_VOLATILE);
+ Py_DECREF (res);
+ Py_DECREF (tmp);
+
+ return TCL_OK;
+}
+
+static void
+PythonCmdDelete (clientData)
+ ClientData clientData; /* Is (self, func) */
+{
+ Py_DECREF ((PyObject *) clientData);
+}
+
+static PyObject *
+Tkapp_CreateCommand (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *cmdName;
+ PyObject *data;
+ PyObject *func;
+
+ /* Args is: (cmdName, func) */
+ if (!PyTuple_Check (args)
+ || !(PyTuple_Size (args) == 2)
+ || !PyString_Check (PyTuple_GetItem (args, 0))
+ || !(PyMethod_Check (PyTuple_GetItem (args, 1))
+ || PyFunction_Check (PyTuple_GetItem (args, 1))))
+ {
+ PyErr_SetString (PyExc_TypeError, "bad argument list");
+ return NULL;
+ }
+
+ cmdName = PyString_AsString (PyTuple_GetItem (args, 0));
+ func = PyTuple_GetItem (args, 1);
+
+ data = PyTuple_New (2); /* ClientData is: (self, func) */
+
+ Py_INCREF (self);
+ PyTuple_SetItem (data, 0, self);
+
+ Py_INCREF (func);
+ PyTuple_SetItem (data, 1, func);
+
+ Tcl_CreateCommand (Tkapp_Interp (self), cmdName, PythonCmd,
+ (ClientData) data, PythonCmdDelete);
+
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+static PyObject *
+Tkapp_DeleteCommand (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *cmdName;
+
+ if (!PyArg_Parse (args, "s", &cmdName))
+ return NULL;
+ if (Tcl_DeleteCommand (Tkapp_Interp (self), cmdName) == -1)
+ {
+ PyErr_SetString (Tkinter_TclError, "can't delete Tcl command");
+ return NULL;
+ }
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+/** File Handler **/
+
+void
+FileHandler (clientData, mask)
+ ClientData clientData; /* Is: func */
+ int mask;
+{
+ PyObject *func;
+ PyObject *arg, *res;
+
+ func = (PyObject *) clientData;
+
+ arg = PyInt_FromLong ((long) mask);
+ res = PyEval_CallObject (func, arg);
+ Py_DECREF (arg);
+ if (res == NULL)
+ {
+ errorInCmd = 1;
+ PyErr_GetAndClear (&excInCmd, &valInCmd);
+ }
+}
+
+static PyObject *
+Tkapp_CreateFileHandler (self, args)
+ PyObject *self;
+ PyObject *args; /* Is (file, mask, func) */
+{
+ PyObject *file;
+ int mask;
+ PyObject *func;
+ int id;
+
+ if (!PyArg_Parse (args, "(OiO)", &file, &mask, &func))
+ return NULL;
+ if (!PyFile_Check (file)
+ || !(PyMethod_Check(func) || PyFunction_Check(func)))
+ {
+ PyErr_SetString (PyExc_TypeError, "bad argument list");
+ return NULL;
+ }
+
+ id = fileno (PyFile_AsFile (file));
+ Py_DECREF (file);
+ Tk_CreateFileHandler (id, mask, FileHandler, (ClientData) func);
+ /* XXX fileHandlerDict */
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+static PyObject *
+Tkapp_DeleteFileHandler (self, args)
+ PyObject *self;
+ PyObject *args; /* Args: file */
+{
+ int id;
+
+ if (!PyFile_Check (args))
+ {
+ PyErr_SetString (PyExc_TypeError, "bad argument list");
+ return NULL;
+ }
+
+ id = fileno (PyFile_AsFile (args));
+ Tk_DeleteFileHandler (id);
+ /* XXX fileHandlerDict */
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+/** Event Loop **/
+
+static int quitMainLoop;
+
+static PyObject *
+Tkapp_MainLoop (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ if (!PyArg_Parse (args, ""))
+ return NULL;
+
+ quitMainLoop = 0;
+ while (tk_NumMainWindows > 0 && !quitMainLoop && !errorInCmd)
+ {
+ if (PyOS_InterruptOccurred ())
+ {
+ PyErr_SetNone (PyExc_KeyboardInterrupt);
+ return NULL;
+ }
+ Tk_DoOneEvent (0);
+ }
+
+ if (errorInCmd)
+ {
+ errorInCmd = 0;
+ PyErr_SetObject (excInCmd, valInCmd);
+ return NULL;
+ }
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+static PyObject *
+Tkapp_Quit (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+
+ if (!PyArg_Parse (args, ""))
+ return NULL;
+ quitMainLoop = 1;
+ Py_INCREF (Py_None);
+ return Py_None;
+}
+
+/**** Tkapp Method List ****/
+
+static PyMethodDef Tkapp_methods[] =
+{
+ {"call", Tkapp_Call},
+ {"globalcall", Tkapp_GlobalCall},
+ {"eval", Tkapp_Eval},
+ {"globaleval", Tkapp_GlobalEval},
+ {"evalfile", Tkapp_EvalFile},
+ {"record", Tkapp_Record},
+ {"adderrorinfo", Tkapp_AddErrorInfo},
+ {"setvar", Tkapp_SetVar},
+ {"globalsetvar", Tkapp_GlobalSetVar},
+ {"getvar", Tkapp_GetVar},
+ {"globalgetvar", Tkapp_GlobalGetVar},
+ {"unsetvar", Tkapp_UnsetVar},
+ {"globalunsetvar", Tkapp_GlobalUnsetVar},
+ {"getint", Tkapp_GetInt},
+ {"getdouble", Tkapp_GetDouble},
+ {"getboolean", Tkapp_GetBoolean},
+ {"exprstring", Tkapp_ExprString},
+ {"exprlong", Tkapp_ExprLong},
+ {"exprdouble", Tkapp_ExprDouble},
+ {"exprboolean", Tkapp_ExprBoolean},
+ {"splitlist", Tkapp_SplitList},
+ {"split", Tkapp_Split},
+ {"merge", Tkapp_Merge},
+ {"createcommand", Tkapp_CreateCommand},
+ {"deletecommand", Tkapp_DeleteCommand},
+ {"createfilehandler", Tkapp_CreateFileHandler},
+ {"deletefilehandler", Tkapp_DeleteFileHandler},
+ {"mainloop", Tkapp_MainLoop},
+ {"quit", Tkapp_Quit},
+ {NULL, NULL}
+};
+
+/**** Tkapp Type Methods ****/
+
+static void
+Tkapp_Dealloc (self)
+ PyObject *self;
+{
+ Tk_DestroyWindow (Tkapp_Tkwin (self));
+ Tcl_DeleteInterp (Tkapp_Interp (self));
+ PyMem_DEL (self);
+}
+
+static PyObject *
+Tkapp_GetAttr (self, name)
+ PyObject *self;
+ char *name;
+{
+ return Py_FindMethod (Tkapp_methods, self, name);
+}
+
+static PyTypeObject Tkapp_Type =
+{
+ OB_HEAD_INIT (&PyType_Type)
+ 0, /*ob_size */
+ "tkapp", /*tp_name */
+ sizeof (TkappObject), /*tp_basicsize */
+ 0, /*tp_itemsize */
+ Tkapp_Dealloc, /*tp_dealloc */
+ 0, /*tp_print */
+ Tkapp_GetAttr, /*tp_getattr */
+ 0, /*tp_setattr */
+ 0, /*tp_compare */
+ 0, /*tp_repr */
+ 0, /*tp_as_number */
+ 0, /*tp_as_sequence */
+ 0, /*tp_as_mapping */
+ 0, /*tp_hash */
+};
+
+/**** Tkinter Module ****/
+
+static PyObject *
+Tkinter_Create (self, args)
+ PyObject *self;
+ PyObject *args;
+{
+ char *screenName = NULL;
+ char *baseName;
+ char *className;
+ int interactive = 0;
+
+ baseName = strrchr (getprogramname (), '/');
+ if (baseName != NULL)
+ baseName++;
+ else
+ baseName = getprogramname ();
+ className = "Tk";
+
+ if (PyArg_Parse (args, ""))
+ /* VOID */ ;
+ else if (PyArg_Parse (args, "z",
+ &screenName))
+ /* VOID */ ;
+ else if (PyArg_Parse (args, "(zs)",
+ &screenName, &baseName))
+ /* VOID */ ;
+ else if (PyArg_Parse (args, "(zss)",
+ &screenName, &baseName, &className))
+ /* VOID */ ;
+ else if (PyArg_Parse (args, "(zssi)",
+ &screenName, &baseName, &className, &interactive))
+ /* VOID */ ;
+ else
+ return NULL;
+
+ return (PyObject *) Tkapp_New (screenName, baseName, className,
+ interactive);
+}
+
+static PyMethodDef moduleMethods[] =
+{
+ {"create", Tkinter_Create},
+ {NULL, NULL}
+};
+
+#ifdef WITH_READLINE
+static int
+EventHook ()
+{
+ if (errorInCmd) /* XXX Reset tty */
+ {
+ errorInCmd = 0;
+ PyErr_SetObject (excInCmd, valInCmd);
+ PyErr_Print ();
+ }
+ if (tk_NumMainWindows > 0)
+ Tk_DoOneEvent (0);
+ return 0;
+}
+#endif /* WITH_READLINE */
+
+static void
+StdinProc (clientData, mask)
+ ClientData clientData;
+ int mask;
+{
+ /* Do nothing. */
+}
+
+void
+PyInit_tkinter ()
+{
+#ifdef WITH_READLINE
+ extern int (*rl_event_hook) ();
+#endif /* WITH_READLINE */
+ PyObject *m, *d, *v;
+
+ m = Py_InitModule ("tkinter", moduleMethods);
+
+ d = PyModule_GetDict (m);
+ Tkinter_TclError = Py_BuildValue ("s", "TclError");
+ PyDict_SetItemString (d, "TclError", Tkinter_TclError);
+
+ v = Py_BuildValue ("i", TK_READABLE);
+ PyDict_SetItemString (d, "READABLE", v);
+ v = Py_BuildValue ("i", TK_WRITABLE);
+ PyDict_SetItemString (d, "WRITABLE", v);
+ v = Py_BuildValue ("i", TK_EXCEPTION);
+ PyDict_SetItemString (d, "EXCEPTION", v);
+
+ /* Unblock stdin. */
+ Tk_CreateFileHandler (0, TK_READABLE, StdinProc, (ClientData) 0);
+
+#ifdef WITH_READLINE
+ rl_event_hook = EventHook;
+#endif /* WITH_READLINE */
+
+ if (PyErr_Occurred ())
+ Py_FatalError ("can't initialize module tkinter");
+}