Outils pour utilisateurs

Outils du site


issue48:tuto-python

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
issue48:tuto-python [2011/06/12 18:13] fredphil91issue48:tuto-python [2011/06/16 08:37] (Version actuelle) auntiee
Ligne 3: Ligne 3:
 Last month, in part 21, you were told to save what you have as "PlaylistMaker.glade", but, in the code, it was referred to as: "playlistmaker.glade". I’m sure you noticed that one has capitals and the other does not. The code will run only if you use both the call and file name with, or both without, the capitals.** Last month, in part 21, you were told to save what you have as "PlaylistMaker.glade", but, in the code, it was referred to as: "playlistmaker.glade". I’m sure you noticed that one has capitals and the other does not. The code will run only if you use both the call and file name with, or both without, the capitals.**
  
-//Je propose de ne pas mettre ce paragraphe en VF : nous n'avions pas d'erreur de nom de fichier dans la VF !//+//Je propose de ne pas mettre ce paragraphe en VF : nous n'avions pas d'erreur de nom de fichier dans la VF !// On le supprime de notre version carrément, alors ?
  
 **To start off on the right foot, you need to have the playlistmaker.glade and playlistmaker.py from last month. If you don't, jump over to the last issue and get the goodies. Before we get to the code, let's take a look at what a playlist file is. There are multiple versions of play lists, and they all have different extensions. The one we will be creating will be a *.m3u type playlist. In its simplest form, it's just a text file that starts with “#EXTM3U”, and then has an entry for each song file you want to play - including the full path. There's also an extension that can be added before each entry that includes the length of the song, the album name the song comes from, the track number, and the song name. We'll bypass the extension for now and just concentrate on the basic version.  **To start off on the right foot, you need to have the playlistmaker.glade and playlistmaker.py from last month. If you don't, jump over to the last issue and get the goodies. Before we get to the code, let's take a look at what a playlist file is. There are multiple versions of play lists, and they all have different extensions. The one we will be creating will be a *.m3u type playlist. In its simplest form, it's just a text file that starts with “#EXTM3U”, and then has an entry for each song file you want to play - including the full path. There's also an extension that can be added before each entry that includes the length of the song, the album name the song comes from, the track number, and the song name. We'll bypass the extension for now and just concentrate on the basic version. 
Ligne 14: Ligne 14:
 Adult Contemporary/Chris Rea/Collection/11 - Looking For The Summer.mp3** Adult Contemporary/Chris Rea/Collection/11 - Looking For The Summer.mp3**
  
-Pour commencer du bon pied, vous avez besoin d'avoir les fichiers playlistmaker.glade et playlistmaker.py du mois dernier. Si ce n'est pas le cas, sautez sur le numéro précédent pour les récupérer. Avant de passer au code, nous allons jeter un oeil à ce qu'est un fichier de liste de lecture. Il y a plusieurs versions des listes de lecture, qui ont toutes des extensions différentes. Le fichier que nous allons créer sera de type *.m3u. Dans sa forme la plus simple, c'est juste un fichier texte qui commence par « #EXTM3U " et qui contient une entrée pour chaque fichier audio que vous voulez écouter - avec le chemin d'accès complet. Il y a aussi une extension qui peut être ajoutée avant chaque entrée contenant la longueur de la chanson, le nom de l'album d'où vient la chanson, le numéro de piste et le nom du morceau. Nous allons ignorer l'extension pour l'instant et se concentrer uniquement sur la version de base.+Pour bien commencer, vous devez avoir les fichiers playlistmaker.glade et playlistmaker.py du mois dernier. Si ce n'est pas le cas, sautez sur le numéro précédent pour les récupérer. Avant de passer au code, nous allons jeter un œil à ce qu'est un fichier de liste de lecture. Il y a plusieurs versions des listes de lecture, qui ont toutes des extensions différentes. Le fichier que nous allons créer sera de type *.m3u. Dans sa forme la plus simple, c'est juste un fichier texte qui commence par « #EXTM3U " et qui contient une entrée pour chaque fichier audio que vous voulez écouter - avec le chemin d'accès complet. Il y a aussi une extension qui peut être ajoutée avant chaque entrée contenant la longueur de la chanson, le nom de l'album d'où vient la chanson, le numéro de piste et le nom du morceau. Nous allons ignorer l'extension pour l'instant et se concentrer uniquement sur la version de base.
  
 Voici un exemple d'un fichier de liste de lecture M3U. Voici un exemple d'un fichier de liste de lecture M3U.
Ligne 39: Ligne 39:
 Maintenant, nous devons créer une routine de gestion d'événement pour chacun des événements que nous avons mis en place. Notez que on_FenetrePrincipale_destroy et on_boBtnQuitter_clicked sont déjà faits pour nous, il n'en reste donc que dix autres à écrire (voir en haut à droite). Écrivons juste des ébauches pour l'instant. Maintenant, nous devons créer une routine de gestion d'événement pour chacun des événements que nous avons mis en place. Notez que on_FenetrePrincipale_destroy et on_boBtnQuitter_clicked sont déjà faits pour nous, il n'en reste donc que dix autres à écrire (voir en haut à droite). Écrivons juste des ébauches pour l'instant.
  
-Nous modifierons ces ébauches de routines dans quelques minutes. Pour l'instant, cela devrait nous permettre de démarrer l'application, et nous pourrons tester les choses au fur et à mesure que nous avançons. Nous devons quand même ajouter une ligne supplémentaire à la routine <nowiki>__init__</nowiki> avant que nous puissions démarrer l'application. Après la ligne self.wTree, ajouter :+Nous modifierons ces ébauches de routines dans quelques minutes. Pour l'instant, cela devrait nous permettre de démarrer l'application nous pourrons tester les choses au fur et à mesure que nous avançons. Nous devons quand même ajouter une ligne supplémentaire à la routine <nowiki>__init__</nowiki> avant de pouvoir démarrer l'application. Après la ligne self.wTree, ajouter :
  
 self.DicoEvenements() self.DicoEvenements()
Ligne 55: Ligne 55:
 gtk.MessageDialog(parent,flags,MessageType,Buttons,message)** gtk.MessageDialog(parent,flags,MessageType,Buttons,message)**
  
-Maintenant, vous pouvez exécuter l'application, voir la fenêtre, puis cliquez sur le bouton Quitter de la barre pour quitter l'application correctement. Enregistrez le code sous le nom "CreateurListeDeLecture-1a.pyet essayez-le. Souvenez-vous qu'il faut l'enregistrer dans le même dossier que le fichier glade nous avons créé la dernière foisou bien copier le fichier glade dans le dossier dans lequel vous avez enregistré ce code.+Maintenant, vous pouvez exécuter l'application, voir la fenêtre, puis cliquer sur le bouton Quitter de la barre d'outils pour quitter l'application correctement. Enregistrez le code sous le nom « CreateurListeDeLecture-1a.py » et essayez-le. Souvenez-vous qu'il faut l'enregistrer dans le même dossier que le fichier glade nous avons créé la dernière fois ou bien copier le fichier glade dans le dossier dans lequel vous avez enregistré ce code.
  
 Nous avons également besoin de définir quelques variables pour une utilisation future. Ajoutez ceci après l'appel à DicoEvenements() dans la fonction <nowiki>__init__</nowiki>. Nous avons également besoin de définir quelques variables pour une utilisation future. Ajoutez ceci après l'appel à DicoEvenements() dans la fonction <nowiki>__init__</nowiki>.
