canvassing for assistance

Sean McIlroy sean_mcilroy at yahoo.com
Mon Feb 28 15:06:06 EST 2005


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[i] + 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[i]=='=' 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()



More information about the Python-list mailing list