Reputation: 63
In urwid, is there a way for child widgets to change their attributes based on screen redraw actions?
Specifically, if I have a button widget with some very long string:
mybutton = urwid.Button(<some very long string>)
Is there a way for the button to display only part of the string when the terminal is re-sized to a column width less than the length of the string? Equivalent to:
mybutton = urwid.Button(<some very long...>)
As it is now, urwid attempts to wrap the button label, which looks ugly in the context of my interface.
Upvotes: 2
Views: 577
Reputation: 23806
I think the easiest way to achieve this is to implement this behavior as a custom widget, which wraps the vanilla urwid.Button
but forcing it to render always in only one row -- here is a fully working example:
from __future__ import print_function, absolute_import, division
import urwid
class MyButton(urwid.WidgetWrap):
def __init__(self, *args, **kw):
self.button = urwid.Button(*args, **kw)
super(MyButton, self).__init__(self.button)
def rows(self, *args, **kw):
return 1
def render(self, size, *args, **kw):
cols = size[0]
maxsize = cols - 4 # buttons use 4 chars to draw < > borders
if len(self.button.label) > maxsize:
new_label = self.button.label[:maxsize - 3] + '...'
self.button.set_label(new_label)
return super(MyButton, self).render(size, *args, **kw)
def show_or_exit(key):
if key in ('q', 'Q', 'esc'):
raise urwid.ExitMainLoop()
if __name__ == '__main__':
# demo:
widget = urwid.Pile([
urwid.Text('Some buttons using urwid vanilla urwid.Button widget:\n'),
urwid.Button('Here is a little button with really a really long string for label, such that it can be used to try out a problem described in Stackoverflow question'),
urwid.Button('And here is another button, also with a really really long string for label, for the same reason as the previous one'),
urwid.Button('And a short one'),
urwid.Text('\n\n\nSame buttons, with a custom button widget:\n'),
MyButton('Here is a little button with really a really long string for label, such that it can be used to try out a problem described in Stackoverflow question'),
MyButton('And here is another button, also with a really really long string for label, for the same reason as the previous one'),
MyButton('And a short one'),
urwid.Columns([
MyButton('Here is a little button with really a really long string for label, such that it can be used to try out a problem described in Stackoverflow question'),
MyButton('And here is another button, also with a really really long string for label, for the same reason as the previous one'),
]),
])
widget = urwid.Filler(widget, 'top')
loop = urwid.MainLoop(widget, unhandled_input=show_or_exit)
loop.run()
Upvotes: 1