In urwid 'Frame' object has no attribute 'rows'

590 Views Asked by At

I am searching any simple way to make urwid.Frame work in python without success, as example, I try this MWE:

frame  = urwid.Frame(urwid.Text(('some text'), align='center'))
filler = urwid.Filler(frame, "top")
loop   = urwid.MainLoop(filler)
loop.run()

And I get the following unuseful error message:

Traceback (most recent call last):
  File "pycurses.py", line 596, in <module>
    loop.run()
  File "/home/fauve/.local/lib/python3.5/site-packages/urwid/main_loop.py", line 287, in run
    self._run()
  File "/home/fauve/.local/lib/python3.5/site-packages/urwid/main_loop.py", line 385, in _run
    self.event_loop.run()
  File "/home/fauve/.local/lib/python3.5/site-packages/urwid/main_loop.py", line 790, in run
    self._loop()
  File "/home/fauve/.local/lib/python3.5/site-packages/urwid/main_loop.py", line 818, in _loop
    self._entering_idle()
  File "/home/fauve/.local/lib/python3.5/site-packages/urwid/main_loop.py", line 779, in _entering_idle
    callback()
  File "/home/fauve/.local/lib/python3.5/site-packages/urwid/main_loop.py", line 574, in entering_idle
    self.draw_screen()
  File "/home/fauve/.local/lib/python3.5/site-packages/urwid/main_loop.py", line 588, in draw_screen
    canvas = self._topmost_widget.render(self.screen_size, focus=True)
  File "/home/fauve/.local/lib/python3.5/site-packages/urwid/widget.py", line 145, in cached_render
    canv = fn(self, size, focus=focus)
  File "/home/fauve/.local/lib/python3.5/site-packages/urwid/decoration.py", line 814, in render
    top, bottom = self.filler_values(size, focus)
  File "/home/fauve/.local/lib/python3.5/site-packages/urwid/decoration.py", line 799, in filler_values
    height = self._original_widget.rows((maxcol,),focus=focus)
  File "/home/fauve/.local/lib/python3.5/site-packages/urwid/widget.py", line 205, in cached_rows
    return fn(self, size, focus)
  File "/home/fauve/.local/lib/python3.5/site-packages/urwid/container.py", line 1611, in rows
    return sum(self.get_item_rows(size, focus))
  File "/home/fauve/.local/lib/python3.5/site-packages/urwid/container.py", line 1512, in get_item_rows
    l.append(w.rows((maxcol,),
AttributeError: 'Frame' object has no attribute 'rows'

I try many variations, such putting the frame inside an urwid.Pile before giving it to the Filler widget, but I still get similar error messages.

So, is their any minimalist example work using urwid.Frame?

And what doese mean this “Frame' object has no attribute 'rows'”? I never ask in my example any .rows method, so why the error message have a behavior like if I used it?

1

There are 1 best solutions below

0
On

The error is indeed not very good. The actual problem here is that the nesting of the Frame and the Filler should be the other way around:

import urwid

text = urwid.Text('some text', align='center')
filler = urwid.Filler(text, "top")
frame  = urwid.Frame(filler)
loop   = urwid.MainLoop(frame)
loop.run()

A flow widget (like Text) gets to decide how many rows it should be. The main loop expects a box widget (which does not get to pick its own width or height). The Filler widget bridges the two: it asks the wrapped flow widget how many rows it takes up (given a number of columns) and then fills up the rest of the rows.

The Frame is a box widget that contains another box widget in the center.

If you haven't seen this page already, I highly recommend looking at the diagrams here: http://urwid.org/manual/widgets.html#included-widgets The colors describe what kinds of widgets nest inside what kinds of widgets.

(Also I suspect it would be technically feasible for Urwid to detect that the widget is of the wrong type and say that instead in the error message, but I haven't dived that deep into the implementation.)