Ligne 63: Ligne 63:
   self.NombreDeLignes = 0   self.NombreDeLignes = 0
  
-Maintenant, nous allons créer une fonction qui nous permet d'afficher une boîte de dialogue à chaque fois que nous avons besoin de donner des informations à nos utilisateurs. Il existe un ensemble de routines toutes faites que nous allons utiliser, mais nous allons faire une routine à nous pour nous faciliter les choses. C'est la routine gtk.MessageDialoget la syntaxe est la suivante...+Maintenant, nous allons créer une fonction qui nous permet d'afficher une boîte de dialogue à chaque fois que nous avons besoin de donner des informations au utilisateur. Il existe un ensemble de routines toutes faites que nous allons utiliser, mais nous allons faire une routine à nous pour nous faciliter les choses. C'est la routine gtk.MessageDialog et la syntaxe est la suivante :
  
   gtk.MessageDialog (parent, drapeaux, MessageType, boutons, message)   gtk.MessageDialog (parent, drapeaux, MessageType, boutons, message)
Ligne 83: Ligne 83:
 GTK_BUTTONS_OK_CANCEL - OK and Cancel Buttons** GTK_BUTTONS_OK_CANCEL - OK and Cancel Buttons**
  
-Une discussion est nécessaire avant d'aller trop loin. Le type de message peut être une des suivants...+Une discussion est nécessaire avant d'aller trop loin. Le type de message peut être l'un des suivants :
  
 GTK_MESSAGE_INFO - message d'information GTK_MESSAGE_INFO - message d'information
Ligne 90: Ligne 90:
 GTK_MESSAGE_ERROR - message d'erreur fatale GTK_MESSAGE_ERROR - message d'erreur fatale
  
-Et les types de boutons sont... +Et les types de boutons sont 
  
 GTK_BUTTONS_NONE - aucun bouton GTK_BUTTONS_NONE - aucun bouton
Ligne 107: Ligne 107:
 However, if you want to display a message box to the user more than once or twice, that's a LOT of typing. The general rule of thumb is that if you write a series of lines-of-code more than once or twice, it's usually better to create a function and then call that. Think of it this way: If we want to display a message dialog to the user, say ten times in your application, that's 10 X 3 (or 30) lines of code. By making a function to do this for us (using the example I just presented), we would have 10 + 3 (or 13) lines of code to write. The more we call a dialog, the less code we actually have to type, and the more readable our code is. Our function (top right) will allow us to call any of the four message dialog types with just one routine using different parameters.** However, if you want to display a message box to the user more than once or twice, that's a LOT of typing. The general rule of thumb is that if you write a series of lines-of-code more than once or twice, it's usually better to create a function and then call that. Think of it this way: If we want to display a message dialog to the user, say ten times in your application, that's 10 X 3 (or 30) lines of code. By making a function to do this for us (using the example I just presented), we would have 10 + 3 (or 13) lines of code to write. The more we call a dialog, the less code we actually have to type, and the more readable our code is. Our function (top right) will allow us to call any of the four message dialog types with just one routine using different parameters.**
  
-Normalement, vous devez utiliser le code suivant, ou du code similaire, pour créer la boîte de dialogue, de l'afficher, attendre une réponse, puis le détruire.+Normalement, vous utiliseriez le code suivant, ou du code similaire, pour créer la boîte de dialogue, l'afficher, attendre une réponse, puis le détruire.
  
   dlg = gtk.MessageDialog (None, 0, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "Ceci est un message de test ...")   dlg = gtk.MessageDialog (None, 0, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "Ceci est un message de test ...")
Ligne 113: Ligne 113:
   dlg.destroy ()   dlg.destroy ()
  
