Rendez-vous sur Arrakis

Un GUI en python : TP 2, des dialogues

Nous sommes aujourd'hui réunis suite à un terrible constat : notre visionneuse tkv craint un max.
C'est pourquoi nous allons ajouter une toute petite option nous permettant de choisir l'image que l'on souhaite visualiser sur notre ordinateur. Cela nous permettra par la même occasion de nous débarasser de certains morceaux qui ne sont plus utiles.

Profitons des dialogues déjà prêts dans la bibliothèque de tkinter en important celle qui nous intéresse :

from tkinter import filedialog

Nous pouvons à la place du téléchargement de l'image appeler une fenêtre de dialogue pour demander l'image à ouvrir :

# Ouverture de l'image
 img_path = filedialog.askopenfilename(\
         initialdir=(os.path.expanduser("~")),\
         title="Image à ouvrir",\
         parent=w)
 

Notez ici plusieurs options :

Cela ne sufit pas, il faudrait proposer seulement les fichiers qui sont des images. On va donc indiquer les motifs qui nous intéressent (pattern). En gros, ce sont juste les extensions :

# Ouverture de l'image
 img_path = filedialog.askopenfilename(\
         initialdir=(os.path.expanduser("~")),\
         filetypes=[('Images', ('.png', '.PNG', '.jpg', '.JPG', '.gif', '.GIF')), ('Tout', '.*')],\
         title="Image à ouvrir",\
         parent=w)
 

On ajoute quand même un petit test pour vérifier que on a bien sélectionné un fichier valide. On utilise la bibliothque “mimetypes” qui est livrée par défaut avec python, et on regarde si le mot “image” apparait dans le type du fichier.
Pour afficher l'erreur, on utilise une fenêtre de dialogue livré avec tkinter après avoir importé la partie qui nous intéresse :

mimtyp = mimetypes.guess_type(img_path)[0] # i.e 'image/jpeg'
 if not mimtyp or "image" not in mimtyp :
     # Il n'y a pas le mot "image" dans le mimetype
     from tkinter import messagebox
     messagebox.showerror("Fichier invalide", "Le fichier demandé n'est pas une image.")
 

Et voilà !

Remarquez qu'il existe un tas de fenêtres de dialogue déjà toutes prêtes pour afficher des avertissements (showwarning) ou des informations (showinfo) ou de poser une simple question (askquestion). Regardez par ici pour plus de détails : http://effbot.org/tkinterbook/tkinter-standard-dialogs.htm .

Je vais rajouter quelques lignes pour afficher une image si elle est passée en argument (par exemple en faisant tkv /home/bibi/image.jpg) :


 # Ouverture de l'image
 if len(sys.argv) == 2:
     # On a une image en agument
     img_path = sys.argv[1]
 else:
     # On va chercher une image sur le disque
     img_path = filedialog.askopenfilename(\
     # ...
     # ...
 

Il reste encore quelques points à améliorer, mais ça reste déjà plus pratique. ^^
Ça sera tout pour aujourd'hui.
La prochaine fois, nous ajouterons quelques boutons à notre visionneuse d'images :)

Voici le code final :


 #!/usr/bin/env python
 # -*- coding:Utf-8 -*- 
 
 import os
 import sys
 import mimetypes
 from tkinter import *
 from tkinter import filedialog
 from PIL import Image, ImageTk
 
 
 # Notre fenêtre principale
 w = Tk()
 w.title("tkv : visionneuse d'images") # Un titre
 w.configure(background='#000000')     # Fond noir
 
 # Un conteneur dans la fenêtre
 mainframe = Frame(w)
 mainframe.pack(fill=BOTH,expand=True, padx=15, pady=15)
 
 # Ouverture de l'image
 img_path=""
 if len(sys.argv) == 2:
     # On a une image en agument
     img_path = sys.argv[1]
 
 if not os.path.isfile(img_path):
     # On va chercher une image sur le disque
     img_path = filedialog.askopenfilename(\
             initialdir=(os.path.expanduser("~")),\
             filetypes=[('Images', ('.png', '.PNG', '.jpg', '.JPG', '.gif', '.GIF')), ('Tout', '.*')],\
             title="Image à ouvrir",\
             parent=w)
 
 # Est-ce un fichier valide ?
 mimtyp = mimetypes.guess_type(img_path)[0] # i.e 'image/jpeg'
 if not mimtyp or "image" not in mimtyp :
     # Il n'y a pas le mot "image" dans le mimetype
     from tkinter import messagebox
     messagebox.showerror("Fichier invalide", "Le fichier demandé n'est pas une image.")
     sys.exit(1)
 
 # Ouverture de l'image
 image = Image.open(img_path)
 # Dimensions de l'écran : 
 gap = 100 # marge par rapport aux bordes de l'écran
 screen_width = w.winfo_screenwidth() - gap
 screen_height = w.winfo_screenheight() - gap
 
 if image.width > screen_width : 
     image = image.resize((screen_width, int(image.height * screen_width / image.width)), Image.ANTIALIAS)
 if image.height > screen_height :   
     image = image.resize((int(image.width * screen_height / image.height), screen_height), Image.ANTIALIAS)
 
 # Chargement de l'image en mémoire
 img = ImageTk.PhotoImage(image)
 
 # Insertion de l'image dans le conteneur.
 img_widget = Label(mainframe, image=img)
 img_widget.pack()
 
 # Démarrage du programme
 w.mainloop()
 
 sys.exit(0)
 

le 23/01/2017 à 17:42:46, Ned a dit :

Merci pour ce tuto. Pour info, le lien vers effbot est faux car il inclut le “.” final de la phrase.
HTH

le 23/01/2017 à 17:48:57, thuban a dit :

Ah merci pour le lien, je corrige !