我正在学习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时采用的正确方法吗?
答案 0 :(得分:1)
只要MyListBox
仍能在常规ListBox
的任何地方站立,子类化应该是安全的。毕竟,MyListBox
确实 是ListBox
,只是一个特殊的。{/ p>
Urwid documentation本身似乎同意:
在这里,我们通过对其进行子类化并定义新的keypress()方法来自定义填充我们的编辑小部件的填充装饰小部件。自定义装饰或容器小部件以这种方式处理输入是Urwid应用程序中的常见模式。与处理unhandled_input函数中的所有特殊输入相比,此模式更易于维护和扩展。
如果你发现自己有太多的业余时间,你可能还想阅读原始Wiki上的Composition Instead Of Inheritance,这可能会给出太多关于哪种情况最佳的意见。