From 1846882254324ac5eb0a96df493c7ab1eabd866e Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 20 Jun 1994 07:49:28 +0000 Subject: Initial revision --- Demo/tkinter/guido/MimeViewer.py | 143 ++++++ Demo/tkinter/guido/dialog.py | 119 +++++ Demo/tkinter/guido/mbox.py | 288 +++++++++++ Demo/tkinter/guido/rmt.py | 152 ++++++ Demo/tkinter/guido/tst.py | 81 +++ Demo/tkinter/guido/wish.py | 26 + Lib/lib-tk/Canvas.py | 115 +++++ Lib/lib-tk/ScrolledText.py | 35 ++ Lib/lib-tk/Tkinter.py | 874 +++++++++++++++++++++++++++++++ Lib/tkinter/Canvas.py | 115 +++++ Lib/tkinter/ScrolledText.py | 35 ++ Lib/tkinter/Tkinter.py | 874 +++++++++++++++++++++++++++++++ Modules/_tkinter.c | 1056 ++++++++++++++++++++++++++++++++++++++ 13 files changed, 3913 insertions(+) create mode 100755 Demo/tkinter/guido/MimeViewer.py create mode 100755 Demo/tkinter/guido/dialog.py create mode 100755 Demo/tkinter/guido/mbox.py create mode 100755 Demo/tkinter/guido/rmt.py create mode 100755 Demo/tkinter/guido/tst.py create mode 100755 Demo/tkinter/guido/wish.py create mode 100644 Lib/lib-tk/Canvas.py create mode 100644 Lib/lib-tk/ScrolledText.py create mode 100644 Lib/lib-tk/Tkinter.py create mode 100755 Lib/tkinter/Canvas.py create mode 100755 Lib/tkinter/ScrolledText.py create mode 100755 Lib/tkinter/Tkinter.py create mode 100644 Modules/_tkinter.c 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 , if there's a default, + # set a grab, and claim the focus too. + + if default >= 0: + w.bind('', + 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('', folder_unpost) + + folderbox['yscrollcommand'] = (folderbar, 'set') + folderbar['command'] = (folderbox, 'yview') + folderbox.bind('', open_folder, 1) + folderbox.bind('<3>', folder_post) + + # Build left part: scan list + + left = Frame(top) + left.pack({'expand': 1, 'fill': 'both', 'side': 'left'}) + + scanbar = Scrollbar(left, {'relief': 'sunken', 'bd': 2}) + scanbar.pack({'fill': 'y', 'side': 'right'}) + + scanbox = Listbox(left, {'font': 'fixed'}) + scanbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'}) + + scanmenu = Menu(root) + scanmenu.add('command', + {'label': 'Open Message', + 'command': open_message}) + scanmenu.add('command', + {'label': 'Remove Message', + 'command': remove_message}) + scanmenu.add('command', + {'label': 'Refile Message', + 'command': refile_message}) + scanmenu.add('separator') + scanmenu.add('command', + {'label': 'Quit', + 'command': 'exit'}) + scanmenu.bind('', scan_unpost) + + scanbox['yscrollcommand'] = (scanbar, 'set') + scanbar['command'] = (scanbox, 'yview') + scanbox.bind('', open_message) + scanbox.bind('<3>', scan_post) + + # Separator between middle and bottom part + + rule2 = Frame(root, {'bg': 'black'}) + rule2.pack({'fill': 'x'}) + + # Build bottom part: current message + + bot = Frame(root) + bot.pack({'expand': 1, 'fill': 'both'}) + # + viewer = None + + # Window manager commands + + root.minsize(800, 1) # Make window resizable + + # Fill folderbox with text + + setfolders() + + # Fill scanbox with text + + rescan() + + # Enter mainloop + + root.mainloop() + +def folder_post(e): + x, y = e.x_root, e.y_root + foldermenu.post(x - 10, y - 10) + foldermenu.grab_set() + +def folder_unpost(e): + tk.call('update', 'idletasks') + foldermenu.grab_release() + foldermenu.unpost() + foldermenu.invoke('active') + +def scan_post(e): + x, y = e.x_root, e.y_root + scanmenu.post(x - 10, y - 10) + scanmenu.grab_set() + +def scan_unpost(e): + tk.call('update', 'idletasks') + scanmenu.grab_release() + scanmenu.unpost() + scanmenu.invoke('active') + +scanparser = 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('', 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('', triple1) + +def returnkey(e): + t.insert('insert', '\n') + invoke() +t.bind('', returnkey) + +def controlv(e): + t.insert('insert', tk.call('selection', 'get')) + t.yview_pickplace('insert') + if t.index('insert')[-2:] == '.0': + invoke() +t.bind('', controlv) + +# 4. Procedure to backspace over one character, as long as +# the character isn't part of the prompt. + +def backspace(e): + if t.index('promptEnd') != t.index('insert - 1 char'): + t.delete('insert - 1 char', 'insert') + t.yview_pickplace('insert') +t.bind('', backspace) +t.bind('', backspace) +t.bind('', backspace) + + +# 5. Procedure that's invoked when return is typed: if +# there's not yet a complete command (e.g. braces are open) +# then do nothing. Otherwise, execute command (locally or +# remotely), output the result or error message, and issue +# a new prompt. + +def invoke(): + cmd = t.get('promptEnd + 1 char', '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', '', self.enter) + Canvas.bind(self, 'box', '', 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('', 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 +#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 +#include + +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"); +} -- cgit v0.12