[Urwid] attribute error encountered while using a render function from Frame class.

Ian Ward ian at excess.org
Sun Jul 28 12:36:47 EDT 2013

On Sun, Jul 28, 2013 at 11:35 AM, SHAIKH TAUSEEF HUSSAIN
<tauseef at nitc.ac.in> wrote:
> Uwid code below creates a layout and displays some text in the layout. Next
> the layout is displayed on the console screen using raw display module from
> urwid library. (More info on my complete project can be gleaned from
> questions at [widget advice for a console
> project](http://stackoverflow.com/questions/17846930/required-widgets-for-displaying-a-1d-console-application)
> and [urwid for a console
> project](http://stackoverflow.com/questions/17381319/using-urwid-to-create-a-2d-console-application).
> My skype help request being
> [here](http://stackoverflow.com/questions/17846113/widget-to-choose-for-1d-urwid-application).)
> However running the code fails as an AttributeError is raised as described
> below. On looking at source code for urwid at
> /usr/lib64/python2.7/site-packages/urwid I see that both main_loop.py and
> curses_display.py have a draw_screen function with different arguments :
> main_loop.py ->    def draw_screen(self):
> curses_display.py > def draw_screen(self, (cols, rows), r ):
> Do I have to specify which one to use by something like **import draw_screen
> from specificFile** command ? Or is there anything fundamentally wrong I am
> looking at the canvas concept ? I can also see that the frame class (**class
> Frame(BoxWidget):** ) in the file
> /usr/lib64/python2.7/site-packages/urwid/**container.py** has a render
> function  (**def render(self, size, focus=False):**)

These two methods don't conflict in any way, and importing doesn't
affect which is used.

MainLoop is a thing that wants to be responsible for handling user
input and redrawing the screen when necessary. Its draw_screen()
method lets you force a screen redraw in cases where the MainLoop
can't tell that it needs to redraw the screen. Since MainLoop has a
screen and widgets to draw its draw_screen() method has no additional

raw_display.Screen.draw_screen() takes a rendered canvas and actually
redraws all or part of the whole screen, so it takes the size and
canvas to draw.

> Traceback (most recent call last):
>       File "./yamlUrwidUIPhase6.py", line 104, in <module>
>         main()
>       File "./yamlUrwidUIPhase6.py", line 98, in main
>         form.main()
>       File "./yamlUrwidUIPhase6.py", line 51, in main
>         self.loop.run()
>       File "/usr/lib64/python2.7/site-packages/urwid/main_loop.py", line
> 274, in run
>         self.screen.run_wrapper(self._run)
>       File "/usr/lib64/python2.7/site-packages/urwid/raw_display.py", line
> 237, in       run_wrapper
>     return fn()
>       File "/usr/lib64/python2.7/site-packages/urwid/main_loop.py", line
> 285, in _run
>     self.draw_screen()
>       File "/usr/lib64/python2.7/site-packages/urwid/main_loop.py", line
> 508, in draw_screen
>     canvas = self._topmost_widget.render(self.screen_size, focus=True)
> AttributeError: 'NoneType' object has no attribute 'render'

This Python error says that self._topmost_widget is None.  We can see
that that value is the loop.widget set in the MainLoop initializer.
Following your code here is where you pass in the widget for the
MainLoop to use:

>         def main(self):
>             global ui
>             #self.view = ui.run_wrapper(formLayout)
>             self.ui.start()
>             self.view = formLayout()
>             self.loop = urwid.MainLoop(self.view, self.palette,
> unhandled_input=self.unhandled_input)

so, self.view here is None too.  So it looks like formLayout() is not
returning a widget.

Hope this helps.


More information about the Urwid mailing list