-Toutefois, si vous voulez afficher une boîte de message à l'utilisateur plus d'une ou deux fois, c'est beaucoup de dactylographie. La règle générale est que si vous écrivez une série de lignes de code plus d'une ou deux fois, il est généralement préférable de créer une fonction puis de l'appeler. Pensez-y de cette manière : si nous voulons afficher un message de dialogue à l'utilisateur par exemple dix fois dans votre application, cela représente 10 x 3 (soit 30) lignes de code. En faisant une fonction pour faire cela pour nous (en utilisant l'exemple que je viens de présenter), nous aurions 10 + 3 (soit 13) lignes de code à écrire. Plus nous appelons une boîte de dialogue, moins cela fait de code à taper, et plus lisible est notre code. Notre fonction (en haut à droite) nous permettra d'appeler l'un des quatre types de message de dialogue avec juste une routine en utilisant différents paramètres.+Toutefois, si vous voulez afficher une boîte de message à l'utilisateur plus d'une ou deux fois, c'est beaucoup de dactylographie. La règle générale est que si vous écrivez une série de lignes de code plus d'une ou deux fois, il est généralement préférable de créer une fonction puis de l'appeler. Pensez-y de cette manière : si nous voulons afficher un message de dialogue pour l'utilisateur, disons dix fois dans l'application, cela représente 10 x 3 (soit 30) lignes de code. En faisant une fonction pour faire cela pour nous (en utilisant l'exemple que je viens de présenter), nous aurions 10 + 3 (soit 13) lignes de code à écrire. Plus nous appelons une boîte de dialogue, moins cela fait de code à taper, et plus lisible est notre code. Notre fonction (en haut à droite) nous permettra d'appeler l'un des quatre types de message de dialogue avec une seule routine en utilisant différents paramètres.
  
 **This is a very simple function that we would then call like this...  **This is a very simple function that we would then call like this... 
Ligne 131: Ligne 131:
    print "NO was clicked"**    print "NO was clicked"**
  
-C'est une fonction très simple que nous pourrons ensuite appeler de cette façon...+C'est une fonction très simple que nous pourrons ensuite appeler comme suit :
  
   self.MessageBox("info", "Le bouton QUITTER a été cliqué")   self.MessageBox("info", "Le bouton QUITTER a été cliqué")
  
-Notez que si nous choisissons d'utiliser le type de dialogue MESSAGE_QUESTION, il y a deux réponses possibles qui seront retournées par la fenêtre de dialogue - un « oui » ou un « non ». Quelle que soit le bouton cliqué par l'utilisateur, nous allons recevoir les informations de retour dans notre code. Pour utiliser la boîte de dialogue de question, l'appel ressemblera à ça ...+Notez que si nous choisissons d'utiliser le type de dialogue MESSAGE_QUESTION, il y a deux réponses possibles qui seront retournées par la fenêtre de dialogue - un « oui » ou un « non ». Quel que soit le bouton cliqué par l'utilisateur, nous allons recevoir les informations de retour dans notre code. Pour utiliser la boîte de dialogue de question, l'appel ressemblera à ceci :
  
-  reponse = self.MessageBox(« question », « Êtes-vous sûr de vouloir faire cela maintenant ? ")+  reponse = self.MessageBox(« question », « Êtes-vous sûr de vouloir faire cela maintenant ? »)
  
   if reponse == gtk.RESPONSE_YES:   if reponse == gtk.RESPONSE_YES:
  
-     print "Clic sur oui"+     print "clic sur oui"
  
   elif reponse == gtk.RESPONSE_NO:   elif reponse == gtk.RESPONSE_NO:
Ligne 157: Ligne 157:
 Vous voyez comment vous pouvez vérifier la valeur du bouton cliqué. Alors maintenant, remplacez l'appel à « pass »  dans chacune de nos routines de gestion d'événement par ce que vous voyez ci-dessous à droite. Vous voyez comment vous pouvez vérifier la valeur du bouton cliqué. Alors maintenant, remplacez l'appel à « pass »  dans chacune de nos routines de gestion d'événement par ce que vous voyez ci-dessous à droite.
  
-Nous n'allons pas garder ça comme ça, mais cela vous donne une indication visuelle que les boutons fonctionnent comme nous le voulons. Enregistrez maintenant le code sous « playlistmaker-1b.py » et testez votre programme. Maintenant nous allons créer une fonction pour définir nos références de widgets. Cette routine va être appelée une seule fois, mais elle rendra notre code beaucoup plus maniable et lisible. En fait, nous voulons créer des variables locales qui font référence à des widgets dans la fenêtre glade - afin que nous puissions faire des appels à eux chaque fois que (et si jamais) nous avons besoin. Mettez cette fonction (en haut à droite) en dessous de la fonction DicoEvenements.+Nous n'allons pas le garder comme ça, mais cela vous donne une indication visuelle que les boutons fonctionnent comme nous le voulons. Enregistrez maintenant le code sous « CréateurListeDeLecture-1b.py » et testez votre programme. Maintenant nous allons créer une fonction pour définir nos références de widgets. Cette routine va être appelée une seule fois, mais elle rendra notre code beaucoup plus maniable et lisible. En fait, nous voulons créer des variables locales qui font référence à des widgets dans la fenêtre glade - afin que nous puissions faire des appels à eux chaque fois que (et si jamais) nous en avons besoin. Mettez cette fonction (en haut à droite) en dessous de la fonction DicoEvenements.
  
-Remarquez qu'il y a une chose qui n'est pas référencée dans notre routine. Il s'agit du widget treeview. Nous allons créer cette référence lorsque nous créerons l'arborescence elle-même. Notez également la dernière ligne de notre routine. Pour utiliser la barre d'état, il faut s'y référer par son ID de contexte. Nous allons utiliser ça plus loin.+Remarquez qu'il y a une chose qui n'est pas référencée dans notre routine. Il s'agit du widget treeview. Nous allons créer cette référence lorsque nous créerons l'arborescence elle-même. Notez également la dernière ligne de notre routine. Pour utiliser la barre d'état, il faut s'y référer par son id de contexte. Nous allons utiliser cela plus loin.
  
-Ensuite, nous allons mettre en place la fonction qui affiche le dialogue « à propos » quand on clique sur le bouton À propos de la barre d'outils. Encore une fois, ceci est un routine intégrée fournie par la bibliothèque GTK. Placez ceci après la fonction MessageBox. Voici le code, en bas à droite.+Ensuite, nous allons mettre en place la fonction qui affiche le dialogue « à propos » quand on clique sur le bouton À propos de la barre d'outils. Encore une fois, ceci est une routine intégrée fournie par la bibliothèque GTK. Placez ceci après la fonction MessageBox. Voici le code, en bas à droite.
  
 **Save your code and then give it a try. You should see a pop-up box, centered in our application, that displays everything we have set. There are more attributes that you can set for the about box (which can be found at http://www.pygtk.org/docs/pygtk/class-gtkaboutdialog.html), but these are what I would consider a minimum set. **Save your code and then give it a try. You should see a pop-up box, centered in our application, that displays everything we have set. There are more attributes that you can set for the about box (which can be found at http://www.pygtk.org/docs/pygtk/class-gtkaboutdialog.html), but these are what I would consider a minimum set.
Ligne 169: Ligne 169:
 Sauvegardez votre code, puis faites un essai. Vous devriez voir une fenêtre pop-up, centrée dans notre application, qui affiche ce que nous avons prévu. Il y a plusieurs attributs que vous pouvez définir pour la boîte à propos (qui peuvent être trouvés sur http://www.pygtk.org/docs/pygtk/class-gtkaboutdialog.html), mais ceux-ci sont ceux que je considère être un ensemble minimal. Sauvegardez votre code, puis faites un essai. Vous devriez voir une fenêtre pop-up, centrée dans notre application, qui affiche ce que nous avons prévu. Il y a plusieurs attributs que vous pouvez définir pour la boîte à propos (qui peuvent être trouvés sur http://www.pygtk.org/docs/pygtk/class-gtkaboutdialog.html), mais ceux-ci sont ceux que je considère être un ensemble minimal.
    
-Avant de poursuivre, nous devons discuter de ce qui se produira à partir d'ici. L'idée générale est que l'utilisateur clique sur le bouton « Ajouter » de la barre d'outils, nous afficherons alors une boîte de dialogue de fichier pour leur permettre d'ajouter des fichiers à la liste de lecture, puis nous afficherons les informations du fichier dans notre widget treeview. De là, ils peuvent ajouter d'autres fichiers, supprimer un fichier unique, supprimer tous les fichiers, déplacer un fichier vers le haut ou le bas, ou bien tout en haut ou tout en bas de l'arborescence. Finalementils vont définir le chemin où le fichier sera enregistré, fournir un nom de fichier avec une extension « m3u », puis cliquez sur le bouton Sauvegarder. Bien que cela semble assez simple, il se passe beaucoup de choses en coulisses. La magie se produit dans le widget treeview, nous allons donc en discuter. Cela ira assez loin, alors lisez attentivement, car il faut comprendre cela pour éviter de commettre des erreurs plus tard.+Avant de poursuivre, nous devons discuter de ce qui se produira à partir d'ici. L'idée générale est que l'utilisateur clique sur le bouton « Ajouter » de la barre d'outils, nous afficherons alors une boîte de dialogue de fichier pour lui permettre d'ajouter des fichiers à la liste de lecture, puis nous afficherons les informations du fichier dans notre widget treeview. De là, il peut ajouter d'autres fichiers, supprimer un fichier unique, supprimer tous les fichiers, déplacer un fichier vers le haut ou le bas, ou bien tout en haut ou tout en bas de l'arborescence. Enfinil va définir le chemin où le fichier sera enregistré, fournir un nom de fichier avec une extension « m3u », puis cliquer sur le bouton Sauvegarder. Bien que cela semble assez simple, il se passe beaucoup de choses en coulisses. La magie se produit dans le widget treeview, nous allons donc en discuter. Cela ira assez loin, alors lisez attentivement, car il faut le comprendre pour éviter de commettre des erreurs plus tard.
    
 **A treeview can be something as simple as a columnar list of data like a spreadsheet or database representation, or it could be more complex like a file-folder listing with parents and children, where the folder would be the parent and the files in that folder would be the children, or something even more complex. For this project, we'll use the first example, a columnar list. In the list, there will be three columns. One is for the name of the music file, one is for the extension of the file (mp3, ogg, wav, etc) and the final column is for the path. Combining this into a string (path, filename, extension) gives us the entry into the playlist we will be writing. You could, of course, add more columns as you wish, but for now, we'll deal with just three. **A treeview can be something as simple as a columnar list of data like a spreadsheet or database representation, or it could be more complex like a file-folder listing with parents and children, where the folder would be the parent and the files in that folder would be the children, or something even more complex. For this project, we'll use the first example, a columnar list. In the list, there will be three columns. One is for the name of the music file, one is for the extension of the file (mp3, ogg, wav, etc) and the final column is for the path. Combining this into a string (path, filename, extension) gives us the entry into the playlist we will be writing. You could, of course, add more columns as you wish, but for now, we'll deal with just three.
Ligne 183: Ligne 183:
 • Fill in the data.** • Fill in the data.**
  
-Une arborescence peut être quelque chose d'aussi simple qu'une liste à colonnes de données comme dans une feuille de calcul ou une base de données, ou bien cela peut être plus complexe comme une liste de fichiers/dossiers avec les parents et les enfants, où le dossier serait le parent et les fichiers de ce dossier seraient les enfants, ou quelque chose d'encore plus complexe. Pour ce projet, nous allons utiliser le premier exemple, une liste à colonnes. Dans la liste, il y aura trois colonnes. Une pour le nom du fichier de musique, une pour l'extension du fichier (mp3, ogg, wav, etc.) et la dernière colonne pour le chemin d'accès. En combinant tout ça dans une chaîne (chemin d'accès, nom de fichier, extension) on obtient l'entrée que nous allons écrire dans la liste de lecture. Vous pourriez bien sûr ajouter d'autres colonnes si vous le souhaitez, mais pour l'instant nous allons nous contenter de trois.+Une arborescence peut être quelque chose d'aussi simple qu'une liste à colonnes de donnéescomme dans une feuille de calcul ou une base de données, ou bien elle peut être plus complexecomme une liste de fichiers/dossiers avec des parents et enfants, où le dossier serait le parent et les fichiers de ce dossier seraient les enfants, ou quelque chose d'encore plus complexe. Pour ce projet, nous allons utiliser le premier exemple, une liste à colonnes. Dans la liste, il y aura trois colonnes. Une pour le nom du fichier de musique, une pour l'extension du fichier (mp3, ogg, wav, etc.) et la dernière colonne pour le chemin d'accès. En combinant tout ça dans une chaîne (chemin d'accès, nom de fichier, extension) on obtient l'entrée que nous allons écrire dans la liste de lecture. Vous pourriez bien sûr ajouter d'autres colonnes si vous le souhaitez, mais pour l'instant nous allons nous contenter de trois.
    
-Une arborescence est simplement un conteneur visuel de stockage qui détient et affiche un modèle. Le modèle est le véritable « dispositif » qui contient et manipule nos données. Il existe deux modèles prédéfinis qui sont utilisés avec un treeview, mais vous pouvez certainement créer le votre. Cela étant dit, pour 98% de votre travail, l'un des deux modèles prédéfinis fera ce dont vous avez besoin. Les deux types sont GTKListStore et GTKTreeStore. Comme leur nom l'indique, le modèle ListStore est habituellement utilisé pour les listes, le TreeStore est utilisé pour les arbres. Pour notre application, nous allons utiliser un GTKListStore.+Une arborescence est simplement un conteneur visuel de stockage qui détient et affiche un modèle. Le modèle est le véritable « dispositif » qui contient et manipule nos données. Il existe deux modèles prédéfinis qui sont utilisés avec un treeview, mais vous pouvez certainement créer le vôtre. Cela étant dit, pour 98 % de votre travail, l'un des deux modèles prédéfinis fera ce dont vous avez besoin. Les deux types sont GTKListStore et GTKTreeStore. Comme leur nom l'indique, le modèle ListStore est habituellement utilisé pour les listes, le TreeStore est utilisé pour les arbres. Pour notre application, nous allons utiliser un GTKListStore.
 Les étapes de base sont les suivantes : Les étapes de base sont les suivantes :
  
Ligne 192: Ligne 192:
 • Définir le type de moteur de rendu à utiliser. • Définir le type de moteur de rendu à utiliser.
 • Créer le ListStore. • Créer le ListStore.
-• Définissez l'attribut de modèle dans l'arborescence de notre modèle. +• Définir l'attribut de modèle dans l'arborescence de notre modèle. 
-• Remplissez les données.+• Remplir les données.
  
 **The third step is to set up the type of renderer the column will use to display the data. This is simply a routine that is used to draw the data into the tree model. There are many different cell renderers that come with GTK, but most of the ones that you would normally use include GtkCellRenderText and GtkCellRendererToggle. **The third step is to set up the type of renderer the column will use to display the data. This is simply a routine that is used to draw the data into the tree model. There are many different cell renderers that come with GTK, but most of the ones that you would normally use include GtkCellRenderText and GtkCellRendererToggle.
Ligne 209: Ligne 209:
 Les variables cNomFic, cTypeFic et cCheminFic définissent les numéros de colonne. Les variables sNomFic, sTypeFic et sCheminFic contiennent les noms de colonnes de notre vue. La septième ligne définit la variable de référence du widget treeview tel qu'il figure dans notre fichier glade. Les variables cNomFic, cTypeFic et cCheminFic définissent les numéros de colonne. Les variables sNomFic, sTypeFic et sCheminFic contiennent les noms de colonnes de notre vue. La septième ligne définit la variable de référence du widget treeview tel qu'il figure dans notre fichier glade.
  
-Ensuite nous appelons une routine (page suivante, en haut à droite), que nous allons créer dans un instant, pour chaque colonne que nous voulons. Ensuite, nous définissons notre GTKListStore avec trois champs de texteet enfin nous utilisons ce GTKListStore comme attribut de modèle de notre widget TreeView. Nous allons ensuite créer la fonction AjouterColonne. Placez--la après la fonction SetupTreeview.+Ensuite nous appelons une routine (page suivante, en haut à droite), que nous allons créer dans un instant, pour chaque colonne que nous voulons. Puis, nous définissons notre GTKListStore avec trois champs de texte etenfinnous utilisons ce GTKListStore comme attribut de modèle de notre widget TreeView. Nous allons ensuite créer la fonction AjouterColonne. Placez-la après la fonction SetupTreeview.
  
 **Each column is created with this function. We pass in the title of the column (what's displayed on the top line of each column) and a columnID. In this case, the variables we set up earlier (sFName and cFname) will be passed here. We then create a column in our TreeView widget giving the title, what kind of cell renderer it will be using, and, finally, the id of the column. We then set the column to be resizable, set the sort id, and finally append the column into the TreeView. **Each column is created with this function. We pass in the title of the column (what's displayed on the top line of each column) and a columnID. In this case, the variables we set up earlier (sFName and cFname) will be passed here. We then create a column in our TreeView widget giving the title, what kind of cell renderer it will be using, and, finally, the id of the column. We then set the column to be resizable, set the sort id, and finally append the column into the TreeView.
Ligne 221: Ligne 221:
 Chaque colonne est créée avec cette fonction. Nous lui passons le titre de la colonne (ce qui est affiché sur la première ligne de chaque colonne) et un idColonne. Dans ce cas, nous utilisons les variables que nous avons créées plus tôt (sNomFic et cNomFic). Nous créons ensuite une colonne dans notre widget TreeView donnant le titre, le type de rendu de cellule et enfin l'id de la colonne. Nous indiquons ensuite que la colonne est redimensionnable, nous définissons l'id de tri et ajoutons enfin la colonne dans le TreeView. Chaque colonne est créée avec cette fonction. Nous lui passons le titre de la colonne (ce qui est affiché sur la première ligne de chaque colonne) et un idColonne. Dans ce cas, nous utilisons les variables que nous avons créées plus tôt (sNomFic et cNomFic). Nous créons ensuite une colonne dans notre widget TreeView donnant le titre, le type de rendu de cellule et enfin l'id de la colonne. Nous indiquons ensuite que la colonne est redimensionnable, nous définissons l'id de tri et ajoutons enfin la colonne dans le TreeView.
    
-Ajoutez ces deux fonctions à votre code. J'ai choisi de les mettre tout de suite après la fonction ReferencesWidget, mais vous pouvez les mettre n'importe où dans la classe PlayListCreator. Ajoutez la ligne suivante après l'appel à ReferencesWidget() dans la fonction <nowiki>__init__</nowiki> pour appeler la fonction.+Ajoutez ces deux fonctions à votre code. J'ai choisi de les mettre tout de suite après la fonction ReferencesWidget, mais vous pouvez les mettre n'importe où dans la classe CreateurListeDeLecture. Ajoutez la ligne suivante après l'appel à ReferencesWidget() dans la fonction <nowiki>__init__</nowiki> pour appeler la fonction.
  
 self.SetupTreeview () self.SetupTreeview ()
  
-Enregistrez et exécutez votre programmeet vous verrez que nous avons maintenant trois colonnes avec en-têtes dans notre widget TreeView.+Enregistrez et exécutez votre programme et vous verrez que nous avons maintenant trois colonnes avec en-têtes dans notre widget TreeView.
    
 **There are so many things left to do. We have to have a way to get the music filenames from the user and put them into the TreeView as rows of data. We have to create our Delete, ClearAll, movement functions, save routine, and file path routines, plus a few "pretty" things that will make our application look more professional. Let's start with the Add routine. After all, that's the first button on our toolbar.  **There are so many things left to do. We have to have a way to get the music filenames from the user and put them into the TreeView as rows of data. We have to create our Delete, ClearAll, movement functions, save routine, and file path routines, plus a few "pretty" things that will make our application look more professional. Let's start with the Add routine. After all, that's the first button on our toolbar. 
Ligne 236: Ligne 236:
   def ShowDialog(self,which,CurrentPath):**   def ShowDialog(self,which,CurrentPath):**
  
-Il reste tellement de choses à faire. Nous devons avoir un moyen d'obtenir les noms de fichiers de musique de l'utilisateur et les mettre dans le TreeView sous forme de lignes de données. Nous devons créer nos fonctions Supprimer, Effacer tout, les fonctions de déplacement, la routine de sauvegarde et les routines de chemins de fichiers, plus quelques « jolies » choses qui donneront à notre application un aspect plus professionnel. Commençons par la routine Ajouter. Après tout, c'est le premier bouton sur notre barre d'outils. +Il reste tellement de choses à faire. Nous devons avoir un moyen d'obtenir les noms de fichiers de musique de l'utilisateur et un moyen de les mettre dans le TreeView sous forme de lignes de données. Nous devons créer nos fonctions Supprimer, Effacer tout, les fonctions de déplacement, la routine de sauvegarde et les routines de chemins de fichiers, plus quelques « jolies » choses qui donneront à notre application un aspect plus professionnel. Commençons par la routine Ajouter. Après tout, c'est le premier bouton sur notre barre d'outils. 
-Lorsque l'utilisateur clique sur le bouton Ajouter, nous voulons faire apparaître une fenêtre de dialogue « standard » d'ouverture de fichier, qui permet des sélections multiples. Une fois que l'utilisateur a fait son choix, nous voulons ensuite prendre ces données et les ajouter dans l'arborescence, comme je l'ai indiqué ci-dessus. Donc la première chose logique à faire est de travailler sur la boîte de dialogue Fichier. Encore une fois, GTK nous fournit un moyen d'appeler une boîte de dialogue « standard » de fichiers. Nous pourrions coder ça en dur simplement avec des lignes de code dans le gestionnaire d'événements on_boBtnAjouter_clicked, mais nous allons faire une classe distincte pour gérer cela. Tant que nous y sommes, nous pouvons faire en sorte que cette classe gére non seulement un dialogue Ouvrir un fichier, mais aussi un dialogue Sélectionner un dossier. Comme auparavant avec la fonction MessageBox, vous pouvez extraire ça dans un fichier qui contient toutes sortes de routines réutilisables pour un usage ultérieur.+Lorsque l'utilisateur clique sur le bouton Ajouter, nous voulons faire apparaître une fenêtre de dialogue « standard » d'ouverture de fichier, qui permet des sélections multiples. Une fois que l'utilisateur a fait son choix, nous voulons ensuite prendre ces données et les ajouter dans l'arborescence, comme je l'ai indiqué ci-dessus. Ainsi, la première chose logique à faire est de travailler sur la boîte de dialogue Fichier. Encore une fois, GTK nous fournit un moyen d'appeler une boîte de dialogue « standard » de fichiers. Nous pourrions coder ça en dur simplement avec des lignes de code dans le gestionnaire d'événements on_boBtnAjouter_clicked, mais nous allons faire une classe distincte pour le gérer. Tant que nous y sommes, nous pouvons faire en sorte que cette classe gère non seulement un dialogue Ouvrir un fichier, mais aussi un dialogue Sélectionner un dossier. Comme auparavant avec la fonction MessageBox, vous pouvez l'extraire dans un fichier qui contient toutes sortes de routines réutilisables pour un usage ultérieur.
    
-Nous allons commencer par définir une nouvelle classe appelée DialogueFichier qui a une seule fonction appelée AfficheDialogue. Cette fonction prendra deux paramètres, l'un appelé « type » (un '0 'ou un '1') qui désigne si nous créons un dialogue d'ouverture de fichier ou de sélection de dossier, et l'autre qui est le chemin à utiliser pour la vue par défaut de la boîte de dialogue appelée CheminCourant. Créez cette classe juste avant notre code principal à la fin du fichier source.+Nous allons commencer par définir une nouvelle classe appelée DialogueFichier qui a une seule fonction appelée AfficheDialogue. Cette fonction prendra deux paramètres, l'un appelé « type » (un '0' ou un '1')qui précise si nous créons un dialogue d'ouverture de fichier ou de sélection de dossier, et l'autrequi est le chemin à utiliser pour la vue par défaut de la boîte de dialogue appelée CheminCourant. Créez cette classe juste avant notre code principal à la fin du fichier source.
  
 class DialogueFichier:  class DialogueFichier: 
Ligne 267: Ligne 267:
     ...     ...
  
-Avant d'aller plus loin, nous allons voir la façon dont la boîte de dialogue de fichier/dossier est effectivement appelée et utilisée. La syntaxe de la boîte de dialogue se présente comme suit+Avant d'aller plus loin, nous allons voir la façon dont la boîte de dialogue de fichier/dossier est effectivement appelée et utilisée. La syntaxe de la boîte de dialogue se présente comme suit :
  
 gtk.FileChooserDialog(titre,parent,action,boutons,backend) gtk.FileChooserDialog(titre,parent,action,boutons,backend)
Ligne 273: Ligne 273:
 et retourne un objet fenêtre de dialogue. Notre première ligne (dans le cas où type vaut 0) sera la ligne ci-dessous. et retourne un objet fenêtre de dialogue. Notre première ligne (dans le cas où type vaut 0) sera la ligne ci-dessous.
  
-Comme vous pouvez le voir, le titre est "Choisir les fichiers a ajouter...", le parent est défini sur none (aucun). Nous demandons une fenêtre de type ouverture de fichier (action)et nous voulons des boutons Annuler et Ouvrir, les deux utilisant des icônes det type « stock ». Nous réglons également les codes de retour de gtk.RESPONSE_CANCEL et gtk.RESPONSE_OK lorsque l'utilisateur fait ses choix. L'appel au sélecteur de dossier dans la clause else est similaire.+Comme vous pouvez le voir, le titre est « Choisir les fichiers a ajouter... », le parent est défini sur none (aucun). Nous demandons une fenêtre de type ouverture de fichier (action) et nous voulons des boutons Annuler et Ouvrir, les deux utilisant des icônes de type « stock ». Nous réglons également les codes de retour de gtk.RESPONSE_CANCEL et gtk.RESPONSE_OK lorsque l'utilisateur fait ses choix. L'appel au sélecteur de dossier dans la clause else est similaire.
  
 **Basically, the only thing that changed between the two definitions are the title (shown above right) and the action type. So our code for the class should now be the code shown middle right. **Basically, the only thing that changed between the two definitions are the title (shown above right) and the action type. So our code for the class should now be the code shown middle right.
Ligne 281: Ligne 281:
 Fondamentalement, les seules choses qui ont changé entre les deux définitions sont le titre (ci-dessus à droite) et le type d'action. Donc le code de la classe devrait maintenant être le code affiché au milieu à droite. Fondamentalement, les seules choses qui ont changé entre les deux définitions sont le titre (ci-dessus à droite) et le type d'action. Donc le code de la classe devrait maintenant être le code affiché au milieu à droite.
  
-Nous définissons la réponse par défaut à la touche OK, puis activons la fonctionnalité de sélection multiple pour que l'utilisateur puisse sélectionner (vous l'aurez deviné) plusieurs fichiers à ajouter. Si nous n'avions pas indiqué cela, la boîte de dialogue permettrait seulement de sélectionner un fichier à la fois, car set_select_multiple est réglé sur faux par défaut. Nos lignes suivantes règlent le chemin actuel, puis affichent la boîte de dialogue elle-même. Avant de taper le code, je vais vous expliquer pourquoi nous devons nous occuper du chemin courant. À chaque fois que vous faites apparaître une boîte de dialogue de fichieret que vous ne définissez pas un chemin, la valeur par défaut est le dossier où réside notre application. Ainsi, si les fichiers de musique que l'utilisateur utilise sont dans /media/musique/ et sont ensuite triés par genre puis par artiste, et puis ensuite par album. Supposons également que l'utilisateur a installé notre application dans /home/user2/createurListeDeLecture. Chaque fois que nous faisons apparaître le dialogue, le dossier de départ serait /home/user2/createurListeDeLecture. Rapidement, l'utilisateur devrait se sentir frustré par cela, préférant retrouver le dernier dossier dans lequel il était la fois suivante. Vous comprenez ? Bien. Voici donc en bas à droite les lignes de code suivantes.+Nous définissons la réponse par défaut à la touche OK, puis activons la fonctionnalité de sélection multiple pour que l'utilisateur puisse sélectionner (vous l'aurez deviné) plusieurs fichiers à ajouter. Si nous n'avions pas indiqué cela, la boîte de dialogue permettrait seulement de sélectionner un fichier à la fois, car set_select_multiple est réglé sur faux par défaut. Nos lignes suivantes règlent le chemin actuel, puis affichent la boîte de dialogue elle-même. Avant de taper le code, je vais vous expliquer pourquoi nous devons nous occuper du chemin courant. À chaque fois que vous faites apparaître une boîte de dialogue de fichier et que vous ne définissez pas un chemin, la valeur par défaut est le dossier où réside notre application. Ainsi, si les fichiers de musique que l'utilisateur utilise sont dans /media/musique/ ils sont ensuite triés par genre puis par artiste, et puis après par album. Supposons également que l'utilisateur a installé notre application dans /home/user2/createurListeDeLecture. Chaque fois que nous faisons apparaître le dialogue, le dossier de départ serait /home/user2/createurListeDeLecture. Rapidement, l'utilisateur devrait se sentir frustré par cela, préférant retrouver le dernier dossier dans lequel il était lorsqu'il démarre la prochaine fois. Vous comprenez ? Bien. Voici donc en bas à droite les lignes de code suivantes.
  
 **Here we check the responses sent back. If the user clicked the 'Open' button which sends back a gtk.RESPONSE_OK, we get the name or names of the files the user selected, set the current path to the folder we are in, destroy the dialog, and then return the data back to the calling routine. If, on the other hand, the user clicked on the 'Cancel' button, we simply destroy the dialog. I put the print statement in there just to show you that the button press worked. You can leave it or take it out. Notice that when we return from the Open button part of the routine, we are returning two sets of values. 'fileselection' is a list of the files selected by the user, as well as the CurrentPath.  **Here we check the responses sent back. If the user clicked the 'Open' button which sends back a gtk.RESPONSE_OK, we get the name or names of the files the user selected, set the current path to the folder we are in, destroy the dialog, and then return the data back to the calling routine. If, on the other hand, the user clicked on the 'Cancel' button, we simply destroy the dialog. I put the print statement in there just to show you that the button press worked. You can leave it or take it out. Notice that when we return from the Open button part of the routine, we are returning two sets of values. 'fileselection' is a list of the files selected by the user, as well as the CurrentPath. 
Ligne 299: Ligne 299:
 print "Current path is %s" % self.CurrentPath** print "Current path is %s" % self.CurrentPath**
  
- +Ici, nous vérifions les réponses renvoyées. Si l'utilisateur a cliqué sur le bouton « Ouvrir » qui renvoie gtk.RESPONSE_OK, nous obtenons le nom ou les noms des fichiers que l'utilisateur a sélectionné, on définit le chemin d'accès courant vers le dossier où nous sommes, on détruit la boîte de dialogue, puis on renvoie les données à la routine appelante. Si, en revanche, l'utilisateur a cliqué sur le bouton « Annuler », il suffit de détruire la boîte de dialogue. Je mets l'instruction print là juste pour vous montrer que l'appui sur le bouton a fonctionné. Vous pouvez la laisser ou la retirer. Notez que lorsque nous sortons de la partie concernant le bouton Ouvrir dans cette routine, nous renvoyons deux ensembles de valeurs : selectionFichiers qui est une liste des fichiers sélectionnés par l'utilisateur, ainsi que le CheminCourant. 
 + 
 +Afin que la routine fasse quelque chose, ajoutez la ligne suivante dans la routine on_boBtnAjouter_clicked : 
 + 
 +fd = DialogueFichier () 
 + 
 +fichiersChoisis,self.CheminCourant = fd.AfficheDialogue(0,self.CheminCourant)  
 + 
 +Ici on récupère les deux valeurs de retour qui sont renvoyées depuis le return. Pour le moment, ajoutez le code ci-dessous pour voir à quoi les informations retournées ressemblent : 
 + 
 +for f in fichiersChoisis: 
 + 
 +    print "Choix utilisateur : %s" % f 
 + 
 +print "Chemin courant : %s" % self.CheminCourant
  
 **When you run the program, click on the 'Add' button. You'll see the file dialog. Now move to somewhere where you have some files and select them. You can hold down the [ctrl] key and click on multiple files to select them individually, or the [shift] key to select multiple contiguous files. Click on the 'Open' button, and look at the response in your terminal window. Please note that if you click on the 'Cancel' button right now, you'll get an error message. That's because the above code assumes that there are no files selected. Don't worry about that right now - we'll handle that in a little bit. I just wanted to let you see what comes back if the 'Open' button is pressed. One thing we should do is add a filter to our file-open dialog. Since we expect the user to normally select music files, we should (1) give the option to display only music files, and (2) give the option to show all files just-in-case. We do this by using the filefilter attributes of the dialog. Here's the code for that which should go in the which == 0 section right after the dialog set line.  **When you run the program, click on the 'Add' button. You'll see the file dialog. Now move to somewhere where you have some files and select them. You can hold down the [ctrl] key and click on multiple files to select them individually, or the [shift] key to select multiple contiguous files. Click on the 'Open' button, and look at the response in your terminal window. Please note that if you click on the 'Cancel' button right now, you'll get an error message. That's because the above code assumes that there are no files selected. Don't worry about that right now - we'll handle that in a little bit. I just wanted to let you see what comes back if the 'Open' button is pressed. One thing we should do is add a filter to our file-open dialog. Since we expect the user to normally select music files, we should (1) give the option to display only music files, and (2) give the option to show all files just-in-case. We do this by using the filefilter attributes of the dialog. Here's the code for that which should go in the which == 0 section right after the dialog set line. 
Ligne 314: Ligne 328:
 dialog.add_filter(filter)** dialog.add_filter(filter)**
  
- +Lorsque vous exécutez le programme, cliquez sur le bouton « Ajouter ». Vous verrez la boîte de dialogue de fichier. Allez maintenant à un endroit où vous avez des fichiers et sélectionnez-les. Vous pouvez appuyer sur la touche [Ctrl] et cliquer sur plusieurs fichiers pour les sélectionner individuellement, ou sur la touche [Maj] pour sélectionner plusieurs fichiers contigus. Cliquez sur le bouton « Ouvrir », et examinez la réponse dans un terminal. Remarquez que si vous cliquez sur le bouton « Annuler » à ce moment, vous obtiendrez un message d'erreur. C'est parce que le code ci-dessus suppose qu'il n'y a pas de fichiers sélectionnés. Ne vous inquiétez pas pour l'instant, nous allons régler cela sous peu. Je voulais simplement vous permettre de voir ce qui revient si l'on appuie sur le bouton « Ouvrir ». Une chose que nous devrions faire est d'ajouter un filtre à notre fenêtre d'ouverture de fichier. Puisque nous attendons que l'utilisateur sélectionne normalement des fichiers de musique, nous devrions : 1) donner la possibilité d'afficher des fichiers de musique uniquement et, 2) donner la possibilité d'afficher tous les fichiers au cas où. Nous faisons cela en utilisant les attributs FileFilter de la boîte de dialogue. Voici le code pour cela, qu'il faut placer dans la partie « type == 0 » juste après la ligne créant le dialogue. 
 + 
 +filtre = gtk.FileFilter()  
 +filtre.set_name("Fichiers musicaux")  
 +filtre.add_pattern("*.mp3")  
 +filtre.add_pattern("*.ogg")  
 +filtre.add_pattern("*.wav")  
 +dialogue.add_filter(filtre)  
 +filtre = gtk.FileFilter()  
 +filtre.set_name("Tous les fichiers")  
 +filtre.add_pattern("*")  
 +dialogue.add_filter(filtre) 
  
 **We are setting up two "groups", one for music files (filter.set_name("Music Files")), and the other for all files. We use a pattern to define the types of files we want. I have defined three patterns, but you can add or delete any that you wish. I put the music filter first, since that's what we will assume the user is going to be mainly concerned with. So the steps are...  **We are setting up two "groups", one for music files (filter.set_name("Music Files")), and the other for all files. We use a pattern to define the types of files we want. I have defined three patterns, but you can add or delete any that you wish. I put the music filter first, since that's what we will assume the user is going to be mainly concerned with. So the steps are... 
Ligne 331: Ligne 356:
 so our routine now looks like the code shown on the next page.** so our routine now looks like the code shown on the next page.**
  
 +Nous mettons en place deux « groupes », l'un pour les fichiers de musique (filtre.set_name("Fichiers musicaux")), et l'autre pour tous les fichiers. Nous utilisons un motif pour définir les types de fichiers que nous voulons. J'ai défini trois motifs, mais vous pouvez ajouter ou supprimer tous ceux que vous souhaitez. Je mets le filtre pour la musique en premier, puisque c'est ce qui intéresse principalement l'utilisateur. Ainsi, les étapes sont :
  
 +• Définir une variable de filtre.
 +• Régler le nom.
 +• Ajouter un motif.
 +• Ajouter le filtre à la boîte de dialogue.
 +
 +Vous pouvez avoir autant ou aussi peu de filtres que vous le souhaitez. Notez également qu'une fois que vous avez ajouté le filtre à la boîte de dialogue, vous pouvez réutiliser la variable de filtre.
 +
 +Retournez dans la routine on_boBtnAjouter_clicked, commentez les dernières lignes que nous avons ajoutées et remplacez-les par cette seule ligne.
 +
 +self.AjouterFichiers(fichiersChoisis)
 +
 +Ainsi notre routine ressemble maintenant au code affiché sur la page suivante.
  
 **So, when we get the response back from file dialog, we will send the list containing the selected files to this routine. Once here, we set up a counter variable (how many files we are adding), then parse the list. Remember that each entry contains the fully qualified filename with path and extension. We'll want to split the filename into path, filename, and extension. First we get the very last 'period' from the filename and assume that is the beginning of the extension and assign its position in the string to extStart. Next we find the very last '/' in the filename to determine the beginning of the filename. Then we break up the string into extension, filename and file path. We then stuff these values into a list named 'data' and append this into our playlist ListStore. We increment the counter since we have done all the work. Finally we increment the variable RowCount which holds the total number of rows in our ListStore, and then we print a message to the status bar. **So, when we get the response back from file dialog, we will send the list containing the selected files to this routine. Once here, we set up a counter variable (how many files we are adding), then parse the list. Remember that each entry contains the fully qualified filename with path and extension. We'll want to split the filename into path, filename, and extension. First we get the very last 'period' from the filename and assume that is the beginning of the extension and assign its position in the string to extStart. Next we find the very last '/' in the filename to determine the beginning of the filename. Then we break up the string into extension, filename and file path. We then stuff these values into a list named 'data' and append this into our playlist ListStore. We increment the counter since we have done all the work. Finally we increment the variable RowCount which holds the total number of rows in our ListStore, and then we print a message to the status bar.
Ligne 341: Ligne 379:
 Next time, we'll finalize our application, filling in the missing routines, etc.** Next time, we'll finalize our application, filling in the missing routines, etc.**
  
 +Ainsi, lorsque nous aurons la réponse au retour de la fenêtre de sélection de fichiers, nous enverrons la liste contenant les fichiers sélectionnés à cette routine. Une fois ici, nous créons une variable de compteur (le nombre de fichiers que nous ajoutons), puis analysons la liste. Rappelez-vous que chaque entrée contient le nom de fichier complet avec le chemin et l'extension. Nous allons devoir fractionner le nom du fichier en chemin, nom de fichier et extension. Nous récupérons d'abord le tout dernier « . » dans le nom de fichier et supposons que c'est le début de l'extension, et nous affectons sa position dans la chaîne à debutExt. Nous trouvons ensuite le tout dernier « / » dans le nom du fichier pour déterminer le début du nom de fichier. Puis, nous découpons la chaîne en extension, nom de fichier et chemin du fichier. Nous plaçons ensuite ces valeurs dans une liste nommée « data » et ajoutons ceci dans listeLecture. Nous incrémentons le compteur puisque nous avons fait tout le travail. Enfin on incrémente la variable NombreDeLignes qui contient le nombre total de lignes dans listeLecture et nous affichons un message dans la barre d'état.
 +
 +Maintenant vous pouvez lancer l'application et voir les données dans l'arborescence.
 +
 +Comme toujours, le code complet peut être trouvé à http://pastebin.com/wTCcGDSW.
  
 +La prochaine fois, nous allons finaliser notre application, en remplissant les routines manquantes, etc.
  
 ====== CODE PAGE 7 ====== ====== CODE PAGE 7 ======
Ligne 486: Ligne 530:
         apropos.destroy()          apropos.destroy() 
  
-Maintenant, commentez (ou retirez simplement) l'appel à MessageBox dans la routine on_boBtnAPropos_clicked, et remplacez-le par un appel à la fonction AfficherAPropos. Cela devrait ressembler à cela.+Maintenant, commentez (ou retirez simplement) l'appel à MessageBox dans la routine on_boBtnAPropos_clicked, et remplacez-le par un appel à la fonction AfficherAPropos. Cela devrait ressembler à :
  
   def on_boBtnAPropos_clicked(self,widget):   def on_boBtnAPropos_clicked(self,widget):
Ligne 505: Ligne 549:
         self.AjouterColonne(self.sTypeFic,self.cTypeFic)         self.AjouterColonne(self.sTypeFic,self.cTypeFic)
         self.AjouterColonne(self.sCheminFic,self.cCheminFic)         self.AjouterColonne(self.sCheminFic,self.cCheminFic)
-        self.playList = gtk.ListStore(str,str,str) +        self.listeLecture = gtk.ListStore(str,str,str) 
-        self.treeview.set_model(self.playList)+        self.treeview.set_model(self.listeLecture)
         self.treeview.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)         self.treeview.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH)
  
