Editing text in Canvas

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Editing text in Canvas

Martin B.-4
Hi all,
I'm write some custom widgets for my app.
Now i write custom Scale widget  like in Gimp2.7.

Here is the code:
http://www.tbs-software.com/spookyln/py/Tk_Scale.py

but i need some kick how to make it editable.When i click to Canvas
focus set to editable entry.First value ok and next is error that focus
not set in item :(

BTW: is possible make gradient fill in Canvas.create_rectangle() ?
thanks for info
_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss

Tk_Scale.py (2K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Editing text in Canvas

Martin B.-4
V Fri, 26 Aug 2011 14:27:42 +0200
Martin B <[hidden email]> 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
_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Editing text in Canvas

Michael Lange
Hi,

Thus spoketh Martin B <[hidden email]>
unto us on Fri, 26 Aug 2011 15:27:05 +0200:

> V Fri, 26 Aug 2011 14:27:42 +0200
> Martin B <[hidden email]> 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):
        self.main.focus()

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.

Regards

Michael

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

Vulcans do not approve of violence.
                -- Spock, "Journey to Babel", stardate 3842.4
_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Editing text in Canvas

Martin B.-4
Thanks for info.
Yes i slowly updating source. using web for my backup sometimes.

Now when i arrive from my bike trip with clean head i tried use
'unbind' in __edit_value method and created new bind in __select value.
seems to work.

as for entry. i dont know how i may change background under entry if
filled rect is under object.
And for question which i posted before. Is some way to fill this rect
with gradient or only way is to create gradient image and use
create_bitmap instead create_rect. this is my first idea how to do this.

quickly updated source is on web. same link as before.

_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Editing text in Canvas

Martin B.-4

> And for question which i posted before. Is some way to fill this rect
> with gradient or only way is to create gradient image and use
> create_bitmap instead create_rect. this is my first idea how to do
> this.

Hello, problem is solved.
Now i implemented vertical and horizontal gradients using
Canvas.create_line()
_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Editing text in Canvas

Michael Lange
In reply to this post by Martin B.-4
Hi,

Thus spoketh Martin B <[hidden email]>
unto us on Fri, 26 Aug 2011 22:26:16 +0200:

> Thanks for info.
> Yes i slowly updating source. using web for my backup sometimes.
>
> Now when i arrive from my bike trip with clean head i tried use
> 'unbind' in __edit_value method and created new bind in __select value.
> seems to work.
>
> as for entry. i dont know how i may change background under entry if
> filled rect is under object.

You are right, this is not possible. Maybe a way to go is to temporarily
create an Entry, as in this example:

from Tkinter import *
root = Tk()
c = Canvas(root)
c.pack()
textvar = StringVar()
t = c.create_text(100, 100, text='foo', anchor='nw')

def edit_begin(event):
    x, y = c.coords(t)
    textvar.set(c.itemcget(t, 'text'))
    e = Entry(c, width=5, textvariable=textvar, bd=0,
                highlightthickness=0, bg=c['bg'])
    e.selection_range(0, 'end')
    w = c.create_window(x, y, window=e, tags=('editwindow',), anchor='nw')
    e.focus_set()
    e.bind('<Return>', edit_end)
    e.bind('<Escape>', edit_cancel)

def edit_cancel(event):
    c.delete('editwindow')
    event.widget.destroy()
    c.focus_set()

def edit_end(event):
    c.itemconfigure(t, text=textvar.get())
    edit_cancel(event)

c.bind('<Control-e>', edit_begin)

c.focus_set()
root.mainloop()

Regards

Michael


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

Earth -- mother of the most beautiful women in the universe.
                -- Apollo, "Who Mourns for Adonais?" stardate 3468.1
_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Editing text in Canvas

Martin B.-4
Yes this is good idea !
Saved into my examples for later use.

Now i quickly updated example on web with gradient fills.
No errors check yet. I need rewrite some things etc. etc.

BTW : i found on inet TkZinc which use OpenGL for writing into canvas.
Someone using this in apps ? thanks
_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Editing text in Canvas

Michael Lange
In reply to this post by Martin B.-4
Thus spoketh Martin B <[hidden email]>
unto us on Sat, 27 Aug 2011 10:26:57 +0200:

>
> > And for question which i posted before. Is some way to fill this rect
> > with gradient or only way is to create gradient image and use
> > create_bitmap instead create_rect. this is my first idea how to do
> > this.
>
> Hello, problem is solved.
> Now i implemented vertical and horizontal gradients using
> Canvas.create_line()

Can you post a brief example how you implemented the gradients?

Michael


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

Genius doesn't work on an assembly line basis.  You can't simply say,
"Today I will be brilliant."
                -- Kirk, "The Ultimate Computer", stardate 4731.3
_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss