I cant find a proper way to update the content of the SimpleWalkerList in URWID. Below is simplified example of the code I am trying to generate list base on the user input:
import urwid
palette = [('header', 'white', 'black'),
('reveal focus', 'black', 'dark cyan', 'standout')]
items = [urwid.Text("foo"),
urwid.Text("bar"),
urwid.Text("baz")]
content = urwid.SimpleListWalker([
urwid.AttrMap(w, None, 'reveal focus') for w in items])
listbox = urwid.ListBox(content)
show_key = urwid.Text("Press any key", wrap='clip')
head = urwid.AttrMap(show_key, 'header')
top = urwid.Frame(listbox, head)
def show_all_input(input, raw):
show_key.set_text("Pressed: " + " ".join([
unicode(i) for i in input]))
return input
def exit_on_cr(input):
if input in ('q', 'Q'):
raise urwid.ExitMainLoop()
elif input == 'up':
focus_widget, idx = listbox.get_focus()
if idx > 0:
idx = idx-1
listbox.set_focus(idx)
elif input == 'down':
focus_widget, idx = listbox.get_focus()
idx = idx+1
listbox.set_focus(idx)
elif input == 'enter':
pass
#
#how here can I change value of the items list and display the ne value????
#
def out(s):
show_key.set_text(str(s))
loop = urwid.MainLoop(top, palette,
input_filter=show_all_input, unhandled_input=exit_on_cr)
loop.run()
Expected result would be changing the value for example from 'foo' to 'oof' (so simple string manipulation). Whatever way I am using is not allowing me to manipulate on the values. Do I need to brake the loop and redraw the entire screen from scratch?
Thanks in advance!
As explained in the docs for SimpleListWalker
:
contents – list to copy into this object
Changes made to this object (when it is treated as a list) are detected automatically and will cause ListBox objects using this list walker to be updated.
So, all you have to do is modify the elements in the list:
elif input in 'rR':
_, idx = listbox.get_focus()
am = content[idx].original_widget
am.set_text(am.text[::-1])
Even if you had immutable values in the list, you could just replace them with new objects:
elif input in 'rR':
_, idx = listbox.get_focus()
w = urwid.Text(content[idx].original_widget.text[::-1])
content[idx] = urwid.AttrMap(w, None, 'reveal focus')
But since you don't have any immutable objects getting in the way, that isn't necessary; the first version will work fine.
Either way, if you press r
, whatever text you were pointing at gets reversed, like foo
to oof
. (Of course if you were using any markup, you'd need to do something a bit more careful than that, but you're not.)