Ligne 526: Ligne 570:
 ====== CODE PAGE 13 (milieu) ====== ====== CODE PAGE 13 (milieu) ======
  
-  class FileDialog+  class DialogueFichier
-    def ShowDialog(self,which,CheminCourant): +    def AfficheDialogue(self,type,CheminCourant): 
-        if which == 0: # choix de fichiers+        if type == 0: # choix de fichiers
             #gtk.FileChooserDialog(titre,parent,action,boutons,backend)             #gtk.FileChooserDialog(titre,parent,action,boutons,backend)
             dialog = gtk.FileChooserDialog("Choisir les fichiers a ajouter...",None,             dialog = gtk.FileChooserDialog("Choisir les fichiers a ajouter...",None,
Ligne 541: Ligne 585:
  
  
-Les deux lignes suivantes seront (en dehors de l'instruction if/else)...+Les deux lignes suivantes seront (en dehors de l'instruction if/else) :
  
         dialog.set_default_response(gtk.RESPONSE_OK)         dialog.set_default_response(gtk.RESPONSE_OK)
Ligne 556: Ligne 600:
  
         if reponse == gtk.RESPONSE_OK:         if reponse == gtk.RESPONSE_OK:
-            fileselection = dialog.get_filenames()+            selectionFichiers = dialog.get_filenames()
             CheminCourant = dialog.get_current_folder()             CheminCourant = dialog.get_current_folder()
             dialog.destroy()             dialog.destroy()
-            return (fileselection,CheminCourant)+            return (selectionFichiers,CheminCourant)
         elif reponse == gtk.RESPONSE_CANCEL:         elif reponse == gtk.RESPONSE_CANCEL:
             print 'Annulation, aucun fichier choisi'             print 'Annulation, aucun fichier choisi'
Ligne 567: Ligne 611:
  
     def on_boBtnAjouter_clicked(self,widget):     def on_boBtnAjouter_clicked(self,widget):
-        fd = FileDialog() +        fd = DialogueFichier() 
-        fichiersChoisis,self.CheminCourant = fd.ShowDialog(0,self.CheminCourant)        +        fichiersChoisis,self.CheminCourant = fd.AfficheDialogue(0,self.CheminCourant)        
         self.AjouterFichiers(fichiersChoisis)         self.AjouterFichiers(fichiersChoisis)
                  
Ligne 582: Ligne 626:
             cheminFic = f[:debutnomFic]             cheminFic = f[:debutnomFic]
             data = [nomFic,extension,cheminFic]             data = [nomFic,extension,cheminFic]
-            self.playList.append(data)+            self.listeLecture.append(data)
             compteur += 1             compteur += 1
         self.NombreDeLignes += compteur         self.NombreDeLignes += compteur
         self.sbar.push(self.context_id,"%s fichiers ajoutes sur un total de %d" % (compteur,self.NombreDeLignes))         self.sbar.push(self.context_id,"%s fichiers ajoutes sur un total de %d" % (compteur,self.NombreDeLignes))
  
issue48/tuto-python.1307895193.txt.gz · Dernière modification : 2011/06/12 18:13 de fredphil91