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
- Vous avez créé un nouvel ensemble de sous-paquets dans le répertoire tui comme décrit dans la structure des modules complémentaires Anaconda.
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
Il n'est pas nécessaire de surcharger la méthode init
si elle n'appelle que la méthode de l'ancêtre init
mais 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éthoderefresh
, mise à jour par la méthodeinput
et utilisée par la méthodeapply
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éthodesinput
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érationInputState
, soit la chaîneinput
elle-même, au cas où cette entrée devrait être traitée par un écran différent. Contrairement au mode graphique, les méthodesapply
etexecute
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éthodeclose
.
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.