[Tutoriel] Glade3 et PyGi


Dans cet article on va comprendre les bases de la création d'une interface utilisateur à l'aide de Glade3 (User interface Designer) et PyGi (PyGObject).
Ce tutoriel traitera un exemple simple et basique et se sera centré sur l'appel des méthodes de PyGi et la manière de lier un fichier XML généré par Glade3 et notre code en PyGi.
Assez parler! Débutons ... !

Création d'une fenêtre de type Top Level nommée (son id) Window1:


Modifier l'affichage de la fenêtre et la forcer à apparaître au centre de l'écran:


Modifier le titre de la fenêtre:


Modifier les dimensions de la fenêtre par défaut:


Utiliser Grid comme Container (La liste des container est regroupée sur Glade, mais dans cet exemple on va utiliser uniquement Grid avec une dimension 3x3 nommé Grid1):



La fenêtre sera divisée comme suit:


Notre Grid sera ajouté automatiquement à l'hiérarchie de Window1 :



Dans Grid1 on ajoute ces Widgets listés dans le champs Control and display de Glade3. On aura une interface similaire à cella:


La liste des éléments et leur types ajoutés à Window1 s'affichent comme suit:


On modifie les propriétés de button1 (bouton ajouté à Windows1). On modifie le nom qui s'affiche sur le bouton et on le renomme  Sortir :


On ajoute un signal (événement) à button1 de type clicked et on lie le signal à la méthode on_button :


On ajoute un signal (événement) à comboboxtext1 de type changed et on lie le signal à la méthode on_comboboxtext :



On ajoute le signal (événement) à checkbutton1 de type toggled et on lie le signal à la méthode on_toggle :



On ajoute le signal (événement) à entry1 de type activate et on lie le signal à la méthode on_entry_activate:



On ajoute le signal (événement) au searchentry1 et de type activate et on lie le signal à la méthode on_entry_activate:


Le logiciel s'affichera comme suit:



