Как создать вложенные списки в urwid?
Можно ли поместить ListBoxes внутри SimpleListWalkers? Я пытаюсь сделать вложенный ListBoxes, но у меня есть эта ошибка:
AttributeError: 'MyListBox' object has no attribute 'rows'
import urwid
class MyListBox(urwid.ListBox):
def focus_next(self):
try:
self.body.set_focus(self.body.get_next(self.body.get_focus()[1])[1])
except:
pass
def focus_previous(self):
try:
self.body.set_focus(self.body.get_prev(self.body.get_focus()[1])[1])
except:
pass
def handle_input(event):
frame.header.set_text("key pressed %s" % event)
if event == "q":
raise urwid.ExitMainLoop
elif event == "up":
lb.focus_previous()
elif event == "down" :
lb.focus_next()
widgets = [urwid.AttrMap(urwid.Text(str(x)),None,"focus") for x in xrange(3)]
nested = [urwid.AttrMap(urwid.Text(str(x)+"_sous"),None,"focus") for x in xrange(3)]
nested_lb = MyListBox(urwid.SimpleListWalker(nested))
lb = MyListBox(urwid.SimpleListWalker(widgets+[nested_lb]))
frame = urwid.Frame(lb,header=urwid.Text("Header"))
palette = [("focus","dark cyan","white")]
loop = urwid.MainLoop(frame,palette,unhandled_input = handle_input)
loop.screen.set_terminal_properties(colors=256)
loop.run()
1 ответ
Согласно инструкции ListBox
является виджетом коробки, который содержит потоковые виджеты внутри
Разница между типами виджетов (бокс, поток и фиксированный) заключается в методе расчета их размера. Подробности описаны в вышеупомянутой ссылке. Короче: ListBox
информируется о его размере из своего контейнера, но требует, чтобы его дети вычислили свои высоты самостоятельно. Как другой ListBox
внутри не может обеспечить это значение (не имеет rows
метод).
Решение состоит в том, чтобы обернуть внутренний ListBox
в BoxAdapter
это заставляет виджет box выглядеть и вести себя как виджет потока:
...
widgets = [urwid.AttrMap(urwid.Text(str(x)),None,"focus") for x in xrange(3)]
nested = [urwid.AttrMap(urwid.Text(str(x)+"_sous"),None,"focus") for x in xrange(3)]
nested_lb = MyListBox(urwid.SimpleListWalker(nested))
lb = MyListBox(urwid.SimpleListWalker(widgets+[urwid.BoxAdapter(nested_lb, 10)]))
...