S
Sean McIlroy
Hi all!
I've written a utility for making diagrams. It could also be a good
environment for experimenting with a Tk canvas, so I'm including the
code here (see below). The problem is that, when I save a canvas and
include the resulting postscript file in a LaTeX document, I often
find that the right edge of the canvas has been cut off and/or that
there's a bunch of extra space at the bottom that forces the picture
to take up a whole page just by itself. The Introduction to Tkinter
lists a bunch of options for the Canvas postscript method, but it
doesn't say anything about the semantics of any of them, and there are
several that sound like they could be what I need. So, if anybody
knows how to exercise finer control over the Canvas postscript method,
I'd be grateful to hear about it.
Peace,
STM
###############################################
## FRESH SHELL: import canvasser
## (so that text can be copied from the shell)
###############################################
pencil = 1
eraser = 10
color = 'black'
def save():
from tkSimpleDialog import askstring
filename = askstring('save diagram','enter name of diagram: ') +
'.eps'
canvas.postscript(file=filename,width=100,height=100,pagewidth=100,pageheight=100)
def circle(x,y,radius=25,color=None):
r = radius
return canvas.create_oval(x-r,y-r,x+r,y+r,fill=color)
#################################################################################
__P__ = None
__I__ = None
def draw(event):
global __P__
Q = [event.x,event.y]
canvas.create_line(__P__[0],__P__[1],Q[0],Q[1],width=pencil,fill=color)
__P__ = Q
def erase(event):
r = eraser
x,y = event.x,event.y
for x in canvas.find_overlapping(x-r,y-r,x+r,y+r):
canvas.delete(x)
def carry(event):
if __I__==None: return
C = canvas.coords(__I__)
x,y = event.x,event.y
if len(C)==2: canvas.coords(__I__,x,y)
else:
a,b = C[:2]
f = lambda i: ( i%2 and [y-b] or [x-a] ) [0]
D = [x,y] + [C + f(i) for i in range(2,len(C))]
canvas.coords(__I__,*D)
def scale(event):
C = canvas.coords(__I__)
if len(C)<>4: return
canvas.coords(__I__,C[0],C[1],event.x,event.y)
def point(event):
codeArea.insert(INSERT,str(event.x) + ',' + str(event.y))
def item(event):
codeArea.insert(INSERT,str(canvas.find_closest(event.x,event.y)[0]))
def mouseDown(event):
global __P__,__I__
m = mode.get()
if m==0: __P__ = [event.x,event.y]
elif m==2: point(event)
elif m==3: item(event)
elif m>=4: __I__ = canvas.find_closest(event.x,event.y)
def mouseDrag(event):
m = mode.get()
if m==0: draw(event)
elif m==1: erase(event)
elif m==4: carry(event)
elif m==5: scale(event)
def mouseUp(event):
global __P__,__I__
__P__ = None
__I__ = None
def runCode(dummy):
x = codeArea.get()
y = [i for i in range(len(x)) if x=='=' and
x[:i].count('(')==0]
z = y and x[:y[0]] + '=' + x[y[0]+1:] or x
print '>>> ' + z
try: exec z in globals()
except: print 'ERROR'
codeArea.delete(0,END)
from Tkinter import *
print '*'*80
print 'REMINDER: canvas; pencil,eraser,color; save,circle'
print '*'*80
root = Tk()
canvas = Canvas(root,background='white')
canvas.bind('<Button-1>',mouseDown)
canvas.bind('<B1-Motion>',mouseDrag)
canvas.bind('<ButtonRelease-1>',mouseUp)
canvas.pack(side=TOP,expand=1,fill=BOTH)
codeArea = Entry(root,font=6)
codeArea.pack(side=TOP,expand=1,fill=X)
codeArea.bind('<Return>',runCode)
ctrl = Frame(root)
mode = IntVar()
Radiobutton(ctrl,indicatoron=0,variable=mode,value=0,text='draw').pack(side=LEFT)
Radiobutton(ctrl,indicatoron=0,variable=mode,value=1,text='erase').pack(side=LEFT)
Radiobutton(ctrl,indicatoron=0,variable=mode,value=2,text='point').pack(side=LEFT)
Radiobutton(ctrl,indicatoron=0,variable=mode,value=3,text='item').pack(side=LEFT)
Radiobutton(ctrl,indicatoron=0,variable=mode,value=4,text='carry').pack(side=LEFT)
Radiobutton(ctrl,indicatoron=0,variable=mode,value=5,text='scale').pack(side=LEFT)
ctrl.pack(side=TOP,pady=10)
root.title('canvasser')
root.mainloop()
I've written a utility for making diagrams. It could also be a good
environment for experimenting with a Tk canvas, so I'm including the
code here (see below). The problem is that, when I save a canvas and
include the resulting postscript file in a LaTeX document, I often
find that the right edge of the canvas has been cut off and/or that
there's a bunch of extra space at the bottom that forces the picture
to take up a whole page just by itself. The Introduction to Tkinter
lists a bunch of options for the Canvas postscript method, but it
doesn't say anything about the semantics of any of them, and there are
several that sound like they could be what I need. So, if anybody
knows how to exercise finer control over the Canvas postscript method,
I'd be grateful to hear about it.
Peace,
STM
###############################################
## FRESH SHELL: import canvasser
## (so that text can be copied from the shell)
###############################################
pencil = 1
eraser = 10
color = 'black'
def save():
from tkSimpleDialog import askstring
filename = askstring('save diagram','enter name of diagram: ') +
'.eps'
canvas.postscript(file=filename,width=100,height=100,pagewidth=100,pageheight=100)
def circle(x,y,radius=25,color=None):
r = radius
return canvas.create_oval(x-r,y-r,x+r,y+r,fill=color)
#################################################################################
__P__ = None
__I__ = None
def draw(event):
global __P__
Q = [event.x,event.y]
canvas.create_line(__P__[0],__P__[1],Q[0],Q[1],width=pencil,fill=color)
__P__ = Q
def erase(event):
r = eraser
x,y = event.x,event.y
for x in canvas.find_overlapping(x-r,y-r,x+r,y+r):
canvas.delete(x)
def carry(event):
if __I__==None: return
C = canvas.coords(__I__)
x,y = event.x,event.y
if len(C)==2: canvas.coords(__I__,x,y)
else:
a,b = C[:2]
f = lambda i: ( i%2 and [y-b] or [x-a] ) [0]
D = [x,y] + [C + f(i) for i in range(2,len(C))]
canvas.coords(__I__,*D)
def scale(event):
C = canvas.coords(__I__)
if len(C)<>4: return
canvas.coords(__I__,C[0],C[1],event.x,event.y)
def point(event):
codeArea.insert(INSERT,str(event.x) + ',' + str(event.y))
def item(event):
codeArea.insert(INSERT,str(canvas.find_closest(event.x,event.y)[0]))
def mouseDown(event):
global __P__,__I__
m = mode.get()
if m==0: __P__ = [event.x,event.y]
elif m==2: point(event)
elif m==3: item(event)
elif m>=4: __I__ = canvas.find_closest(event.x,event.y)
def mouseDrag(event):
m = mode.get()
if m==0: draw(event)
elif m==1: erase(event)
elif m==4: carry(event)
elif m==5: scale(event)
def mouseUp(event):
global __P__,__I__
__P__ = None
__I__ = None
def runCode(dummy):
x = codeArea.get()
y = [i for i in range(len(x)) if x=='=' and
x[:i].count('(')==0]
z = y and x[:y[0]] + '=' + x[y[0]+1:] or x
print '>>> ' + z
try: exec z in globals()
except: print 'ERROR'
codeArea.delete(0,END)
from Tkinter import *
print '*'*80
print 'REMINDER: canvas; pencil,eraser,color; save,circle'
print '*'*80
root = Tk()
canvas = Canvas(root,background='white')
canvas.bind('<Button-1>',mouseDown)
canvas.bind('<B1-Motion>',mouseDrag)
canvas.bind('<ButtonRelease-1>',mouseUp)
canvas.pack(side=TOP,expand=1,fill=BOTH)
codeArea = Entry(root,font=6)
codeArea.pack(side=TOP,expand=1,fill=X)
codeArea.bind('<Return>',runCode)
ctrl = Frame(root)
mode = IntVar()
Radiobutton(ctrl,indicatoron=0,variable=mode,value=0,text='draw').pack(side=LEFT)
Radiobutton(ctrl,indicatoron=0,variable=mode,value=1,text='erase').pack(side=LEFT)
Radiobutton(ctrl,indicatoron=0,variable=mode,value=2,text='point').pack(side=LEFT)
Radiobutton(ctrl,indicatoron=0,variable=mode,value=3,text='item').pack(side=LEFT)
Radiobutton(ctrl,indicatoron=0,variable=mode,value=4,text='carry').pack(side=LEFT)
Radiobutton(ctrl,indicatoron=0,variable=mode,value=5,text='scale').pack(side=LEFT)
ctrl.pack(side=TOP,pady=10)
root.title('canvasser')
root.mainloop()