Pour le widget checkbutton1 on va le faire manuellement en modifiant le fichier XML généré par Glade. On va ajouter le signal au child switch1 (qui signifie que switch1 est l'enfant de Window1) comme ceci:

<signal name="notify::active" handler="on_switch_activate" swapped="no"/>
 

Cette ligne se traduit avec PyGi en:

switch1.connect("notify::active", on_switch_activate)
 

Ceci dit lier switch1 à un signal de type notify::active (notification active)

Sans beaucoup étaler le tutoriel, voilà le fichier XML généré par Glade3 et le code source en PyGi avec des commentaires pour comprendre l'utilisation et le fonctionnement de chaque ligne.


Code source du fichier XML de Glade3:

<!--

Exemple mis en ligne par: Chiheb NeXus

Licence : Aucune licence!

Langage de programmation: XML généré par Glade3

-->



<?xml version="1.0" encoding="UTF-8"?>

<!-- Generated with glade 3.16.1 -->

<interface>

  <requires lib="gtk+" version="3.10"/>

  <object class="GtkWindow" id="window1">

    <property name="can_focus">False</property>

    <property name="title" translatable="yes">Test Glade3 &amp; PyGi (Python3)</property>

    <property name="window_position">center-always</property>

    <property name="default_width">500</property>

    <property name="default_height">250</property>

    <child>

      <object class="GtkGrid" id="grid1">

        <property name="visible">True</property>

        <property name="can_focus">False</property>

        <child>

          <object class="GtkButton" id="button1">

            <property name="label" translatable="yes">Sortir</property>

            <property name="visible">True</property>

            <property name="can_focus">True</property>

            <property name="receives_default">True</property>

            <property name="image_position">top</property>

            <signal name="clicked" handler="on_button" swapped="no"/>

          </object>

          <packing>

            <property name="left_attach">0</property>

            <property name="top_attach">0</property>

            <property name="width">1</property>

            <property name="height">1</property>

          </packing>

        </child>

        <child>

          <object class="GtkSwitch" id="switch1">

            <property name="visible">True</property>

            <property name="can_focus">True</property>

           

            <!-- Ajout de l'appel du signal dans l'XML généré par Glade3 manuellement et lier

            le widget switch1 à un signal de type notify::active qui va pointer sur la méthode

            on_switch_activate

             -->

            <signal name="notify::active" handler="on_switch_activate" swapped="no"/>

          </object>

          <packing>

            <property name="left_attach">1</property>

            <property name="top_attach">0</property>

            <property name="width">1</property>

            <property name="height">1</property>

          </packing>

        </child>

        <child>

          <object class="GtkComboBoxText" id="comboboxtext1">

            <property name="visible">True</property>

            <property name="can_focus">False</property>

            <property name="button_sensitivity">on</property>

            <items>

              <item translatable="yes">NeXus</item>

              <item translatable="yes">Nymph</item>

              <item translatable="yes">Tristiana</item>

              <item translatable="yes">Auroroe</item>

              <item translatable="yes">Liturgy</item>

            </items>

            <signal name="changed" handler="on_comboboxtext" swapped="no"/>

          </object>

          <packing>

            <property name="left_attach">2</property>

            <property name="top_attach">0</property>

            <property name="width">1</property>

            <property name="height">1</property>

          </packing>

        </child>

        <child>

          <object class="GtkCheckButton" id="checkbutton1">

            <property name="label" translatable="yes">checkbutton</property>

            <property name="visible">True</property>

            <property name="can_focus">True</property>

            <property name="receives_default">False</property>

            <property name="xalign">0</property>

            <property name="draw_indicator">True</property>

            <signal name="toggled" handler="on_toggle" swapped="no"/>

          </object>

          <packing>

            <property name="left_attach">0</property>

            <property name="top_attach">1</property>

            <property name="width">1</property>

            <property name="height">1</property>

          </packing>

        </child>

        <child>

          <object class="GtkRadioButton" id="radiobutton1">

            <property name="label" translatable="yes">radiobutton</property>

            <property name="visible">True</property>

            <property name="can_focus">True</property>

            <property name="receives_default">False</property>

            <property name="xalign">0</property>

            <property name="active">True</property>

            <property name="draw_indicator">True</property>

          </object>

          <packing>

            <property name="left_attach">1</property>

            <property name="top_attach">1</property>

            <property name="width">1</property>

            <property name="height">1</property>

          </packing>

        </child>

        <child>

          <object class="GtkEntry" id="entry1">

            <property name="visible">True</property>

            <property name="can_focus">True</property>

            <property name="text" translatable="yes">Put your text and press Enter</property>

            <signal name="activate" handler="on_entry_activate" swapped="no"/>

          </object>

          <packing>

            <property name="left_attach">1</property>

            <property name="top_attach">2</property>

            <property name="width">2</property>

            <property name="height">1</property>

          </packing>

        </child>

        <child>

          <object class="GtkSearchEntry" id="searchentry1">

            <property name="visible">True</property>

            <property name="can_focus">True</property>

            <property name="primary_icon_name">edit-find-symbolic</property>

            <property name="primary_icon_activatable">False</property>

            <property name="primary_icon_sensitive">False</property>

            <signal name="activate" handler="on_entry_activate" swapped="no"/>

          </object>

          <packing>

            <property name="left_attach">2</property>

            <property name="top_attach">1</property>

            <property name="width">1</property>

            <property name="height">1</property>

          </packing>

        </child>

        <child>

          <placeholder/>

        </child>

      </object>

    </child>

  </object>

</interface>



Code source en PyGi de l'exemple: 

#!/user/bin/python
# -*- coding: utf-8 -*-
###################################################################
# Exemple mis en ligne par: Chiheb NeXus
# Licence : Aucune licence!
# Langage de programmation: Python3 et PyGi (PyGtk Version 3)
###################################################################

from gi.repository import Gtk

class Handler():
 """
 - Mettre tous les signaux dans une seule classe
 - NB: Dans PyGi les argements des méthodes sont des widgets intermédiaires qui héritent toutes les caractéristiques 
   des widgets d'origine. Ceci dit, si on essaye de donner une action à un widget de type "button" nommé "button1"
   dans la partie du code on écrit: def action(self, intermerdiare):
   intermerdiare hérite toutes les caractéristiques de button1 et l'action sur intermerdiare est une action indirecte sur button1
   Ceci est peut être bien expliqué en C/GTK+ vu que PyGi est en quelques sorte un porjet réecrit depuis C/GTK+.
 - Ps: Lors d'une utilisation avancée de PyGi, les signaux jouent un rôle primordial dans la création de notre Gui.
      C'est pourquoi une maîtrise de l'utilisation des signaux est fortement récommendée et, aussi, la modification du ficher XML
      généré par Glade3 est, aussi, récommendée.

 - Dans cet exemple, notre programme principale n'est pas mis dans une classe à part, vu sa simplicité. Mais, dans un programme
      avancé, une bonne maîtrise de Python et de PyGi est nécessaire.
      Glade3 ne permet que réduire le temps de création de Gui et éviter la création de l'interface à la main.
      Cependant, ceci ne veut pas dire qu'on va oublier les manipulations manuelles pour parvenir aux résultas voulus.

 - Documentation sur Github:

     1- Toutes les méthodes Gtk.methodes (exemple: Gtk.main_quit())
      https://lazka.github.io/pgi-docs/#Gtk-3.0/functions.html

     2- Les méthodes supportées par Gtk.Button() {Comment interéagir avec les widgets de type Gtk.Button()}
      https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/Button.html#Gtk.Button

     3- Les méthodes supportées par Gtk.Entry() {Comment interéagir avec les widgets de type Gtk.Entry()}
      https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/Entry.html#Gtk.Entry

     4- Les méthodes supportées par Gtk.Switch() {Comment interéagir avec les widgets de type Gtk.Switch()}
      https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/Switch.html#Gtk.Switch

     5- Les méthodes supportées par Gtk.ComboBoxText() {Comment interéagir avec les widgets de type Gtk.ComboBoxText()}
      https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/ComboBoxText.html#Gtk.ComboBoxText

     6- Les méthodes supportées par Gtk.ToggleButton() {Comment interéagir avec les widgets de type Gtk.ToggleButton()}
      https://lazka.github.io/pgi-docs/#Gtk-3.0/classes/ToggleButton.html#Gtk.ToggleButton

     7- Les méthodes supportées par Gtk.SearchEntry() {Comment interéagir avec les widgets de type Gtk.SearchEntry()}
      https://lazka.github.io/pgi-docs/#RB-3.0/classes/SearchEntry.html#RB.SearchEntry 

  - Pour plus d'informations: https://lazka.github.io/pgi-docs/

 """

 def on_button(self, button):
  """
  - Gtk.main_quit(): Est une fonction par défaut de PyGi
            qui permet de sortir de la boucle infinie de l'interface en Gtk+ en utilisant Python 
  - La méthode utilise le mot "self" et "button" comme arguments
  - "button" joue le rôle d'un widget intermédiaire entre button1 et cette partie de code
  """
  Gtk.main_quit()

 def on_switch_activate(self, switch, args):
  """
  - "switch" est un widget intermédiaire entre "switch1" et cette partie de code
         et args est l'argument passé à la méthode lors de l'appel de widget "switch1"
  - switch.get_active() : Cette méthode retourne "True" ou "False" 
      => "True" = Le bouton (widget) est actif / "False" = Le bouton (widget) est inactif 

  """
  if switch.get_active():
   # Bouton actif
   print("Switch activé!")
  else:
   # L'inverse 
   print("Switch désactivé!")

 def on_comboboxtext(self, combobox):
  """
  - L'ajout des éléments à ComboBoxText est faite sous Glade3
  - Cette méthode affichera uniquement les noms stockés dans le fichier XML générée par Glade3
  - combobox.get_active_text() : Retourne le text activé de widget ComboBoxText lors de la saisie dans l'interface UI 
       Le type de retour est une chaine de caractaire (String) et l'affiche sera sous la terminale
  """
  # On vérifie si combobox est vide ou non.
  # S'il est vide, il n'y aura aucun affichage sinon on affiche le contenu

  if combobox.get_active_text() != None:
   print("L'élément saisi est: " + combobox.get_active_text())

 def on_toggle(self, toggle):
  """
  - Le bouton "toggle1" affiche sur la terminale "Toggle button est activé!" ou "Toggle button est désactivé"
  - toggle.get_active() : Retourne "True" ou "False" et qui permet de vérifier l'état de widget (activé ou non)
  - L'affiche est sous la terminale
  """
  if toggle.get_active():
   print("Toggle button est activé!")
  else: 
   print("Toggle button est désactivé")

 def on_entry_activate(self, entry):
  """
  - Affichage du text saisi dans "entry1" et "seachentry1"
  - entry est un widget intermédiaire entre "entry1" et "seachentry1" 
  - entry.get_text(): Retourne le text entré dans "entry1" et "seachentry1"
  - L'affiche sera sur la terminale
  """
  txt = entry.get_text()
  print(txt)


#builder est de type Gtk.Builder() : Notre constructeur du fichier XML de Glade
builder = Gtk.Builder()

# Ajouter le chemin de fichier d'interface générée par Glade
builder.add_from_file("test.glade")  

# Tous les signaus sont mis dans une classe nommée Handler()
builder.connect_signals(Handler()) 

# window est un objet qui hérite toutes les méthodes de window1
window = builder.get_object("window1") 

# Affichage de la fenêtre window = Affichage de la fenêtre window1
window.show_all()   

# Lier la fenêtre principale à un signal de destruction de la fenêtre
window.connect("delete-event",Gtk.main_quit)  

# Lancer la boucle infinie qui permettera de visualiser l'interface indéfiniment sauf s'il y aura une intervention
# de l'utilisateur ou du programme interne 
Gtk.main() 


Code source: GladePyGi

[PyQt4] Convertisseur de devise


Convertisseur de devise est une application développée avec PyQt4.
Ce logiciel permet de convertir en temps réel les devises nationales des pays en s'appuyant sur les données mises en ligne de la Banque de Canada (url:http://www.bankofcanada.ca/en/markets/csv/exchange_eng.csv). Ce logiciel permet aussi de convertir en temps réel 1 Bitcoin en devises nationales en s'appuyant sur le données mis en ligne sur le site Bitpay (url: http://www.bitpay.com) et sur d'afficher l'évolution de Litecoin en s'appuyant sur les données du site Btc-E (url: http://www.btc-e.com).
Source: Github.

[PyGObject] Calculatrice PyGtk


Calculatrice PyGtk3+ est une calculatrice basique développée sous Python3 et en utilisant le module PyGObject (nommé aussi PyGI). 

Le principe de cette calculatrice est simple : 
 - L'utilisateur écrit les nombres de son équation
 - L'affichage est immédiat des nombres
 - Le point "." est remplacé lors de l'affichage par une virgule "," , mais il est utilisé comme un point lors des calculs internes de l'application
 - L'idée du calcule repose sur la fonction eval ,qui est une fonction propre à Python 3.xx, qui prend le texte affiché dans la Gtk.Entry (nommée : "entree" dans notre application) et le calcule. 
- En cas d'erreur lors de la saisie, rien ne se passe jusqu'à la correction de la syntaxe entrée.

**Fix & update** 27/10/2014 : 
  • Ajout des icônes sur les boutons : "Fermer", "Effacer tout" et "effacer le dernier chiffre"
  • Ajout des parenthèses "(" et ")"
  • Ajout du racine carré et de la méthode "calcul_racine"
  • Le bouton "=" occupe maintenant deux colonnes
**Fix ** 28/10/2014 :
  • Correction de la méthode "calcul_racine" et optimisation du code grâce à arshajii du forum stackoverflow.com
**Fix & Update** 29/10/2014  :
  • Ajout des fonctions trigonométriques
  • Optimisation du code
  • Création d'un dossier pour le logo et l'icône
**Update** 30/10/2014  :
  • Ajouter un sub-menu pour choisir le font et la taille de la Gtk.Entry

Vous pouvez télécharger le code source de Calculatrice PyGtk sur Github ou bien sur Google Drive

[PyGObject] Youtube-dl Pygtk Gui


Youtube-dl PyGtk Gui est une interface graphique du célèbre youtube-dl, crée avec Python 3.xx en utilisant le module Python PyGtk3 (PyGObject nommé aussi PyGI) et GLib.

Beaucoup de mots difficiles ? hein ?
Pas de problème. Je vais tout expliquer par la suite .

youtube-dl : Est un programme tournant sur presque tous les systèmes d'exploiations (Windows, Mac OS X, Gnu/Linux, Unix, Unix-like, BSD , etc...). Cette portabilité est due au  langage de programmation Python qui s'exécute sur les différents systèmes d'exploitations cités (autres aussi).

Python : est un langage de programmation objet, multi-paradigme et multiplateformes. Il favorise la programmation impérative structurée, fonctionnelle et orientée objet. Il est doté d'un typage dynamique fort, d'une gestion automatique de la mémoire par ramasse-miettes et d'un système de gestion d'exceptions ; il est ainsi similaire à Perl, Ruby, Scheme, Smalltalk et Tcl. La dernière version stable de Python est Pyton 3.4.2. (source Wikipédia)

PyGtk3 : Est un module Python permettant la création d'interfaces graphiques utilisant la bibliothèque GTK2. Depuis la version GTK3, PyGObject (appelé aussi : PyGI) remplace PyGtk dans ce rôle.
PyGObject (PyGI) : Est une liaison entre Python et GLib/GObject/GIO/Gtk+. Ce qui signifie : PyGI est une module Python qui donne accès propre et conforme à l'ensemble de la plateforme de logiciel de GNOME grâce à l'utilisation de l'introspection GObject.

GLib : est une bibliothèque libre de manipulation de structures de données - arbres, table de hachage et listes. Elle a commencé en tant qu'élément de GTK+, mais est utilisée maintenant par de nombreuses applications.
C'était à l'origine une bibliothèque utilisée comme fourre-tout pour le code bas niveau. Elle s'est désormais étendue pour offrir des fonctionnalités diverses qui sont en plus portables.
GLib fait partie du paquet GTK+ du projet GNU. Elle est distribuée selon les termes de la licence GNU LGPL.


Ouuuuf !! Des définitions, des définitions et encore des définitions !!

N'ayez pas peur. Il faut connaître ces outils pour ne pas se casser la tête en tout créant du point de départ (from scartch). Python et tous ces modules nous facilitent la vie et nous donnent un accès à une multitude de choix pour ne pas compliquer la création des GUI.
En effet, je me rappelle de mon professeur d'analyse quand il nous a dit pour ne pas compliquer la résolution de cette équation, on la traite avec les nombres complexes et la résultat sera directe.
Notre cas suit la règle de mon professeur : Pour créer une interface graphique basée sur GTK+, faudra bien connaître nos outils de travail et savoir les manipuler.

Assez de théorique. Un peu de pratique.
Le code source de "Youtube-dl PyGtk Gui" peut être téléchargé soi sur Google Drive ou bien sur Github.


  • Explication du concept générale du programme :


"Youtube-dl PyGtk Gui" est une interface graphique qui se base sur "youtube-dl" qui pourra être téléchargé et installé via ce lien (lien officiel de youtube-dl).
Lors du lancement de "Youtube-dl PyGtk Gui", l'utilisateur doit entrer l'URL de la vidéo youtube qu'il veut télécharger, puis choisir le format souhaité (pour l'instant la GUI supporte les formats MP4 et FLV, les autres formats et fonctionnalités seront ajoutées dans les prochaines versions du programme). L'appui sur le bouton télécharger actionne youtube-dl en lui envoyant l'option du téléchargement d'une vidéo, la format et l'URL. Les informations collectées par notre GUI et affichées sur son TextView (espace de visualisation textuel). L'appui sur le bouton Stopper, annule le téléchargement et stoppe la barre de progression "ProgressBar".


  • Explication de quelques concepts du code utilisé :
Je dois remercier gianmant du forum  stackoverflow pour l'idée de l’a-synchronisation en utilisant GLib :


GLib.source_remove(self.source_id_out) : Enlever self.source_id_out de la boucle principale.
Gtk.events_pending() : Retourne "True" s'il y a un événement en attente dans le programme et "False" dans le cas contraire.
Gtk.main_iteration_do(False) : Ne pas bloquer l'itération du programme
GLib.spawn_async(params,flags=GLib.SpawnFlags.SEARCH_PATH|\
GLib.SpawnFlags.DO_NOT_REAP_CHILD,standard_output=True,standard_error=True) :
 La définition générale est : GLib.spawn_async(arguments,flags,child,setup,standard_output,standard_error)
GLib.spawn_async appelle la fonction GLib.spawn_async_with_pipes sans les pipes, Donc : GLib.spawn_async = Exécute un programme enfant (child)de manière asynchrone. Ce qui signifie que le programme ne sera pas bloqué en attendant l'enfant (processus enfant) pour quitter.
io = GLib.IOChannel(stdout) : Création d'une variable qui stock les informations du socket de retour
err = GLib.IOChannel(stderr) : Création d'une variable qui stock les informations du socket d'erreur
self.source_id_out = io.add_watch(GLib.IO_IN|GLib.IO_HUP, write_to_textview,self.tw_out,priority=GLib.PRIORITY_HIGH) : La définition générale est : def glib.io_add_watch(file id, condition, callback, addional arguments ...)                               File ID : GLib.IO_IN = Date to read / GLib.IO_HUP = Hang UP / GLib.IO_ERR =  Condition d'erreur / GLib.IO_out = Données peuvent être écrites / Glib.IO_PRI = Données urgentes pour la lecture . add_watch : contrôle le file id par la condition ajoutée et si la condition est vraie, callback sera exécuté
GLib.spawn_close_pid(pid)  : Faut fermer GLib.spawn_asyn avec GLib.spawn_close_pid()


  • Mise à jour : 

18/10/2014 Fixed - Support des formats suivants :
  • WEBM [Audio Basse Qualité]
  • M4A [Audio]
  • MP4 [Vidéo 144p]
  • WEBM [Vidéo 240p]
  • MP4 [Vidéo 240p]
  • WEBM [Vidéo 360p]
  • MP4 [Vidéo 360p]
  • WEBM [Vidéo 480p]
  • MP4 [Vidéo 480p]
  • WEBM [Vidéo 720p]
  • MP4 [Vidéo 720p]
  • WEBM [Vidéo 1080p]
  • MP4 [Vidéo 1080p]
  • 3GP [Vidéo 176x144]
  • 3GP [Vidéo 320x240]
  • FLV [Vidéo 400x240]
  • WEBM [Vidéo 640x360]
  • MP4 [Vidéo 640x360]
  • MP4 [Vidéo 1280x720 Meilleure Qualité]
    • Une seule zone d'affichage du traitement lors du téléchargement
    • Ajout de deux fenêtres de dialogues en cas de mauvaise manipulation du logiciel
    • Ajout de la repository GitHub
09/11/2014 Update :

  • Optimisation du code source
  • Fenêtre de taille fixe
  • VBox homogène
  • Traduction de la Gui en anglais
11/11/2014 Update :

  • Ajout d'une interface de choix de langue (Français et anglais)



[Tutoriel] Oscillographe d'un mouvement harmonique

Dans ce billet on va explorer un autre exemple d'un programme crée avec Python 3 en utilisant le module "Tkinter" (nommé aussi : Tk). 
Ce billet utilisera des techniques vues dans ce billet et dans ce billet , qui nous permettront de représenter un mouvement vibratoire harmonique inspiré des cours de physique. 

Pour rappel, un mouvement vibratoire harmonique se définit comme étant la projection d ’ un
mouvement circulaire uniforme sur une droite. Les positions successives d ’ un mobile qui effectue ce type de mouvement sont traditionnellement repérées par rapport à une position
centrale : on les appelle alors des élongations. ’ équation qui décrit l’ évolution de l’ élongation
d’un tel mobile au cours du temps est toujours de la forme :
 , dans laquelle "e" représente l'élongation du mobile à tout instant t . Les constantes A, f et φ désignent respectivement l’ amplitude, la fréquence et la phase du mouvement vibratoire.
Le but du présent projet est de fournir un instrument de visualisation simple de ces différents
concepts, à savoir un système d ’ affichage automatique de graphiques élongation/temps. 
L’utilisateur pourra choisir librement les valeurs des paramètres A, f et φ, et observer les courbes qui en résultent.
Donc, en premier lieu, on créera un module nommé "oscillographe.py" qui contiendra le "Canvas" principale où les courbes seront affichées. Puis, on créera un autre fichier avec un code plus développé  nommé "main_occilo.py" qui contiendra des classes pouvant afficher et modifier à volonté les constantes A, f et φ.

Sans attarder, voilà des images animées (.gif) des deux programmes en exécution : 
 - Test du module "oscillographie.py" : 

  
- Exécution du code du fichier "main_oscillo.py" : 



Vous pouvez télécharger le code source des deux programmes via Google Drive.

[Tutoriel] : Affichage d'une série de wagons, des personnages dans les fenêtres et changer la couleur des wagons.


Dans ce billet on va explorer un autre exemple d'un programme crée avec Python en utilisant le module "Tkinter" (nommé aussi : Tk). 
Ce billet utilisera des techniques vues dans ce billet, qui nous permettra d'afficher une fenêtre contenant trois wagons et plusieurs fenêtres. L'appui sur le bouton "Train" affichera les wagons, l'appui sur le bouton "Salut" affichera des petits visages dans les fenêtres et la saisie d'une couleur en appuyant sur le bouton "Éclaire" changera la couleur du premier et du troisième wagons. 
Voilà une image "gif" qui illustre le fonctionnement de notre programme. 


À noter : Le code source en Python est fonctionnel avec "Python 3" et plus. 
Avec les versions antérieures vous rencontrez des erreurs. Et aussi, il faut respecter l'indentation lors de la saisie du code sur vos IDE préférés.

Vous pouvez télécharger le code source (Mis en format .zip)  sur Google Drive.


[Tutoriel] : Affichage des couleurs et leur noms avec Python et Tkinter


Dans ce billet on va explorer ensemble un exemple d'un programme crée avec Python en utilisant le module Tkinter (nommé aussi : Tk) qui est l'interface standard de la boite à outils Tk GUI de la langage de programmation Python .
Ce tutoriel consiste à créer un GUI permettant la saisie d'un couleur à afficher dans un rectangle. Les couleurs doivent êtres écrites comme suit : [Black, Brown, Red, Orange, Yellow, Green, Blue, Purple, Grey, White]. Le programme sera sensible aux majuscules et en cas de mauvaise saisie, un message d'erreur s'affichera et  indiquera qu'on doit appuyez sur la touche 'R' ou 'r' pour relancer la saisie.
Assez parler, voilà une présentation du programme (format .gif) et  le code documenté :



#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Auteur : Chiheb
# Licence : Free Licence

######### Affichage des couleurs + leurs noms ###########

class Application (object) :

   def __init__ (self) :
       "Constructeur de la fenêtre principale"
       # Initialisation de Tkinter()
       self.root = Tk()
       # Texte de la fenêtre principale
       self.root.title ('Affichage des couleurs')
       # Appel de la fontion dessineCadre() de la classe Application()
       self.dessineCadre()
       # Création d'un Label()
       Label(self.root,text = "Entrer le nom du couleur : ").grid(row=2,column=1,columnspan=3)
       # Création du premier boutton
       Button(self.root,text='Montrer',command = self.changeCouleur).grid(row=3,column=1)
       # Création du deuxième boutton
       Button(self.root,text='Quitter',command = self.root.quit).grid(row=3,column=3)
       # Création d'une espace de saisie de type Entry
       self.entree = Entry(self.root,width=14)
       self.entree.grid(row=3,column=2)
       # Listes des couleurs
       self.cc = ['Black','Brown','Red','Orange','Yellow','Green','Blue','Purple','Grey','White']
       # Boucle pincipale

       self.root.mainloop()

   def dessineCadre (self) :

       "Canvas avec un text box au milieu indiquant la couleur"
       # Création du Canvas de l'instance self.root avec une largeur = 250, hauteur = 100
       # et couleur de l'arière plan = ivory
       self.can = Canvas(self.root,width= 250, height = 100, bg='ivory')
       # Le Vanvas crée possède une seule ligne (row=1) et une seule colonne (column=1)
       # L'espacement de la colonne est de l'ordre de 3
       # padx = Remplissage facultatif autour d'une widget dans une cellule
       # pady = Sa valeur par défaut est 1
       self.can.grid(row=1,column=1,columnspan=3,pady=5,padx=5)
       # Création d'un rectangle
       self.can.create_rectangle(65,30,185,70,fill='light grey',width=2)  

   def changeCouleur(self) :
       "Changer la couleur du fond du rectangle"
       text_id = None
       # Utilisation de la méthode get() pour reçevoir les données par l'utilisateur
       self.ch = self.entree.get()
       # Affichage facultatif
       print("Vous avez saisie : ",self.ch)
       # Appuyer sur 'R' ou 'r' renouvelle la fenêtre de la saisie
       if self.ch.upper() =='R' :
       self.videEntree()
       if self.ch in self.cc :
       #Création du rectangle aux positions : 65,30,185,70 de l'écran
      self.can.itemconfigure(self.can.create_rectangle(65,30,185,70,fill=self.ch,width=2))   
       # Création du texte
       text_id = self.can.create_text(130,50,anchor = "center")
       # Configuration du contenu du texte
       self.can.itemconfig(text_id,text=self.ch)
       # Insertion du texte avec une police = 12
       self.can.insert(text_id,12,"")
       else :
       # Création d'un Cavnas item, un text plus précisement pour l'erreur
       # Recréation de du Vavnas en mettant la couleur par défaut = white

       self.can.itemconfigure(self.can.create_rectangle(65,30,185,70,fill='white',width=2))
       text_id = self.can.create_text(130,50,anchor = "center")
       # Message d'erreur en cas de mauvaise saisie
       self.can.itemconfig(text_id,text="  ERREUR\n(R)enouveller")
       self.can.insert(text_id,12,"")
       if self.ch.upper() =='R' :
           # Message facultatif
           print("Renouvellement de la fenêtre de la saisie")
       else :
           # Message facultatif
           print('"{}" n\'est pas inclus dans la liste des couleurs'.format(self.ch))

   def videEntree(self) :
       "Rétablir le fond blanc et enlever les caractères saisies"
       # Mettre le fond de la fenêtre de la saisie en blanc
       self.entree.configure(bg='white')
       # Vider le champs de la saisie
       self.entree.delete(0,len(self.ch))

 ################# Programme principal #################

if __name__ == '__main__' :
    from tkinter import *
    f = Application()


Vous pouvez télécharger le code source directement via : Google Drive