5.14. NormalTUISpoke を使用したテキストインターフェイススポークの定義


Defining a Simple TUI Spoke の例では、メソッドが利用可能かつ提供されるデータの出力と処理に対処する TUI スポークを実装する方法が示されました。ただし、pyanaconda.ui.tui.spokes パッケージの NormalTUISpoke クラスを使用してこれを実現する別の方法があります。このクラスを継承することで、設定する必要のあるフィールドと属性を指定するだけで、一般的な TUI スポークを実装できます。以下の例で説明します。

前提条件

  • Anaconda アドオン構造 で説明されているように、TUI ディレクトリーの下に新しいサブパッケージのセットを追加しました。

手順

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

    class HelloWorldEditSpoke(NormalTUISpoke):
        """Example class demonstrating usage of editing in TUI"""
        category = HelloWorldCategory
    
        def init(self, data, storage, payload):
            """
            :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: object storing storage-related information
                            (disks, partitioning, boot loader, etc.)
            :type storage: blivet.Blivet
            :param payload: object storing packaging-related information
            :type payload: pyanaconda.packaging.Payload
            """
            super().init(self, *args, **Kwargs)
    
            self.title = N_("Hello World Edit")
            self._container = None
    
            # values for user to set
            self._checked = False
            self._unconditional_input = ""
            self._conditional_input = ""
    
        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 self.data.
            :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
            """
            super().refresh(args)
            self._container = ListColumnContainer(columns=1)
    
            # add ListColumnContainer to window (main window container)
            # this will automatically add numbering and will call callbacks when required
            self.window.add(self._container)
    
            self._container.add(CheckboxWidget(title="Simple checkbox", completed=self._checked),
                                callback=self._checkbox_called)
            self._container.add(EntryWidget(title="Unconditional text input",
                                            value=self._unconditional_input),
                                callback=self._get_unconditional_input)
    
            # show conditional input only if the checkbox is checked
            if self._checked:
                self._container.add(EntryWidget(title="Conditional password input",
                                                value="Password set" if self._conditional_input
                                                else ""),
                                    callback=self._get_conditional_input)
    
            self.window.add_with_separator(self._container)
    
        def _checkbox_called(self, data):  # pylint: disable=unused-argument
            """Callback when user wants to switch checkbox.
    
            :param data: can be passed when adding callback in container (not used here)
            :type data: anything
            """
            self._checked = not self._checked
    
        def _get_unconditional_input(self, data):  # pylint: disable=unused-argument
            """Callback when the user wants to set unconditional input.
    
            :param data: can be passed when adding callback in container (not used here)
            :type data: anything
            """
            dialog = Dialog(
                "Unconditional input",
                conditions=[self._check_user_input]
            )
            self._unconditional_input = dialog.run()
    
        def _get_conditional_input(self, data):  # pylint: disable=unused-argument
            """Callback when the user wants to set conditional input.
    
            :param data: can be passed when adding callback in container (not used here)
            :type data: anything
            """
            dialog = PasswordDialog(
                "Unconditional password input",
                policy_name=PASSWORD_POLICY_ROOT
            )
            self._conditional_input = dialog.run()
    
        def _check_user_input(self, user_input, report_func):
            """Check if the user has written a valid value.
    
            :param user_input: user input for validation
            :type user_input: str
    
            :param report_func: function for reporting errors on user input
            :type report_func: func with one param
            """
            if re.match(r'^\w+$', user_input):
                return True
            else:
                report_func("You must set at least one word")
                return False
    
        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, key)
    
    
        @property
        def completed(self):
            # completed if user entered something non-empty to the Conditioned input
            return bool(self._conditional_input)
    
        @property
        def status(self):
            return "Hidden input %s" % ("entered" if self._conditional_input
                                        else "not entered")
    
        def apply(self):
            # nothing needed here, values are set in the self.args tree
            pass
    Copy to Clipboard Toggle word wrap

    詳細と最新のコードは、Hello World NormalTUISpoke - GitHub Repository を参照してください。

トップに戻る
Red Hat logoGithubredditYoutubeTwitter

詳細情報

試用、購入および販売

コミュニティー

Red Hat ドキュメントについて

Red Hat をお使いのお客様が、信頼できるコンテンツが含まれている製品やサービスを活用することで、イノベーションを行い、目標を達成できるようにします。 最新の更新を見る.

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。このような変更は、段階的に実施される予定です。詳細情報: Red Hat ブログ.

会社概要

Red Hat は、企業がコアとなるデータセンターからネットワークエッジに至るまで、各種プラットフォームや環境全体で作業を簡素化できるように、強化されたソリューションを提供しています。

Theme

© 2025 Red Hat