私は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
これらのメソッドはすべて、リストボックス自体ではなく、その属性の 1 つ (ボディ) で呼び出されることに注意してください。
この状況に不満を持っていたので、リストボックス自体をサブクラス化して API に 2 つの新しいサービス (メソッド) を提供することにしました: 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 を扱うときに取るべき正しいアプローチですか?