Urwid raising (maxcol,) = size too many values to unpack

538 Views Asked by At

I'm trying to create an Urwid UI for a robot. The layout I have in mind is made of three horizontal areas:

  • One liner message (like "unknown key pressed")
  • Running log messages (anything that happens in the robot)
  • Watched variables I'd like to always be displayed

I created this code resulting in the screenshotted layout:

brief_message = urwid.Text(u'Robot starting...')
log_messages = urwid.Text('running log messages here')
variables = urwid.Text('k=v variable list here')
body = urwid.Pile([
    #urwid.Filler(brief_message, height=1),
    urwid.LineBox(urwid.Filler(log_messages, valign='bottom', top=1)),
    urwid.LineBox(urwid.Filler(variables, valign='top', bottom=1)),
])
loop = urwid.MainLoop(body)
loop.run()

screenshot of resulting layout

The problem is that if I uncomment urwid.Filler(brief_message, height=1) line, I get an exception and I'm not sure why:

[ full traceback snipped ]
  File "/tmp/venv/lib/python3.8/site-packages/urwid/widget.py", line 1001, in render
    (maxcol,) = size
ValueError: too many values to unpack (expected 1)

I understand this happens because a flow widget is treated like a box widget, but I thought wrapping brief_message with an urwid.Filler is exactly what I'm supposed to do. Further, if I remove height=1 from the Filler the program works, but brief_message's height is a third of the screen, which isn't what I want - it should be a oneliner.

What am I missing?

1

There are 1 best solutions below

2
W1ndstorm On BEST ANSWER

Looking at the documentation for urwid.Filler it says:

If body is a flow widget then height must be 'flow' and min_height will be ignored.

You can't set set to the height to 1 or anything except flow if you are using flow widget like urwid.Text as the body.

As far as actually getting the result you're looking for, what follows is my best guess. I don't have an appropriate test environment set up so YMMV.

Looking at the documentation for Pile you can pass tuples with a height value and it will be treated as a box widget. So you might try

body = urwid.Pile([
    (1, urwid.Filler(brief_message)),
    urwid.LineBox(urwid.Filler(log_messages, valign='bottom', top=1)),
    urwid.LineBox(urwid.Filler(variables, valign='top', bottom=1)),
])