5.13. シンプルな TUI スポークを定義する
NormalTUISpoke クラスを継承したクラスを定義することで、シンプルなテキストユーザーインターフェイス (TUI) スポークを実装できます。
前提条件
- Anaconda add-on structure の説明に従って、tui ディレクトリーに新しいサブパッケージセットを作成している。
手順
以下の例に従って、アドオン Text User Interface (TUI) のサポートを追加するために必要なすべての定義を含むモジュールを作成します。
class HelloWorldSpoke(NormalTUISpoke): # category this spoke belongs to category = HelloWorldCategory def init(self, *args, kwargs): """ Create the representation of the spoke. :see: simpleline.render.screen.UIScreen """ super().init(*args, kwargs) self.title = N_("Hello World") self._hello_world_module = HELLO_WORLD.get_proxy() self._container = None self._reverse = False self._lines = "" 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 """ # nothing to do here super().initialize() def setup(self, args=None): """ The setup method that is called right before the spoke is entered. It should update its state according to the contents of DBus modules. :see: simpleline.render.screen.UIScreen.setup """ super().setup(args) self._reverse = self._hello_world_module.Reverse self._lines = self._hello_world_module.Lines return True def refresh(self, args=None): """ The refresh method that is called every time the spoke is displayed. It should generate the UI elements according to its state. :see: pyanaconda.ui.common.UIObject.refresh :see: simpleline.render.screen.UIScreen.refresh """ super().refresh(args) self._container = ListColumnContainer( columns=1 ) self._container.add( CheckboxWidget( title="Reverse", completed=self._reverse ), callback=self._change_reverse ) self._container.add( EntryWidget( title="Hello world text", value="".join(self._lines) ), callback=self._change_lines ) self.window.add_with_separator(self._container) def _change_reverse(self, data): """ Callback when user wants to switch checkbox. Flip state of the "reverse" parameter which is boolean. """ self._reverse = not self._reverse def _change_lines(self, data): """ Callback when user wants to input new lines. Show a dialog and save the provided lines. """ dialog = Dialog("Lines") result = dialog.run() self._lines = result.splitlines(True) def input(self, args, key): """ The input method that is called by the main loop on user's input. * If the input should not be handled here, return it. * If the input is invalid, return InputState.DISCARDED. * If the input is handled and the current screen should be refreshed, return InputState.PROCESSED_AND_REDRAW. * If the input is handled and the current screen should be closed, return InputState.PROCESSED_AND_CLOSE. :see: simpleline.render.screen.UIScreen.input """ if self._container.process_user_input(key): return InputState.PROCESSED_AND_REDRAW if key.lower() == Prompt.CONTINUE: self.apply() self.execute() return InputState.PROCESSED_AND_CLOSE return super().input(args, key) def apply(self): """ The apply method is not called automatically for TUI. It should be called in input() if required. It should update the contents of internal data structures with values set in the spoke. """ self._hello_world_module.SetReverse(self._reverse) self._hello_world_module.SetLines(self._lines) def execute(self): """ The execute method is not called automatically for TUI. It should be called in input() if required. It is supposed to do all changes to the runtime environment according to the values set in the spoke. """ # nothing to do here pass詳細と最新のコードは、Hello World Anaconda Addon - GitHub Repository を参照してください。
注記ancestor の
initのみを呼び出す場合はinitメソッドを上書きする必要はありませんが、この例のコメントでは、一般的な方法でスポーククラスのコンストラクターへ渡された引数を記述します。前述の例は以下のとおりです。
-
setupメソッドは、各エントリーのスポークの内部属性のデフォルト値を設定します。これは、refreshメソッドによって表示され、inputメソッドによって更新され、applyメソッドによって使用されて内部データ構造を更新します。 -
executeメソッドの目的は、GUI の同等のメソッドの目的と同じです。この場合、このメソッドは効果がありません。 -
inputメソッドはテキストインターフェイスに固有のものです。キックスタートまたは GUI には同等のものはありません。inputメソッドはユーザーの対話を行います。 -
inputメソッドは、入力された文字列を処理し、そのタイプと値に応じてアクションを取ります。上記の例では、任意の値を要求し、それを内部属性 (キー) として保存します。より複雑なアドオンでは、通常、文字をアクションとして解析したり、数値を整数に変換したり、追加の画面を表示したり、ブール値を切り替えたりするなど、重要なアクションを実行する必要があります。 この入力を別の画面で処理する必要がある場合に備えて、入力クラスの
return値は、InputStateenum またはinput文字列自体のいずれかである必要があります。グラフィカルモードとは対照的に、applyメソッドとexecuteメソッドは、スポークを離れるときに自動的に呼び出されません。入力メソッドから明示的に呼び出す必要があります。スポークの画面を閉じる (非表示にする) 場合も同様です。closeメソッドから明示的に呼び出す必要があります。別のスポークで入力した追加情報が必要な場合など、別の画面を表示するには、別の
TUIObjectをインスタンス化し、ScreenHandler.push_screen_modal()を使用してそれを表示します。テキストベースのインターフェイスの制限により、TUI スポークは非常によく似た構造を持つ傾向があり、ユーザーがチェックまたはチェックを外して入力する必要があるチェックボックスまたはエントリーのリストで構成されます。