Ticket #66 (closed defect: fixed)

Opened 2 years ago

Last modified 7 months ago

Dynamically updating a Pile causes exception

Reported by: robla Owned by: ian
Priority: major Milestone: Urwid 1.0.0
Component: unknown Version:
Keywords: Cc:

Description

Using pile.widget_list.append(myfield) to add a widget to an existing Pile causes two problems:
1. The new field fails to render
2. Navigating to where the widget should be causes an exception to be thrown

Snippet of IRC conversation on this subject:

(05:42:25 PM) wardi: hmm, that should work
[...]
(05:45:27 PM) wardi: the way Pile is implemented atm it keeps two lists, one of the widgets and one describing how each is to be displayed (item_types)
(05:47:12 PM) wardi: you could build a new pile every time you want to add an item, or do self.pile.item_types.append(('flow', None)) after appending the widget
(05:48:02 PM) ***robla tries the item_types thing to see if that does the trick
(05:48:36 PM) wardi: but that's a bug.. it should be defaulting to something and not crashing the way you're seeing

To repro, run the attached script, hit "ctrl n" to create new fields, and then try to navigate to the bottom. The script will bomb at that point.

Change History

Changed 2 years ago by robla

I wasn't able to attach the script, but it's pretty small, so I'm including it as a comment:

#!/usr/bin/python

import urwid.curses_display
import urwid

class EntryForm:
    
    def __init__(self):
        self.ui = urwid.curses_display.Screen()
        self.ui.register_palette( [ ('default', 'default', 'default'), 
                                    ('editfield', 'light gray', 'black'),
                                    ('editfieldfocus', 'white', 'black') ] )

    def run(self):
        editfield1 = urwid.Edit( ('default', "Edit me: "), "blah blah blah" )
        editfield2 = urwid.Edit( ('default', "Edit me2: "), "blah blah blah2" )
        formarray = [ urwid.AttrWrap( editfield1, 'editfield', 'editfieldfocus'),
                      urwid.AttrWrap( editfield2, 'editfield', 'editfieldfocus') ]
        self.pile = urwid.Pile( formarray )
        self.walker = urwid.SimpleListWalker( [ self.pile ] )
        self.listbox = urwid.ListBox( self.walker )
        self.view = urwid.Frame( self.listbox )

        self.ui.run_wrapper( self.runLoop )

    def runLoop(self):
        size = self.ui.get_cols_rows()
        while(True):
            canvas = self.view.render( size, focus=1 )
            self.ui.draw_screen( size, canvas )
            keys = None
            while(keys == None): 
                keys = self.ui.get_input()
            for key in keys:
                if key == 'window resize':
                    size = self.ui.get_cols_rows()
                elif key == 'ctrl n':
                    editfield3 = urwid.Edit( ('default', "Edit me3: "), "blah blah blah2" )
                    self.pile.widget_list.append(editfield3)
                    # Work around the reported bug by uncommenting the following
                    #self.pile.item_types.append(('flow', None)) 
                elif key == 'ctrl x':
                    print "Exiting by ctrl-x"
                    return
                else:
                    self.view.keypress( size, key )


def show_form():
    form=EntryForm()
    form.run()

def main():
    show_form()

main()

Changed 7 months ago by ian

  • status changed from new to closed
  • resolution set to fixed
Note: See TracTickets for help on using tickets.