Commit 62b1cd03 authored by Georg Brandl's avatar Georg Brandl

Work a bit more on tkinter demos.

parent 6aaa618d
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
from tkinter import * from tkinter import *
class Option: class Option:
varclass = StringVar # May be overridden varclass = StringVar # May be overridden
...@@ -45,6 +46,7 @@ class Option: ...@@ -45,6 +46,7 @@ class Option:
def set(self, e=None): # Should be overridden def set(self, e=None): # Should be overridden
pass pass
class BooleanOption(Option): class BooleanOption(Option):
varclass = BooleanVar varclass = BooleanVar
...@@ -60,6 +62,7 @@ class BooleanOption(Option): ...@@ -60,6 +62,7 @@ class BooleanOption(Option):
command=self.set) command=self.set)
self.button.pack(side=RIGHT) self.button.pack(side=RIGHT)
class EnumOption(Option): class EnumOption(Option):
def addoption(self): def addoption(self):
...@@ -76,6 +79,7 @@ class EnumOption(Option): ...@@ -76,6 +79,7 @@ class EnumOption(Option):
value=v, value=v,
command=self.set) command=self.set)
class StringOption(Option): class StringOption(Option):
def addoption(self): def addoption(self):
...@@ -87,6 +91,7 @@ class StringOption(Option): ...@@ -87,6 +91,7 @@ class StringOption(Option):
self.entry.pack(side=RIGHT, fill=X, expand=1) self.entry.pack(side=RIGHT, fill=X, expand=1)
self.entry.bind('<Return>', self.set) self.entry.bind('<Return>', self.set)
class ReadonlyOption(Option): class ReadonlyOption(Option):
def addoption(self): def addoption(self):
...@@ -94,6 +99,7 @@ class ReadonlyOption(Option): ...@@ -94,6 +99,7 @@ class ReadonlyOption(Option):
anchor=E) anchor=E)
self.label.pack(side=RIGHT) self.label.pack(side=RIGHT)
class Dialog: class Dialog:
def __init__(self, master): def __init__(self, master):
...@@ -140,6 +146,7 @@ class Dialog: ...@@ -140,6 +146,7 @@ class Dialog:
enumoption = EnumOption enumoption = EnumOption
readonlyoption = ReadonlyOption readonlyoption = ReadonlyOption
class PackDialog(Dialog): class PackDialog(Dialog):
def __init__(self, widget): def __init__(self, widget):
...@@ -248,6 +255,7 @@ class RemotePackDialog(PackDialog): ...@@ -248,6 +255,7 @@ class RemotePackDialog(PackDialog):
class stringoption(remotepackoption, StringOption): pass class stringoption(remotepackoption, StringOption): pass
class readonlyoption(remotepackoption, ReadonlyOption): pass class readonlyoption(remotepackoption, ReadonlyOption): pass
class WidgetDialog(Dialog): class WidgetDialog(Dialog):
def __init__(self, widget): def __init__(self, widget):
...@@ -357,6 +365,7 @@ class WidgetDialog(Dialog): ...@@ -357,6 +365,7 @@ class WidgetDialog(Dialog):
'Slider': _bistate, 'Slider': _bistate,
} }
class RemoteWidgetDialog(WidgetDialog): class RemoteWidgetDialog(WidgetDialog):
def __init__(self, master, app, widget): def __init__(self, master, app, widget):
...@@ -407,6 +416,7 @@ class RemoteWidgetDialog(WidgetDialog): ...@@ -407,6 +416,7 @@ class RemoteWidgetDialog(WidgetDialog):
class stringoption(remotewidgetoption, StringOption): pass class stringoption(remotewidgetoption, StringOption): pass
class readonlyoption(remotewidgetoption, ReadonlyOption): pass class readonlyoption(remotewidgetoption, ReadonlyOption): pass
def test(): def test():
import sys import sys
root = Tk() root = Tk()
......
# Widget to display a man page # Widget to display a man page
import os
import re import re
import sys
from tkinter import * from tkinter import *
from tkinter import _tkinter from tkinter.font import Font
from tkinter.scrolledtext import ScrolledText from tkinter.scrolledtext import ScrolledText
# XXX These fonts may have to be changed to match your system
BOLDFONT = '*-Courier-Bold-R-Normal-*-120-*'
ITALICFONT = '*-Courier-Medium-O-Normal-*-120-*'
# XXX Recognizing footers is system dependent # XXX Recognizing footers is system dependent
# (This one works for IRIX 5.2 and Solaris 2.2) # (This one works for IRIX 5.2 and Solaris 2.2)
footerprog = re.compile( footerprog = re.compile(
...@@ -16,64 +15,64 @@ footerprog = re.compile( ...@@ -16,64 +15,64 @@ footerprog = re.compile(
emptyprog = re.compile('^[ \t]*\n') emptyprog = re.compile('^[ \t]*\n')
ulprog = re.compile('^[ \t]*[Xv!_][Xv!_ \t]*\n') ulprog = re.compile('^[ \t]*[Xv!_][Xv!_ \t]*\n')
# Basic Man Page class -- does not disable editing
class EditableManPage(ScrolledText): class EditableManPage(ScrolledText):
"""Basic Man Page class -- does not disable editing."""
# Initialize instance
def __init__(self, master=None, **cnf): def __init__(self, master=None, **cnf):
# Initialize base class
ScrolledText.__init__(self, master, **cnf) ScrolledText.__init__(self, master, **cnf)
bold = Font(font=self['font']).copy()
bold.config(weight='bold')
italic = Font(font=self['font']).copy()
italic.config(slant='italic')
# Define tags for formatting styles # Define tags for formatting styles
self.tag_config('X', underline=1) self.tag_config('X', underline=1)
self.tag_config('!', font=BOLDFONT) self.tag_config('!', font=bold)
self.tag_config('_', font=ITALICFONT) self.tag_config('_', font=italic)
# Set state to idle # Set state to idle
self.fp = None self.fp = None
self.lineno = 0 self.lineno = 0
# Test whether we are busy parsing a file
def busy(self): def busy(self):
"""Test whether we are busy parsing a file."""
return self.fp != None return self.fp != None
# Ensure we're not busy
def kill(self): def kill(self):
"""Ensure we're not busy."""
if self.busy(): if self.busy():
self._endparser() self._endparser()
# Parse a file, in the background
def asyncparsefile(self, fp): def asyncparsefile(self, fp):
"""Parse a file, in the background."""
self._startparser(fp) self._startparser(fp)
self.tk.createfilehandler(fp, _tkinter.READABLE, self.tk.createfilehandler(fp, READABLE,
self._filehandler) self._filehandler)
parsefile = asyncparsefile # Alias parsefile = asyncparsefile # Alias
# I/O handler used by background parsing
def _filehandler(self, fp, mask): def _filehandler(self, fp, mask):
"""I/O handler used by background parsing."""
nextline = self.fp.readline() nextline = self.fp.readline()
if not nextline: if not nextline:
self._endparser() self._endparser()
return return
self._parseline(nextline) self._parseline(nextline)
# Parse a file, now (cannot be aborted)
def syncparsefile(self, fp): def syncparsefile(self, fp):
from select import select """Parse a file, now (cannot be aborted)."""
def avail(fp=fp, tout=0.0, select=select):
return select([fp], [], [], tout)[0]
height = self.getint(self['height'])
self._startparser(fp) self._startparser(fp)
while 1: while True:
nextline = fp.readline() nextline = fp.readline()
if not nextline: if not nextline:
break break
self._parseline(nextline) self._parseline(nextline)
self._endparser() self._endparser()
# Initialize parsing from a particular file -- must not be busy
def _startparser(self, fp): def _startparser(self, fp):
"""Initialize parsing from a particular file -- must not be busy."""
if self.busy(): if self.busy():
raise RuntimeError('startparser: still busy') raise RuntimeError('startparser: still busy')
fp.fileno() # Test for file-ness fp.fileno() # Test for file-ness
...@@ -87,22 +86,22 @@ class EditableManPage(ScrolledText): ...@@ -87,22 +86,22 @@ class EditableManPage(ScrolledText):
self.delete('1.0', END) self.delete('1.0', END)
self['state'] = savestate self['state'] = savestate
# End parsing -- must be busy, need not be at EOF
def _endparser(self): def _endparser(self):
"""End parsing -- must be busy, need not be at EOF."""
if not self.busy(): if not self.busy():
raise RuntimeError('endparser: not busy') raise RuntimeError('endparser: not busy')
if self.buffer: if self.buffer:
self._parseline('') self._parseline('')
try: try:
self.tk.deletefilehandler(self.fp) self.tk.deletefilehandler(self.fp)
except TclError as msg: except TclError:
pass pass
self.fp.close() self.fp.close()
self.fp = None self.fp = None
del self.ok, self.empty, self.buffer del self.ok, self.empty, self.buffer
# Parse a single line
def _parseline(self, nextline): def _parseline(self, nextline):
"""Parse a single line."""
if not self.buffer: if not self.buffer:
# Save this line -- we need one line read-ahead # Save this line -- we need one line read-ahead
self.buffer = nextline self.buffer = nextline
...@@ -161,8 +160,8 @@ class EditableManPage(ScrolledText): ...@@ -161,8 +160,8 @@ class EditableManPage(ScrolledText):
self.lineno = self.lineno + 1 self.lineno = self.lineno + 1
self['state'] = savestate self['state'] = savestate
# Insert a string at the end, with at most one property (tag)
def _insert_prop(self, str, prop = ' '): def _insert_prop(self, str, prop = ' '):
"""Insert a string at the end, with at most one property (tag)."""
here = self.index(AtInsert()) here = self.index(AtInsert())
self.insert(AtInsert(), str) self.insert(AtInsert(), str)
if TkVersion <= 4.0: if TkVersion <= 4.0:
...@@ -172,10 +171,10 @@ class EditableManPage(ScrolledText): ...@@ -172,10 +171,10 @@ class EditableManPage(ScrolledText):
if prop != ' ': if prop != ' ':
self.tag_add(prop, here, AtInsert()) self.tag_add(prop, here, AtInsert())
# Readonly Man Page class -- disables editing, otherwise the same
class ReadonlyManPage(EditableManPage): class ReadonlyManPage(EditableManPage):
"""Readonly Man Page class -- disables editing, otherwise the same."""
# Initialize instance
def __init__(self, master=None, **cnf): def __init__(self, master=None, **cnf):
cnf['state'] = DISABLED cnf['state'] = DISABLED
EditableManPage.__init__(self, master, **cnf) EditableManPage.__init__(self, master, **cnf)
...@@ -183,12 +182,9 @@ class ReadonlyManPage(EditableManPage): ...@@ -183,12 +182,9 @@ class ReadonlyManPage(EditableManPage):
# Alias # Alias
ManPage = ReadonlyManPage ManPage = ReadonlyManPage
# Test program.
# usage: ManPage [manpage]; or ManPage [-f] file # usage: ManPage [manpage]; or ManPage [-f] file
# -f means that the file is nroff -man output run through ul -i # -f means that the file is nroff -man output run through ul -i
def test(): def main():
import os
import sys
# XXX This directory may be different on your system # XXX This directory may be different on your system
MANDIR = '' MANDIR = ''
DEFAULTPAGE = 'Tcl' DEFAULTPAGE = 'Tcl'
...@@ -211,10 +207,9 @@ def test(): ...@@ -211,10 +207,9 @@ def test():
if formatted: if formatted:
fp = open(name, 'r') fp = open(name, 'r')
else: else:
fp = os.popen('nroff -man %s | ul -i' % name, 'r') fp = os.popen('nroff -man -c %s | ul -i' % name, 'r')
manpage.parsefile(fp) manpage.parsefile(fp)
root.mainloop() root.mainloop()
# Run the test program when called as a script
if __name__ == '__main__': if __name__ == '__main__':
test() main()
...@@ -192,7 +192,7 @@ def open_message(e=None): ...@@ -192,7 +192,7 @@ def open_message(e=None):
num = int(m.group(1)) num = int(m.group(1))
m = mhf.get_message(num) m = mhf.get_message(num)
if viewer: viewer.destroy() if viewer: viewer.destroy()
from MimeViewer import MimeViewer from mimeviewer import MimeViewer
viewer = MimeViewer(bot, '+%s/%d' % (folder, num), m) viewer = MimeViewer(bot, '+%s/%d' % (folder, num), m)
viewer.pack() viewer.pack()
viewer.show() viewer.show()
......
...@@ -18,7 +18,6 @@ stand-alone application. ...@@ -18,7 +18,6 @@ stand-alone application.
""" """
from tkinter import * from tkinter import *
import random import random
...@@ -201,27 +200,28 @@ class ArrayItem: ...@@ -201,27 +200,28 @@ class ArrayItem:
self.value = value self.value = value
self.canvas = array.canvas self.canvas = array.canvas
x1, y1, x2, y2 = self.position() x1, y1, x2, y2 = self.position()
self.item = array.canvas.create_rectangle(x1, y1, x2, y2, self.item_id = array.canvas.create_rectangle(x1, y1, x2, y2,
fill='red', outline='black', width=1) fill='red', outline='black', width=1)
array.canvas.tag_bind(self.item, '<Button-1>', self.mouse_down) self.canvas.tag_bind(self.item_id, '<Button-1>', self.mouse_down)
array.canvas.tag_bind(self.item, '<Button1-Motion>', self.mouse_move) self.canvas.tag_bind(self.item_id, '<Button1-Motion>', self.mouse_move)
array.canvas.tag_bind(self.item, '<ButtonRelease-1>', self.mouse_up) self.canvas.tag_bind(self.item_id, '<ButtonRelease-1>', self.mouse_up)
def delete(self): def delete(self):
item = self.item item_id = self.item_id
self.array = None self.array = None
self.item = None self.item_id = None
item.delete() self.canvas.delete(item_id)
def mouse_down(self, event): def mouse_down(self, event):
self.lastx = event.x self.lastx = event.x
self.lasty = event.y self.lasty = event.y
self.origx = event.x self.origx = event.x
self.origy = event.y self.origy = event.y
self.item.tkraise() self.canvas.tag_raise(self.item_id)
def mouse_move(self, event): def mouse_move(self, event):
self.item.move(event.x - self.lastx, event.y - self.lasty) self.canvas.move(self.item_id,
event.x - self.lastx, event.y - self.lasty)
self.lastx = event.x self.lastx = event.x
self.lasty = event.y self.lasty = event.y
...@@ -236,7 +236,7 @@ class ArrayItem: ...@@ -236,7 +236,7 @@ class ArrayItem:
self.array.items[here], self.array.items[i] = other, self self.array.items[here], self.array.items[i] = other, self
self.index = i self.index = i
x1, y1, x2, y2 = self.position() x1, y1, x2, y2 = self.position()
self.canvas.coords(self.item, (x1, y1, x2, y2)) self.canvas.coords(self.item_id, (x1, y1, x2, y2))
other.setindex(here) other.setindex(here)
def setindex(self, index): def setindex(self, index):
...@@ -248,9 +248,9 @@ class ArrayItem: ...@@ -248,9 +248,9 @@ class ArrayItem:
self.index = index self.index = index
newpts = self.position() newpts = self.position()
trajectory = interpolate(oldpts, newpts, nsteps) trajectory = interpolate(oldpts, newpts, nsteps)
self.item.tkraise() self.canvas.tag_raise(self.item_id)
for pts in trajectory: for pts in trajectory:
self.canvas.coords(self.item, pts) self.canvas.coords(self.item_id, pts)
self.array.wait(50) self.array.wait(50)
def swapwith(self, other): def swapwith(self, other):
...@@ -263,45 +263,45 @@ class ArrayItem: ...@@ -263,45 +263,45 @@ class ArrayItem:
self.index, other.index = other.index, self.index self.index, other.index = other.index, self.index
mynewpts = self.position() mynewpts = self.position()
othernewpts = other.position() othernewpts = other.position()
myfill = self.canvas.itemcget(self.item, 'fill') myfill = self.canvas.itemcget(self.item_id, 'fill')
otherfill = self.canvas.itemcget(other.item, 'fill') otherfill = self.canvas.itemcget(other.item_id, 'fill')
self.canvas.itemconfig(self.item, fill='green') self.canvas.itemconfig(self.item_id, fill='green')
self.canvas.itemconfig(other.item, fill='yellow') self.canvas.itemconfig(other.item_id, fill='yellow')
self.array.master.update() self.array.master.update()
if self.array.speed == "single-step": if self.array.speed == "single-step":
self.canvas.coords(self.item, mynewpts) self.canvas.coords(self.item_id, mynewpts)
self.canvas.coords(other.item, othernewpts) self.canvas.coords(other.item_id, othernewpts)
self.array.master.update() self.array.master.update()
self.canvas.itemconfig(self.item, fill=myfill) self.canvas.itemconfig(self.item_id, fill=myfill)
self.canvas.itemconfig(other.item, fill=otherfill) self.canvas.itemconfig(other.item_id, fill=otherfill)
self.array.wait(0) self.array.wait(0)
return return
mytrajectory = interpolate(myoldpts, mynewpts, nsteps) mytrajectory = interpolate(myoldpts, mynewpts, nsteps)
othertrajectory = interpolate(otheroldpts, othernewpts, nsteps) othertrajectory = interpolate(otheroldpts, othernewpts, nsteps)
if self.value > other.value: if self.value > other.value:
self.canvas.tag_raise(self.item) self.canvas.tag_raise(self.item_id)
self.canvas.tag_raise(other.item) self.canvas.tag_raise(other.item_id)
else: else:
self.canvas.tag_raise(other.item) self.canvas.tag_raise(other.item_id)
self.canvas.tag_raise(self.item) self.canvas.tag_raise(self.item_id)
try: try:
for i in range(len(mytrajectory)): for i in range(len(mytrajectory)):
mypts = mytrajectory[i] mypts = mytrajectory[i]
otherpts = othertrajectory[i] otherpts = othertrajectory[i]
self.canvas.coords(self.item, mypts) self.canvas.coords(self.item_id, mypts)
self.canvas.coords(other.item, otherpts) self.canvas.coords(other.item_id, otherpts)
self.array.wait(50) self.array.wait(50)
finally: finally:
mypts = mytrajectory[-1] mypts = mytrajectory[-1]
otherpts = othertrajectory[-1] otherpts = othertrajectory[-1]
self.canvas.coords(self.item, mypts) self.canvas.coords(self.item_id, mypts)
self.canvas.coords(other.item, otherpts) self.canvas.coords(other.item_id, otherpts)
self.canvas.itemconfig(self.item, fill=myfill) self.canvas.itemconfig(self.item_id, fill=myfill)
self.canvas.itemconfig(other.item, fill=otherfill) self.canvas.itemconfig(other.item_id, fill=otherfill)
def compareto(self, other): def compareto(self, other):
myfill = self.canvas.itemcget(self.item, 'fill') myfill = self.canvas.itemcget(self.item_id, 'fill')
otherfill = self.canvas.itemcget(other.item, 'fill') otherfill = self.canvas.itemcget(other.item_id, 'fill')
if self.value < other.value: if self.value < other.value:
myflash = 'white' myflash = 'white'
otherflash = 'black' otherflash = 'black'
...@@ -314,12 +314,12 @@ class ArrayItem: ...@@ -314,12 +314,12 @@ class ArrayItem:
myflash = otherflash = 'grey' myflash = otherflash = 'grey'
outcome = 0 outcome = 0
try: try:
self.canvas.itemconfig(self.item, fill=myflash) self.canvas.itemconfig(self.item_id, fill=myflash)
self.canvas.itemconfig(other.item, fill=otherflash) self.canvas.itemconfig(other.item_id, fill=otherflash)
self.array.wait(500) self.array.wait(500)
finally: finally:
self.canvas.itemconfig(self.item, fill=myfill) self.canvas.itemconfig(self.item_id, fill=myfill)
self.canvas.itemconfig(other.item, fill=otherfill) self.canvas.itemconfig(other.item_id, fill=otherfill)
return outcome return outcome
def position(self): def position(self):
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
import os import os
import re import re
import sys import sys
import cgi import html
from xml.parsers import expat from xml.parsers import expat
LEFT, CENTER, RIGHT = "LEFT", "CENTER", "RIGHT" LEFT, CENTER, RIGHT = "LEFT", "CENTER", "RIGHT"
...@@ -201,7 +201,7 @@ class Sheet: ...@@ -201,7 +201,7 @@ class Sheet:
if hasattr(cell, 'xml'): if hasattr(cell, 'xml'):
cellxml = cell.xml() cellxml = cell.xml()
else: else:
cellxml = '<value>%s</value>' % cgi.escape(cell) cellxml = '<value>%s</value>' % html.escape(cell)
out.append('<cell row="%s" col="%s">\n %s\n</cell>' % out.append('<cell row="%s" col="%s">\n %s\n</cell>' %
(y, x, cellxml)) (y, x, cellxml))
out.append('</spreadsheet>') out.append('</spreadsheet>')
...@@ -216,7 +216,7 @@ class Sheet: ...@@ -216,7 +216,7 @@ class Sheet:
f.close() f.close()
def load(self, filename): def load(self, filename):
f = open(filename, 'r') f = open(filename, 'rb')
SheetParser(self).parsefile(f) SheetParser(self).parsefile(f)
f.close() f.close()
...@@ -382,7 +382,7 @@ class StringCell(BaseCell): ...@@ -382,7 +382,7 @@ class StringCell(BaseCell):
return s % ( return s % (
align2xml[self.alignment], align2xml[self.alignment],
self.fmt, self.fmt,
cgi.escape(self.text)) html.escape(self.text))
class FormulaCell(BaseCell): class FormulaCell(BaseCell):
......
...@@ -7,10 +7,10 @@ import re ...@@ -7,10 +7,10 @@ import re
import sys import sys
from tkinter import * from tkinter import *
from ManPage import ManPage from manpage import ManPage
MANNDIRLIST = ['/depot/sundry/man/mann','/usr/local/man/mann'] MANNDIRLIST = ['/usr/local/man/mann', '/usr/share/man/mann']
MAN3DIRLIST = ['/depot/sundry/man/man3','/usr/local/man/man3'] MAN3DIRLIST = ['/usr/local/man/man3', '/usr/share/man/man3']
foundmanndir = 0 foundmanndir = 0
for dir in MANNDIRLIST: for dir in MANNDIRLIST:
...@@ -197,7 +197,7 @@ class SelectionBox: ...@@ -197,7 +197,7 @@ class SelectionBox:
def show_page(self, name): def show_page(self, name):
file = '%s/%s.?' % (self.chaptervar.get(), name) file = '%s/%s.?' % (self.chaptervar.get(), name)
fp = os.popen('nroff -man %s | ul -i' % file, 'r') fp = os.popen('nroff -man -c %s | ul -i' % file, 'r')
self.text.kill() self.text.kill()
self.title['text'] = name self.title['text'] = name
self.text.parsefile(fp) self.text.parsefile(fp)
......
...@@ -4,21 +4,25 @@ import _tkinter ...@@ -4,21 +4,25 @@ import _tkinter
import os import os
import sys import sys
tk = _tkinter.create(os.environ['DISPLAY'], 'wish', 'Tk', 1) tk = _tkinter.create(os.environ['DISPLAY'], 'wish', 'Tk', 1, 1)
tk.call('update') tk.call('update')
cmd = '' cmd = ''
while 1: while True:
if cmd: prompt = '' if cmd:
else: prompt = '% ' prompt = ''
else:
prompt = '% '
try: try:
sys.stdout.write(prompt) sys.stdout.write(prompt)
sys.stdout.flush() sys.stdout.flush()
line = sys.stdin.readline() line = sys.stdin.readline()
if not line:
break
except EOFError: except EOFError:
break break
cmd = cmd + (line + '\n') cmd += line
if tk.getboolean(tk.call('info', 'complete', cmd)): if tk.getboolean(tk.call('info', 'complete', cmd)):
tk.record(line) tk.record(line)
try: try:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment