[Tkinter-discuss] Editing text in Canvas

Michael Lange klappnase at web.de
Fri Aug 26 21:50:07 CEST 2011


Thus spoketh Martin B <spooky.ln at tbs-software.com> 
unto us on Fri, 26 Aug 2011 15:27:05 +0200:

> V Fri, 26 Aug 2011 14:27:42 +0200
> Martin B <spooky.ln at tbs-software.com> napsáno:
> sorry for bothering problem is solved. But another raised.
> How i remove insertion from text object after i hit Return.
> If i click on canvas insert cursor dissapear but if i write some
> numbers then these numbers is written in new pos on text object.
> Thanks

Hm, here I get:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python2.6/lib-tk/Tkinter.py", line 1413, in __call__
    return self.func(*args)
  File "test7.py", line 79, in __edit_value
    self.dchars(item, SEL_FIRST, SEL_LAST)
  File "/usr/lib/python2.6/lib-tk/Tkinter.py", line 2181, in dchars
    self.tk.call((self._w, 'dchars') + args)
TclError: selection isn't in item

I guess you changed your code a litle since the last post ?

Anyway, your problem is that the Canvas still has keyboard focus and so
the __edit_value() callback will be called no matter which of its items
the canvas focusses. To understand this you need to be aware that the
Canvas' internal focus is not the same as the "normal" widget focus, as
"man canvas" says:

"""Once the focus has been set to an item, the item will display the
insertion cursor and all keyboard events will be directed to that item.
The focus item within a canvas and the focus window on the screen (set
with the focus command) are totally independent: a given item does not
actually have the input focus unless (a) its canvas is the focus window
and (b) the item is the focus item within the canvas. In most cases it is
advisable to follow the focus widget command with the focus command to
set the focus window to the canvas (if it was not there already)."""

So you need to either add a callback for Button-1 (and maybe other)
events that checks the x and y-coords of the event and moves keyboard
focus away from the canvas, which could basically look like:

    self.bind('<1>', self._set_focus, add=True)

    def _set_focus(self, event):
        if not self.objects['entry'] in self.find('overlapping', event.x,
                                              event.y, event.x, event.y):

or let your __edit_value () callback handle the situation, although I
admit that at a quick glance I have no idea how to do that.

The third solution that comes to mind seems the best to me: use
self.create_window() to replace your text object with an Entry widget
which should handle keyboard focus properly. 



.-.. .. ...- .   .-.. --- -. --.   .- -. -..   .--. .-. --- ... .--. . .-.

Vulcans do not approve of violence.
		-- Spock, "Journey to Babel", stardate 3842.4

More information about the Tkinter-discuss mailing list