.. _tba-08-gui: Ajouter une interface graphique =============================== L'objectif de cette partie est d'ajouter une interface graphique au jeu. Cette interface permettra d'améliorer l'expérience utilisateur en offrant une interaction visuelle avec le jeu. Initial GitHub stuff -------------------- Ouvrir le codespace associé au repo que vous avez *forké* ou le dossier local si vous avez cloné le dépôt. Vous pouvez travailler alternativement dans le codespace ou en local si vous avez synchronisé votre travail avec le repo forké à la fin de chaque chapitre (section "Final GitHub Stuff" du chapitre précédent). A partir du terminal, récupérer la dernière version du jeu depuis votre dépôt :: $ git pull Utiliser l'extension ``GitLens`` pour examiner l'historique des commits, et en particulier les différences entre la version actuelle et la version précédente. **Pour ce chapitre vous devez récupérer une nouvelle branche depuis le dépôt initial** (le dépôt que vous avez forké au tout début du projet). Suivez les instructions ci-dessous pour ajouter cette branche à votre dépôt local et à votre fork sur GitHub. Vérifier que le dépôt initial est bien configuré comme dépôt distant nommé ``upstream`` :: $ git remote -v origin git@github.com:username/TBA.git (fetch) origin git@github.com:username/TBA.git (push) upstream https://github.com/DanielCourivaud/TBA.git (fetch) upstream https://github.com/DanielCourivaud/TBA.git (push) Si le dépôt ``upstream`` n'apparaît pas, l'ajouter avec la commande :: $ git remote add upstream https://github.com/DanielCourivaud/TBA.git Maintenant que le dépôt ``upstream`` est configuré, récupérer la nouvelle branche nommée ``tba-tk`` depuis ce dépôt :: $ git fetch upstream Switcher sur la nouvelle branche ``tba-tk`` :: $ git switch tba-tk Votre dépôt local pointe maintenant sur la branche ``tba-tk`` qui contient les modifications apportées pour ce chapitre. .. note:: Les branches ``main`` et ``tba-quests`` sont toujours présentes dans le dépôt local :: $ git branch main tba-quests * tba-tk ``main`` contient l'ensemble du travail réalisé jusqu'à présent, y compris l'intégration des quêtes réalisée au chapitre précédent. Observations des modifications globales --------------------------------------- Pour observer les modifications apportées dans cette branche, identifier d'abord les fichiers mis en jeu. Ici la branche ``main`` est utilisée comme référence :: $ git diff --name-status main tba-tk On observe que le dossier ``assets`` a été ajouté. Il contient les images utilisées par l'interface graphique. Dans cette version seuls quelques images de boutons ont été créées. C'est ici qu'il faudra placer toutes les images que vous souhaitez utiliser dans votre interface graphique, y compris les images représentant les lieux de votre univers. Ajout de l'interface graphique ------------------------------ La principale modification concerne le fichier ``game.py`` qui comporte maintenant deux nouvelles classes ``_StdoutRedirector`` et ``GameGUI``. La classe ``_StdoutRedirector`` permet de rediriger les sorties standard (print) vers le widget texte de l'interface graphique. C'est dans ce widget que les messages du jeu seront affichés (ils n'apparaîtront plus dans le terminal). .. quiz:: quizz-01 :title: Le widget texte .. warning:: Quelques indications pour les réponses à apporter : - Les lignes consécutives doivent être séparées par un tiret. Exemple : ``10-15`` ; - Les lignes non consécutives doivent être séparées par des virgules suivies d'un seul espace. Exemple : ``10, 11, 13, 17`` ; - Les objets doivent être décrits par la chaine de caractères utilisée par la commande :command:`type()`. Exemple : si la commande :command:`type()` retourne ````, la réponse est ``list``; - Lorsqu'il y a plusieurs réponses à fournir, elles doivent être dans l'ordre d'apparition dans le code et séparées par des virgules suivies d'un seul espace. Exemple : ``obj1, obj2, obj3`` ; - Les fonctions et les méthodes doivent comporter les parenthèses. Exemple : ``__init__()``. #. :quiz:`{"type":"FB","answer":"290", "size":5}` A quelle ligne est défini le widget texte ? #. :quiz:`{"type":"FB","answer":"296", "size":5}` A quelle ligne le widget texte est il positionné dans l'interface graphique ? #. :quiz:`{"type":"FB","answer":"195", "size":5}` A quelle ligne l'affichage du terminal est redirigé vers le widget ? #. :quiz:`{"type":"FB","answer":"294", "size":5}` A quelle ligne peut on changer la couleur du texte et de l'arrière plan ? La classe ``GameGUI`` est la classe principale de l'interface graphique. Elle hérite de la classe ``tk.Tk`` de la bibliothèque Tkinter. Cette classe gère la création et l'affichage de l'interface graphique, ainsi que l'interaction entre le joueur et le moteur du jeu. L'utilisation d'une interface graphique modifie le paradigme de programmation du jeu. En effet, dans une application graphique, le flux d'exécution est géré par une boucle d'événements (event loop) qui attend les actions de l'utilisateur (clics de souris, saisie clavier, etc.) et réagit en conséquence. Cela contraste avec la programmation séquentielle traditionnelle où le programme s'exécute de manière linéaire ou même avec la programmation orientée objet classique, telle qu'on l'a pratiquée jusqu'à présent. Le positionnement des widgets dans l'interface graphique est réalisé à l'aide de la méthode ``grid()`` qui permet de placer les widgets dans une grille définie par des lignes et des colonnes. Chaque widget peut occuper une ou plusieurs cellules de cette grille. Cette opération est chronophage et ne sera pas étudiée en détail ici. En conséquence il est très fortement conseillé de conserver la structure proposée. On peut synthétiser la création de l'interface graphique en trois étapes principales : - définition de la structure de l'interface graphique (layout) ; - création des widgets (boutons, zones de texte, etc.) ; - positionnement des widgets dans la grille. .. quiz:: quizz-02 :title: La classe GameGUI #. :quiz:`{"type":"FB","answer":"tk.Tk", "size":15}` La classe ``GameGUI`` hérite d'une classe, laquelle ? #. :quiz:`{"type":"FB","answer":"390", "size":5}` A quelle ligne entre t-on dans la boucle d'événements ? #. :quiz:`{"type":"FB","answer":"172, 173", "size":15}` A quelles lignes sont définies les dimensions de l'image ? #. :quiz:`{"type":"FB","answer":"178", "size":5}` A quelle ligne sont définies les dimensions de l'interface graphique ? #. :quiz:`{"type":"FB","answer":"182", "size":5}` A quelle ligne est établie la connexion entre le moteur du jeu et l'interface graphique ? #. :quiz:`{"type":"FB","answer":"_build_layout", "size":15}` Quelle méthode privée définit la composition de l'interface graphique ? #. :quiz:`{"type":"FB","answer":"191", "size":5}` A quelle ligne est elle appelée ? #. :quiz:`{"type":"FB","answer":"195", "size":5}` A quelle ligne est effectuée la redirection du terminal vers le widget texte ? #. :quiz:`{"type":"FB","answer":"243", "size":5}` A quelle ligne est défini le répertoire utilisé pour les images ? #. :quiz:`{"type":"FB","answer":"253, 260, 264, 268, 272, 278", "size":25}` A quelles lignes sont instanciés les boutons ? #. :quiz:`{"type":"FB","answer":"256, 263, 267, 271, 275, 281", "size":25}` A quelles lignes sont ils positionnés sur l'interface graphique ? #. :quiz:`{"type":"FB","answer":"305", "size":5}` A quelle ligne est définie la zone de saisie de texte ? #. :quiz:`{"type":"FB","answer":"306", "size":5}` A quelle ligne la zone de saisie de texte est elle positionnée dans l'interface graphique ? #. :quiz:`{"type":"FB","answer":"317", "size":5}` A quelle ligne est identifié le lieu dans lequel le joueur se trouve ? #. :quiz:`{"type":"FB","answer":"362", "size":5}` A quelle ligne l'instruction donné par le joueur est elle mise en oeuvre ? #. :quiz:`{"type":"FB","answer":"386", "size":5}` A quelle ligne le jeu est il lancé sans interface graphique ? #. :quiz:`{"type":"FB","answer":"390", "size":5}` A quelle ligne le jeu est il lancé avec interface graphique ? Modification des autres classes ------------------------------- Analyser les autres fichiers modifiés. .. quiz:: quizz-03 :title: Les autres fichiers #. :quiz:`{"type":"FB","answer":"room.py", "size":15}` Quel est le seul autre fichier modifié ? #. :quiz:`{"type":"FB","answer":"24", "size":5}` A quelle ligne ? Intégration de l'interface graphique ------------------------------------ A l'issue de la phase d'analyse, il faut maintenant porter les modifications vers votre jeu. .. admonition:: A faire Les modifications observées dans la branche ``tba-tk`` doivent être intégrées dans votre branche ``main``. Il faut donc s'assurer de revenir sur la branche ``main`` avant d'apporter la moindre modification. .. tip:: Utiliser l'extension ``GitLens`` et sa fonctionnalité ``SEARCH & COMPARE > Compare References...`` pour porter le code pertinent de la branche ``tba-tk`` vers la branche ``main`` par copier/coller. Assurez vous que toutes les commandes fonctionnent correctement et que l'interface graphique s'affiche bien. Ajouter des boutons pour les autres commandes. Créer des images de taille fixe pour représenter les lieux du jeu. Final GitHub stuff ------------------ Enregistrer les modifications apportées aux fichiers dans le repo local (codespace ou machine locale) :: $ git add . .. important:: Vous pouvez vérifier les statistiques de commit avec la commande :: $ git shortlog -s -n Ajouter un commit à l'historique :: $ git commit -m "Add gui" Votre historique doit ressembler à ceci : .. image:: images/tba-08-gui-gitgraph-01.png :width: 600px :align: center Pour référencer plus facilement cette version dans le futur, créer un tag :: $ git tag v6 Synchroniser votre codespace avec votre dépôt GitHub :: $ git push origin main --tags Vérifier que les modifications sont bien présentes dans le dépôt GitHub.