#
# editing canvas items
#
# fredrik lundh, december 1998
#
# fredrik@pythonware.com
# http://www.pythonware.com
#
from Tkinter import *
class MyCanvas(Frame):
def __init__(self, root):
Frame.__init__(self, root)
self.canvas = Canvas(self)
self.canvas.pack(fill=BOTH, expand=1)
# standard bindings
self.canvas.bind("<1>", self.set_focus)
self.canvas.bind("<Double-Button-1>", self.set_cursor)
self.canvas.bind("<Key>", self.handle_key)
# add a few items to the canvas
self.canvas.create_text(50, 50, text="hello")
self.canvas.create_text(50, 100, text="world")
def highlight(self, item):
# mark focused item. note that this code recreates the
# rectangle for each update, but that's fast enough for
# this case.
bbox = self.canvas.bbox(item)
self.canvas.delete("highlight")
if bbox:
i = self.canvas.create_rectangle(
bbox, fill="white",
tag="highlight"
)
self.canvas.lower(i, item)
def has_focus(self):
return self.canvas.focus()
def has_selection(self):
# FIXME: hack to work around bug in Tkinter 1.101 (Python 1.5.1)
return self.canvas.tk.call(self.canvas._w, 'select', 'item')
def set_focus(self, event):
if self.canvas.type(CURRENT) != "text":
return
self.highlight(CURRENT)
# move focus to item
self.canvas.focus_set() # move focus to canvas
self.canvas.focus(CURRENT) # set focus to text item
self.canvas.select_from(CURRENT, 0)
self.canvas.select_to(CURRENT, END)
def set_cursor(self, event):
# move insertion cursor
item = self.has_focus()
if not item:
return # or do something else
# translate to the canvas coordinate system
x = self.canvas.canvasx(event.x)
y = self.canvas.canvasy(event.y)
self.canvas.icursor(item, "@%d,%d" % (x, y))
self.canvas.select_clear()
def handle_key(self, event):
# widget-wide key dispatcher
item = self.has_focus()
if not item:
return
insert = self.canvas.index(item, INSERT)
if event.char >= " ":
# printable character
if self.has_selection():
self.canvas.dchars(item, SEL_FIRST, SEL_LAST)
self.canvas.select_clear()
self.canvas.insert(item, "insert", event.char)
self.highlight(item)
elif event.keysym == "BackSpace":
if self.has_selection():
self.canvas.dchars(item, SEL_FIRST, SEL_LAST)
self.canvas.select_clear()
else:
if insert > 0:
self.canvas.dchars(item, insert-1, insert)
self.highlight(item)
# navigation
elif event.keysym == "Home":
self.canvas.icursor(item, 0)
self.canvas.select_clear()
elif event.keysym == "End":
self.canvas.icursor(item, END)
self.canvas.select_clear()
elif event.keysym == "Right":
self.canvas.icursor(item, insert+1)
self.canvas.select_clear()
elif event.keysym == "Left":
self.canvas.icursor(item, insert-1)
self.canvas.select_clear()
else:
pass # print event.keysym
if __name__ == "__main__":
root = Tk()
ui=MyCanvas(root)
ui.pack()
root.mainloop()