# # 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()