Search code examples
pythonlistboxwidgeturwid

How to put a urwid.BigText into a urwid.ListBox


I keep getting an error AttributeError: 'BigText' object has no attribute 'rows' when trying to have a BigText at the top of a ListBox. I understand that the BigText is a "fixed" widget, while ListBox expects a "flow" widget, but I can't seem to get my program to take the BigText no matter what I try. Here's an exhaustive example of what I've attempted:

head_title = urwid.BigText(('banner', u'Header'), urwid.HalfBlock5x4Font())
head = urwid.Filler(head_title)
# head = urwid.AttrMap(head, 'banner')
# head = urwid.AttrMap(head, 'streak')
head = urwid.BoxAdapter(head, 3)
print head
# this gives me `<BoxAdapter flow widget <Filler box widget <BigText fixed widget>> height=3>`


body = [head, urwid.Divider()]
return urwid.ListBox(body)

Thanks!


Solution

  • BigText is a of 'fixed' sizing. That means that both the width and the height of the widget is defined by the widget. ListBox only accepts widgets of 'flow' sizing. This means that the width will be decided by the container (in this case the ListBox). So, you have to first convert he 'fixed' widget to a 'flow' widget. This can be done with the Padding decoration widget by setting the width property to 'clip'.

    See here for a full example:

    import urwid
    def show_or_exit(key):
        if key in ('q', 'Q'):
            raise urwid.ExitMainLoop()
        return key
    
    head = urwid.ListBox(urwid.SimpleFocusListWalker([
        urwid.Padding(
            urwid.BigText(('banner', "Hello world"), urwid.HalfBlock5x4Font()),
            width='clip')
    ]))
    
    loop = urwid.MainLoop(head, unhandled_input=show_or_exit)
    loop.run()