Reputation: 241
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?
Upvotes: 2
Views: 679
Reputation: 2214
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.)
Upvotes: 2