[Tkinter-discuss] Cursor coordinates

Vasilis Vlachoudis Vasilis.Vlachoudis at cern.ch
Sat Dec 5 19:49:00 CET 2009

Hi Michael,

using your suggestions I've made the routine that works with multilines, 
and no binary search this time :)


# -------------------------
from Tkinter import *
import tkFont
import string

def click(event):
    global canvas, font, txt
    x = canvas.canvasx(event.x)
    y = canvas.canvasy(event.y)
    print "Clicked: ",x,y
    print "Cursor:  ",cursorxy(canvas)

def cursorxy(canvas):
    item = canvas.focus()
    if item:
        font = tkFont.nametofont(canvas.itemcget(item,"font"))
        x1,y1,x2,y2 = canvas.bbox(item)
        fontheight = font.metrics().get("linespace")
        index = canvas.index(item,INSERT)
        if index==0:
            return x1,y1+fontheight//2
        txt = canvas.itemcget(item,"text")
        # count the lines before
        subtxt = txt[:index]
        print "subtxt=\"%s\""%(subtxt)
        lines = subtxt.count("\n")
        y = y1 + lines*fontheight + fontheight//2
        if lines>0:
            x = x1 + font.measure(subtxt[subtxt.rfind("\n")+1:])
            x = x1 + font.measure(subtxt)
        return (x,y)
        return (None,None)

# ---------------------------------------------------------------------
root = Tk()
canvas = Canvas(root, background="White")
canvas.pack(expand=YES, fill=BOTH)
#font = tkFont.Font(font=("Helvetica",10))
canvas.bind("<1>", click)
root.bind("<Escape>", lambda e:root.destroy())

quotes="""Anyone who has never made a mistake has never tried anything new.
Common sense is the collection of prejudices acquired by age eighteen.
Education is what remains after one has forgotten everything he learned 
in school.
Few are those who see with their own eyes and feel with their own hearts.
Gravitation cannot be held responsible for people falling in love.
I don't know with what weapons World War III will be fought, but World 
War IV will be fought with sticks and stones.
I never think of the future - it comes soon enough.
If A equals success, then the formula is: A = X + Y + Z, X is work. Y is 
play. Z is keep your mouth shut.
If I have seen farther than others, it is because I was standing on the 
shoulders of giants.
If the facts don't fit the theory, change the facts.
If we knew what we were doing, it wouldn't be called research, would it?
Imagination is more important than knowledge.
In the middle of difficulty lies opportunity."""

txt = canvas.create_text(10,10,text=quotes,anchor=NW)


Michael O'Donnell wrote:
> Ok,
> The following code demonstrates:
> a) finding the char index  of the insertion cursor in a text item in a Canvas
> b) translating that char position into pixel position
> c) drawing a box around the insertion cursor.
> Did I miss something?
> from Tkinter import *
> from tkFont import Font
> root=Tk()
> canvas=Canvas(root)
> canvas.pack()
> myFont=Font(family="Times", size=14)
> myText="blahblah"
> txt = canvas.create_text(10,10,text=myText, anchor=NW, font=myFont)
> # place the cursor on the fifth character
> canvas.focus_set()
> canvas.focus(txt)
> canvas.icursor(txt, 5)
> # get the position
> print "cursor character position=",canvas.index(txt, INSERT)
> # Find the pixel bounds of the insertion cursor
> #  (assume 1 pixel width of the cursor)
> text=myText[0:canvas.index(txt, INSERT)]
> width=myFont.measure(text)
> bbox=canvas.bbox(txt)
> x1=bbox[0]+width-1
> y1=bbox[1]
> x2=x1+3
> y2=bbox[3]
> canvas.create_rectangle(x1,y1,x2,y2, outline="red")
> root.mainloop()

More information about the Tkinter-discuss mailing list