1

我正在学习urwid。

Urwid 列表框有一个不适合我的 API。例如,为了将焦点更改为下一个/上一个元素,我想写:

listbox.focus_next() / listbox.focus_previous()

但是 urwid.ListBox 提供的 API 是这样的:

1)关注列表框中的前一个元素

listwalker = listbox.body
widget,current_position  = listwalker.get_focus()
try : 
    widget,previous_position = listwalker.get_prev(current_position)
    listwalker.set_focus(previous_position)
except : 
     # you're at the beginning of the listbox
     pass

2)关注列表框中的下一个元素

# same code, except that you change get_prev with get_next
listwalker = listbox.body
widget,current_position  = listwalker.get_focus()
try : 
    widget,next_position = listwalker.get_next(current_position)
    listwalker.set_focus(next_position)
except : 
     # you're at the end of the listbox
     pass

请注意,所有这些方法都不是在列表框本身上调用的,而是在其属性之一(主体)上调用的。

对这种情况不满意,我决定继承 listbox 本身,为 API 提供两个新服务(方法):focus_previous() 和 focus_next(),如下所示:

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            

在处理令人不快的 API 时,这是(子类化)正确的方法吗?

4

1 回答 1

1

只要MyListBox仍然能够站在常客所在的任何地方ListBox,子类化就应该是安全的。毕竟,MyListBox真的一个ListBox,只是一个特殊的。

Urwid文档本身似乎同意:

在这里,我们通过子类化并定义一个新的 keypress() 方法来自定义保存我们的 Edit 小部件的 Filler 装饰小部件。自定义装饰或容器小部件以这种方式处理输入是 Urwid 应用程序中的常见模式。这种模式比处理 unhandled_input 函数中的所有特殊输入更容易维护和扩展。

如果您发现自己有太多空闲时间,您可能还想通读原始 Wiki 上的Composition 而不是 Inheritance,它可能给出了太多关于哪种情况下最好的意见。

于 2014-11-16T15:41:43.337 回答