Urwid:按钮小部件回调如何工作?

Urwid: how does the button widget callback work?

urwid 库有问题,如果有人熟悉的话,我可以帮忙。下面有两个代码片段,第一个是从 urwid 文档复制的工作示例,第二个是我将文档中的一些不同示例放在一起的结果。

我的主要问题是 item_chosen 函数应该在 "click" 事件上 运行,即按回车键,但在第二个事件中似乎没有 运行版本

除了文档之外,很难找到很多 urwid 资源,而且我使用它的时间还不够长,无法完全了解他们的小部件模型,如果这在某种程度上微不足道或显而易见,我深表歉意。

这是从 urwid 文档复制的工作示例。

import urwid

choices = u'Chapman Cleese Gilliam Idle Jones Palin'.split()

def menu(title, choices):
    body = [urwid.Text(title), urwid.Divider()]
    for c in choices:
        button = urwid.Button(c)
        urwid.connect_signal(button, 'click', item_chosen, c)
        body.append(urwid.AttrMap(button, None, focus_map='reversed'))
    return urwid.ListBox(urwid.SimpleFocusListWalker(body))

def item_chosen(button, choice):
    response = urwid.Text([u'You chose ', choice, u'\n'])
    done = urwid.Button(u'Ok')
    urwid.connect_signal(done, 'click', exit_program)
    main.original_widget = urwid.Filler(urwid.Pile([response,
        urwid.AttrMap(done, None, focus_map='reversed')]))

def exit_program(button):
    raise urwid.ExitMainLoop()

main = urwid.Padding(menu(u'Pythons', choices), left=2, right=2)
top = urwid.Overlay(main, urwid.SolidFill(u'\N{MEDIUM SHADE}'),
    align='center', width=('relative', 60),
    valign='middle', height=('relative', 60),
    min_width=20, min_height=9)
urwid.MainLoop(top, palette=[('reversed', 'standout', '')]).run()

我尝试将其重构为 class,但成败参半。

class Menu:
    def __init__(self,title,choices):
        pad = urwid.Padding(self.make(title, choices), left=2, right=2)
        self.main = urwid.Overlay(pad, urwid.SolidFill(u'\N{MEDIUM SHADE}'),
            align='center', width=('relative', 60),
            valign='middle', height=('relative', 60),
            min_width=20, min_height=9)

    def make(self,title,choices):
        body = [urwid.Text(title), urwid.Divider()]
        for c in choices:
            button = urwid.Button(c)
            urwid.connect_signal(button, 'click', self.item_chosen, c)
            body.append(urwid.AttrMap(button, None, focus_map='reversed'))
        return urwid.ListBox(urwid.SimpleFocusListWalker(body))

    def item_chosen(self, button, choice):
        response = urwid.Text([u'You chose ', choice, u'\n'])
        done = urwid.Button(u'Ok')
        urwid.connect_signal(done, 'click', exit_program)
        self.main.original_widget = urwid.Filler(urwid.Pile([response,
            urwid.AttrMap(done, None, focus_map='reversed')]))

我的完整代码在这里:https://pastebin.com/bv4eubiy

如上所述,如果您 运行 第二个代码,您会注意到,显示您选择的内容的对话框没有出现,我不明白为什么。

在对文档进行了大量思考之后,我的错误很明显。

self.main.original_widget = urwid.Filler(urwid.Pile([response,urwid.AttrMap(done, None, focus_map='reversed')]))

正在修改 urwid.Padding class 的 original_widget 成员。在我上面的代码中,我将 self.main 设置为 urwid.Overlay 而不是 urwid.Padding。在一些物体周围移动可以解决问题。