‘AttributeError’ al intentar crear una pantalla de consola usando urwid

El código siguiente crea un diseño y muestra algo de texto en el diseño. A continuación, el diseño se muestra en la pantalla de la consola utilizando el módulo de visualización sin formato de la biblioteca urwid. (Se puede obtener más información sobre mi proyecto completo a partir de las preguntas en el consejo de widgets para un proyecto de consola y urwid para un proyecto de consola . Mi solicitud de ayuda de Skype está aquí .) Sin embargo, la ejecución del código falla cuando se genera un AttributeError como se describe a continuación. Al mirar el código fuente de urwid en /usr/lib64/python2.7/site-packages/urwid veo que main_loop.py y curses_display.py tienen una función draw_screen con diferentes argumentos: main_loop.py -> def draw_screen (self ):

curses_display.py> def draw_screen (self, (columnas, filas), r):

¿Tengo que especificar cuál usar por algo como importar el comando draw_screen from specificFile ? ¿O hay algo fundamentalmente incorrecto en el concepto de canvas? También puedo ver que la clase de marco ( clase Frame (BoxWidget):) en el archivo /usr/lib64/python2.7/site-packages/urwid/ container.py tiene una función de render ( def render (self, size, focus = Falso):)

El error en el código en ejecución es:
Traceback (most recent call last):
File "./yamlUrwidUIPhase6.py", line 104, in
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'

El código :

 import sys sys.path.append('./lib') import os from pprint import pprint import random import urwid ui=urwid.raw_display.Screen() class FormDisplay(object): def __init__(self): global ui self.ui = ui self.palette = self.ui.register_palette([ ('Field', 'dark green, bold', 'black'), # information fields, Search: etc. ('Info', 'dark green', 'black'), # information in fields ('Bg', 'black', 'black'), # screen background ('InfoFooterText', 'white', 'dark blue'), # footer text ('InfoFooterHotkey', 'dark cyan, bold', 'dark blue'), # hotkeys in footer text ('InfoFooter', 'black', 'dark blue'), # footer background ('InfoHeaderText', 'white, bold', 'dark blue'), # header text ('InfoHeader', 'black', 'dark blue'), # header background ('BigText', RandomColor(), 'black'), # main menu banner text ('GeneralInfo', 'brown', 'black'), # main menu text ('LastModifiedField', 'dark cyan, bold', 'black'), # Last modified: ('LastModifiedDate', 'dark cyan', 'black'), # info in Last modified: ('PopupMessageText', 'black', 'dark cyan'), # popup message text ('PopupMessageBg', 'black', 'dark cyan'), # popup message background ('SearchBoxHeaderText', 'light gray, bold', 'dark cyan'), # field names in the search box ('SearchBoxHeaderBg', 'black', 'dark cyan'), # field name background in the search box ('OnFocusBg', 'white', 'dark magenta') # background when a widget is focused ]) urwid.set_encoding('utf8') 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) self.loop.run() def unhandled_input(self, key): if key == 'f8': quit() return def formLayout(): global ui text1 = urwid.Text("Urwid 3DS Application program - F8 exits.") text2 = urwid.Text("One mission accomplished") textH = urwid.Text("topmost Pile text") cols = urwid.Columns([text1,text2]) pile = urwid.Pile([textH,cols]) fill = urwid.Filler(pile) textT = urwid.Text("Display") textSH = urwid.Text("Pile text in Frame") textF = urwid.Text("Good progress !") frame = urwid.Frame(fill,header=urwid.Pile([textT,textSH]),footer=textF) dim = ui.get_cols_rows() #ui is treated as global handle for all functions, either belonging #to any class or standalone functions such as formLayout #need to check if screen has been started if not ui._started: print("Screen has not been started, so no use of rendering.Thus return :-( ") return ui.draw_screen(dim, frame.render(dim, True)) return def RandomColor(): '''Pick a random color for the main menu text''' listOfColors = ['dark red', 'dark green', 'brown', 'dark blue', 'dark magenta', 'dark cyan', 'light gray', 'dark gray', 'light red', 'light green', 'yellow', 'light blue', 'light magenta', 'light cyan', 'default'] color = listOfColors[random.randint(0, 14)] return color def main(): form = FormDisplay() form.main() ######################################## ##### MAIN ENTRY POINT ######################################## if __name__ == '__main__': main() 

No quiero cambiar la función formLayout ya que tengo la intención de agregar más a este marco de código básico, donde en otra función se agregará repetidamente a formLayout para seguir actualizando la pantalla basándose en los valores de lectura de un archivo yml. Ya tengo un código separado que trata de leer el archivo yaml y extraer diccionarios ordenados. Después de descubrir cómo hacer funcionar la consola básica de urwid, puedo pasar a la integración de ambos para crear mi aplicación final.

El error de atributo se eliminó agregando las siguientes líneas en el código como se muestra en esta pregunta .

línea 1: self.loop.widget = self.view en main de la clase FormDisplay

línea 2: haciendo un return Frame de return en lugar de un return en la función formLayout ()

línea 3: líneas agregadas para manejar las pulsaciones de teclas en la función unhandled_input