Discussion:
[Urwid] How to capture when a widget obtains focus?
Matthew Mosesohn
2013-08-13 13:21:21 UTC
Permalink
Hi Urwidians,

I wrapped Edit class like so:

class EditWithTip(urwid.Edit):
def __init__(self, label, default_value=None, tooltip=None,
toolbar=None):
urwid.Edit.__init__(self, caption=label, edit_text=default_value)
self.tip = tooltip
self.toolbar = toolbar
def keypress(self, size, key):
key = super(EditWithTip, self).keypress(size, key)
self.toolbar.set_text(self.tip)
return key
def mouse_event(self, size, event, button, x, y, focus):
self.toolbar.set_text(self.tip)
(maxcol,) = size
if button==1:
return self.move_cursor_to_coords( (maxcol,), x, y )

mouse_event works as expected. When I click each Edit field, I get the
tooltip (footer of my frame) set to the proper text. Iit doesn't have the
intended consequence I was hoping for with keypress. As I navigate through
my Edit elements (in a ListBox), I get the intended set_text called after I
press a key once the element is active. I was wondering what function I
could implement to run this function when my element is selected via
keyboard.

Best Regards,
Matthew Mosesohn
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.excess.org/pipermail/urwid/attachments/20130813/79e39a2b/attachment.htm
Ian Ward
2013-08-13 13:35:40 UTC
Permalink
On Tue, Aug 13, 2013 at 9:21 AM, Matthew Mosesohn
Post by Matthew Mosesohn
mouse_event works as expected. When I click each Edit field, I get the
tooltip (footer of my frame) set to the proper text. Iit doesn't have the
intended consequence I was hoping for with keypress. As I navigate through
my Edit elements (in a ListBox), I get the intended set_text called after I
press a key once the element is active. I was wondering what function I
could implement to run this function when my element is selected via
keyboard.
If you only have tool-tips for widgets in your ListBox you could
extend ListBox and have it update the tool-tips after each keypress or
mouse_event that comes through.

A fancier approach is to add an on idle handler to your main loop that
checks the widget in focus with get_focus_path so that it can update
the tool-tip from any widget just before the screen is actually
rendered.
Matthew Mosesohn
2013-08-13 13:52:05 UTC
Permalink
Actually, I just found a better solution:

def render(self, size, focus=False):
if focus:
self.toolbar.set_text(self.tip)
canv = super(EditWithTip, self).render(size, focus)

Render gets called all the time for the object, but focus is only True if
it's in focus. It's good enough for my needs and I don't need to handle
ListBox indexes and check positions. I just want to be able to add
tooltip-enhanced Edits arbitrarily anywhere and not have to track it or
store tooltip strings separately.
Post by Ian Ward
On Tue, Aug 13, 2013 at 9:21 AM, Matthew Mosesohn
Post by Matthew Mosesohn
mouse_event works as expected. When I click each Edit field, I get the
tooltip (footer of my frame) set to the proper text. Iit doesn't have the
intended consequence I was hoping for with keypress. As I navigate
through
Post by Matthew Mosesohn
my Edit elements (in a ListBox), I get the intended set_text called
after I
Post by Matthew Mosesohn
press a key once the element is active. I was wondering what function I
could implement to run this function when my element is selected via
keyboard.
If you only have tool-tips for widgets in your ListBox you could
extend ListBox and have it update the tool-tips after each keypress or
mouse_event that comes through.
A fancier approach is to add an on idle handler to your main loop that
checks the widget in focus with get_focus_path so that it can update
the tool-tip from any widget just before the screen is actually
rendered.
_______________________________________________
Urwid mailing list
Urwid at lists.excess.org
http://lists.excess.org/mailman/listinfo/urwid
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.excess.org/pipermail/urwid/attachments/20130813/8bdfeb8b/attachment.htm
Ian Ward
2013-08-13 14:28:32 UTC
Permalink
On Tue, Aug 13, 2013 at 9:52 AM, Matthew Mosesohn
Post by Matthew Mosesohn
self.toolbar.set_text(self.tip)
canv = super(EditWithTip, self).render(size, focus)
Render gets called all the time for the object, but focus is only True if
it's in focus. It's good enough for my needs and I don't need to handle
ListBox indexes and check positions. I just want to be able to add
tooltip-enhanced Edits arbitrarily anywhere and not have to track it or
store tooltip strings separately.
Be careful with this, render() gets called when the widget is actually
rendering, so it's possible that the previous tool tip has been used
to calculate how much space it needs on the screen. If you swap in a
tool-tip that takes more rows or less rows you could cause the render
to fail.

With the methods I describe you can still store your tool-tips on the
widgets themselves, just just a standard attribute name on the widget
and getattr(), you don't need to handle widget positions.

Continue reading on narkive:
Loading...