我找不到更新URWID中SimpleWalkerList内容的正确方法。以下是我尝试根据用户输入生成列表的代码的简化示例:
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()
预期的结果是将值从“ foo”更改为“ oof”(如此简单的字符串操作)。 无论使用哪种方式,都不允许我操纵这些值。我需要刹车循环并从头开始重新绘制整个屏幕吗?
谢谢!
答案 0 :(得分:1)
如SimpleListWalker
文档中所述:
内容–要复制到该对象的列表
对此对象所做的更改(当它被视为列表时)将自动检测到,并将导致使用此列表行者的ListBox对象被更新。
因此,您所需要做的就是修改列表中的元素:
elif input in 'rR':
_, idx = listbox.get_focus()
am = content[idx].original_widget
am.set_text(am.text[::-1])
即使列表中有不可变的值,也可以将它们替换为新对象:
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')
但是由于您没有任何不可变的对象,因此没有必要;第一个版本可以正常工作。
无论哪种方式,如果您按r
,则指向的任何文本都将颠倒,例如从foo
到oof
。 (当然,如果您正在使用任何标记,则需要做些比这更谨慎的操作,但实际上并非如此。)