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

これらのメソッドはすべて、リストボックス自体ではなく、その属性の 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 を扱うときに取るべき正しいアプローチですか?

4

1 に答える 1

1

MyListBoxレギュラーがどこにでも立つことができる限りListBox、サブクラス化は安全なはずです. 結局のところ、MyListBox本当に、ただの特別なものですListBox

Urwidのドキュメント自体は次のように同意しているようです。

ここでは、サブクラス化して新しい keypress() メソッドを定義することで、Edit ウィジェットを保持している Filler 装飾ウィジェットをカスタマイズしています。このように入力を処理するように装飾またはコンテナー ウィジェットをカスタマイズすることは、Urwid アプリケーションの一般的なパターンです。このパターンは、unhandled_input 関数ですべての特別な入力を処理するよりも、維持および拡張が容易です。

余暇が多すぎる場合は、元の Wiki の継承の代わりに構成を読みたいと思うかもしれません。これは、どの状況でどれが最適かについてあまりにも多くの意見を提供している可能性があります。

于 2014-11-16T15:41:43.337 に答える