4.13. シンプルな TUI Spoke の定義

以下の例は、Hello World サンプルアドオンのシンプルなText User Interface (TUI) スポークの実装を示しています。

前提条件

手順

  • 以下の例に従って、アドオン Text User Interface (TUI) のサポートを追加するために必要なすべての定義を含むモジュールを作成します。

例4.10 シンプルな TUI Spoke の定義

def init(self, app, data, storage, payload, instclass):
    """
    :see: simpleline.render.screen.UIScreen
    :param data: data object passed to every spoke to load/store data
                 from/to it
    :type data: pykickstart.base.BaseHandler
    :param storage: dummy object storing storage-related information
     :type storage: blivet.Blivet
    :param payload: object storing packaging-related information
    :type payload: pyanaconda.packaging.Payload

    """

    NormalTUISpoke.init(self, data, storage, payload)
    self.title = N_("Hello World")
    self._container = None
    self._hello_world_module = HELLO_WORLD.get_proxy()
    self._reverse = False
    self._entered_text = ""

def initialize(self):
    """
    The initialize method that is called after the instance is created.
    The difference between init and this method is that this may take
    a long time and thus could be called in a separate thread.

    :see: pyanaconda.ui.common.UIObject.initialize

    """

    NormalTUISpoke.initialize(self)
    self._reverse = self._hello_world_module.Reverse
    self._entered_text = "".join(self._hello_world_module.Lines)

def refresh(self, args=None):
    """
    The refresh method that is called every time the spoke is displayed.
    It should update the UI elements according to the contents of
    internal data structures.

    :see: pyanaconda.ui.common.UIObject.refresh
    :see: simpleline.render.screen.UIScreen.refresh
    :param args: optional argument that may be used when the screen is
                 scheduled
    :type args: anything

    """

    self._reverse = self._hello_world_module.Reverse
    self._entered_text = "".join(self._hello_world_module.Lines)

    self._container = ListColumnContainer(columns=1)
    self.window.add(self._container)

    self._container.add(CheckboxWidget(title="Reverse", completed=self._reverse),
                                   callback=self._change_reverse)
    self._container.add(EntryWidget(title="Hello world text", value=self._entered_text),
                                   callback=self._change_lines)

    self._window.add_separator()

def apply(self):
    """
    The apply method that is called when the spoke is left. It should
    update the contents of internal data structures with values set in the spoke.

    """

    self._hello_world_module.SetReverse(self._reverse)
    lines = self._entered_text.splitlines(True)
    self._hello_world_module.SetLines(lines)

def execute(self):
    """
    The execute method that is called when the spoke is left. It is
    supposed to do all changes to the runtime environment according to
    the values set in the spoke.

    """

    # nothing to do here
    pass

def input(self, args, key):
    """
    The input method that is called by the main loop on user's input.

    :param args: optional argument that may be used when the screen is
                 scheduled
    :type args: anything
    :param key: user's input
    :type key: unicode
    :return: if the input should not be handled here, return it, otherwise
                 return InputState.PROCESSED or InputState.DISCARDED if the input was
                 processed successfully or not respectively
    :rtype: enum InputState

    """

    if self._container.process_user_input(key):
        return InputState.PROCESSED_AND_REDRAW
    else:
        return super().input(args=args, key=key)
注記

ancestor の init のみを呼び出す場合は init メソッドを上書きする必要はありませんが、この例のコメントでは、一般的な方法でスポーククラスのコンストラクターへ渡された引数を記述します。

上の例では、以下のようになります。

  • initialize メソッドでは、スポークの内部属性のデフォルト値を設定します。これは、refresh メソッドにより更新され、apply メソッドによって内部データ構造を更新するために使用されます。
  • execute メソッドの目的は、GUI の同等のメソッドの目的と同じです。この場合、このメソッドは効果がありません。
  • input メソッドはテキストインターフェースに固有のものです。キックスタートまたは GUI には同等のものはありません。input メソッドはユーザーの対話を行います。
  • input メソッドは、入力された文字列を処理し、そのタイプと値に応じてアクションを取ります。上記の例は値を要求してから、それを内部属性 (キー) として保存します。より複雑なアドオンでは、通常、文字をアクションとして解析したり、数値を整数に変換したり、追加の画面を表示したり、ブール値を切り替えたりするなど、重要なアクションを実行する必要があります。
  • この入力を別の画面で処理する必要がある場合に備えて、入力クラスの return 値は、InputState enum または input 文字列自体のいずれかである必要があります。グラフィカルモードとは対照的に、スポークを離れる際に apply メソッドは自動的に呼び出されません。input メソッドから明示的に呼び出す必要があります。スポークの画面を閉じる (非表示にする) 場合も同様です。close メソッドから明示的に呼び出す必要があります。

別のスポークで入力した追加情報が必要な場合など、別の画面を表示するには、別の TUIObject をインスタンス化し、ScreenHandler.push_screen_modal() を使用してそれを表示します。

テキストベースのインターフェースの制限により、TUI スポークは非常によく似た構造を持つ傾向があり、ユーザーがチェックまたはチェックを外して入力する必要があるチェックボックスまたはエントリーの一覧で構成されます。