5.13. Définition d'une branche simple de l'interface utilisateur


L'exemple suivant montre la mise en œuvre d'une interface utilisateur textuelle (TUI) simple dans l'exemple de module complémentaire Hello World :

Conditions préalables

Procédure

  • Créez des modules avec toutes les définitions nécessaires pour ajouter la prise en charge de l'interface utilisateur textuelle (TUI), conformément aux exemples suivants :

Exemple 5.11. Définition d'une branche simple de l'interface utilisateur

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 separated 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
Note

Il n'est pas nécessaire de surcharger la méthode init si elle n'appelle que la méthode de l'ancêtre initmais les commentaires de l'exemple décrivent de manière compréhensible les arguments transmis aux constructeurs des classes parlantes.

Dans l'exemple précédent :

  • La méthode setup définit une valeur par défaut pour l'attribut interne du rayon à chaque entrée, qui est ensuite affichée par la méthode refresh, mise à jour par la méthode input et utilisée par la méthode apply pour mettre à jour les structures de données internes.
  • La méthode execute a le même objectif que la méthode équivalente dans l'interface graphique ; dans ce cas, la méthode n'a pas d'effet.
  • La méthode input est spécifique à l'interface texte ; il n'y a pas d'équivalent dans Kickstart ou GUI. Les méthodes input sont responsables de l'interaction avec l'utilisateur.
  • La méthode input traite la chaîne saisie et prend des mesures en fonction de son type et de sa valeur. L'exemple ci-dessus demande une valeur quelconque et la stocke en tant qu'attribut interne (clé). Dans les modules complémentaires plus complexes, vous devez généralement effectuer des actions non triviales, telles que l'analyse des lettres en tant qu'actions, la conversion des nombres en nombres entiers, l'affichage d'écrans supplémentaires ou le basculement de valeurs booléennes.
  • La valeur return de la classe d'entrée doit être soit l'énumération InputState, soit la chaîne input elle-même, au cas où cette entrée devrait être traitée par un écran différent. Contrairement au mode graphique, les méthodes apply et execute ne sont pas appelées automatiquement lorsqu'on quitte le rayon ; elles doivent être appelées explicitement depuis la méthode input. Il en est de même pour la fermeture (masquage) de l'écran du rayon : elle doit être appelée explicitement depuis la méthode close.

Pour afficher un autre écran, par exemple si vous avez besoin d'informations supplémentaires qui ont été saisies dans un autre rayon, vous pouvez instancier un autre TUIObject et utiliser ScreenHandler.push_screen_modal() pour l'afficher.

En raison des restrictions imposées par l'interface textuelle, les rayons de l'interface utilisateur ont tendance à avoir une structure très similaire, qui consiste en une liste de cases à cocher ou d'entrées qui doivent être cochées ou décochées et remplies par l'utilisateur.

Red Hat logoGithubRedditYoutubeTwitter

Apprendre

Essayez, achetez et vendez

Communautés

À propos de la documentation Red Hat

Nous aidons les utilisateurs de Red Hat à innover et à atteindre leurs objectifs grâce à nos produits et services avec un contenu auquel ils peuvent faire confiance.

Rendre l’open source plus inclusif

Red Hat s'engage à remplacer le langage problématique dans notre code, notre documentation et nos propriétés Web. Pour plus de détails, consultez leBlog Red Hat.

À propos de Red Hat

Nous proposons des solutions renforcées qui facilitent le travail des entreprises sur plusieurs plates-formes et environnements, du centre de données central à la périphérie du réseau.

© 2024 Red Hat, Inc.