Advertisement
Kaadem-85

photothèque.py

Nov 7th, 2016
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 39.23 KB | None | 0 0
  1. #!/usr/bin/python3
  2. # -*- coding: utf8 -*-
  3.  
  4. # Copyright © 2016 Ordinosor <https://twitter.com/Ordinosor>
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program.  If not, see <http://www.gnu.org/licenses/>
  17.  
  18. #==== IMPORTATION DES MODULES ============================================================================
  19.  
  20. from tkinter import* # Importation du module tkinter
  21. import os
  22. from PIL import Image, ImageTk  # Module PIL (traitement des images importées)
  23. import tkinter.messagebox
  24. import tkinter.filedialog
  25.  
  26. #=========================================================================================================
  27.  
  28. class Phototheque(object) :
  29.     "Classe instanciant la page 'Photothèque'"
  30.  
  31. #---------------------------------------------------------------------------------------------------------
  32.  
  33.     def __init__(self, fenetre):
  34.         "Méthode constructeur"
  35.         self.fenetre = fenetre
  36.  
  37. #---------------------------------------------------------------------------------------------------------
  38.        
  39.     def home(self):
  40.         "Page d'accueil"
  41.         self.rep = os.getcwd() # Retourne le répertoire courant
  42.         self.main_frame = Frame(self.fenetre, bg = 'white') # Cadre principal
  43.         self.main_frame.grid() # Gestionnaire de positionnement
  44.  
  45.         self.home = LabelFrame(self.main_frame, text=' MA PHOTOTHÈQUE ', labelanchor='n',\
  46.                     font='Times 40 italic', bg='white', relief='ridge', bd=3, padx=20, pady=20) # Titre
  47.         self.home.grid(row = 0, padx = 300, pady = 60)
  48.  
  49.         self.home_image = "/default_image.png" # Image de la page principale
  50.         self.image_home = Image.open(self.rep + self.home_image)
  51.         self.image_home_size = 512, 512
  52.         self.image_home.thumbnail(self.image_home_size) # Redimensionnement de l'image
  53.         self.home_photo = ImageTk.PhotoImage(self.image_home, master = self.fenetre)
  54.    
  55.         self.titre = Button(self.home, image=self.home_photo, bg = 'green', relief = 'ridge',\
  56.                      bd=2, padx = 40, cursor = 'hand2', command = self.folders)
  57.         self.titre.grid(padx = 100, sticky ='nsew') # Bouton de la page d'accueil
  58.                                                     # qui donne accès à la page des albums
  59.  
  60. #---------------------------------------------------------------------------------------------------------
  61.  
  62.     def folders(self, back_to_folders = None):
  63.         "Dossiers créés"
  64.  
  65.         self.back_to_folders = back_to_folders # Variable servant à afficher proprement la page
  66.                                                # lorsque l'utilisateur était dans un dossier qu'il a refermé.
  67.         self.image_folder = "/folder_icon.png" # Image de la page principale
  68.         self.folder_image = Image.open(self.rep + self.image_folder)
  69.         self.folder_image_size = 128, 128
  70.         self.folder_image.thumbnail(self.folder_image_size) # Redimensionnement de l'image
  71.         self.photo_folder = ImageTk.PhotoImage(self.folder_image, master = self.fenetre)
  72.  
  73.         if self.back_to_folders == True : # Si l'utilisateur revient sur la page des albums
  74.             for self.child in self.main_frame.winfo_children():
  75.                 self.child.destroy()
  76.             self.home = LabelFrame(self.main_frame, labelanchor='n', font='Times 40 italic', bg='white',\
  77.                         relief='ridge', bd=3, padx=20, pady=20)
  78.             self.home.grid(row = 0, padx = 300, pady = 60)
  79.  
  80.         for self.child in self.home.winfo_children():
  81.             if self.child.winfo_class() == 'Button':
  82.                 self.child.destroy()
  83.         self.home.config(text = ' Mes albums ')
  84.         self.home.grid(padx = 200)
  85.  
  86.         self.can_dossiers_defil = Scrollbar(self.main_frame, bg = 'green', relief='ridge',\
  87.                                   width = 18, orient = 'vertical', troughcolor = 'white', activebackground = 'green')
  88.         self.can_dossiers_defil.grid(row=0,column=1, rowspan = 2, sticky='ns') # Barre de défilement
  89.         self.can_dossiers = Canvas(self.home, bg = 'white', highlightthickness = 0 ,\
  90.                             scrollregion = (0,0,5000,5000),height = 500, width = 700, \
  91.                             yscrollcommand = self.can_dossiers_defil.set)
  92.         self.can_dossiers.grid(row = 0, column = 0)
  93.         self.can_dossiers.grid_propagate(0)
  94.         self.can_dossiers_defil.config(command=self.can_dossiers.yview)
  95.        
  96.         with open("dossiers_images", 'r') as self.dossiers_images : # Ouverture fichier
  97.             self.read_dossiers_images = self.dossiers_images.readlines()
  98.         self.a = 5      # Variables de positionnement des images dans le canvas
  99.         self.b = 10
  100.         self.list_buttons_images = [] # Liste qui contient les images illustrant les boutons de chaque album créé
  101.         self.list_labels_images = []  # Liste qui contient les noms des albums créés
  102.  
  103.         self.empty_folder_image = "/empty_folder.png" # image représentant un album vide (Bouton "Nouvel album")
  104.         self.image_empty_folder = Image.open(self.rep + self.empty_folder_image)
  105.         self.image_empty_folder_size = 100, 100
  106.         self.image_empty_folder.thumbnail(self.image_empty_folder_size) # Redimensionnement de l'image
  107.         self.empty_folder_photo = ImageTk.PhotoImage(self.image_empty_folder, master = self.fenetre)
  108.  
  109.  
  110.         self.new_folder_image = "/default_image.png" # Image illustrant un dossier créé mais qui ne contient aucune image
  111.         self.image_new_folder = Image.open(self.rep + self.new_folder_image)
  112.         self.new_folder_size = 128, 128
  113.         self.image_new_folder.thumbnail(self.new_folder_size)
  114.         self.new_folder_photo = ImageTk.PhotoImage(self.image_new_folder, master = self.fenetre)
  115.  
  116.         self.new_label = str()
  117.    
  118.         for i, element in enumerate(self.read_dossiers_images): # Parcours de la liste des albums créés
  119.             self.list_labels_images.append(self.read_dossiers_images[i].strip()) # Ajout de chaque nom d'album
  120.             self.folder_and_label = LabelFrame(self.can_dossiers, bg = 'white', bd = 0) # Création des cadres (Boutons + Labels)
  121.             #Placement des cadres dans le canvas
  122.             self.can_dossiers.create_window(self.b, self.a, anchor = 'nw', window = self.folder_and_label)
  123.             self.b += 140 # Incrémentation de la variable des colonnes
  124.             if self.b > 680 :
  125.                 self.a += 185 # Incrémentation de la variable des lignes
  126.                 self.b = 10
  127.             with open(self.read_dossiers_images[i].strip(), 'r') as self.file: # Ouverture du fichier de chaque album en mode lecture.
  128.                 self.read_file = self.file.readlines()
  129.  
  130.             if len(self.read_file) > 0 : # Si l'album contient des images, la 1ère image illustre le bouton.
  131.                 self.read_file_image =  self.read_file[0][0:self.read_file[0].index('~#~')]
  132.                 self.image_read_file = Image.open(self.read_file[0][0:self.read_file[0].index('~#~')])
  133.                 self.image_read_file_size = 160, 160
  134.                 self.image_read_file.thumbnail(self.image_read_file_size) # Redimensionnement de l'image
  135.                 self.read_file_photo = ImageTk.PhotoImage(self.image_read_file, master = self.fenetre)
  136.                 self.list_buttons_images.append(self.read_file_photo)                  
  137.                 self.folder = Button(self.folder_and_label, image = self.list_buttons_images[i],\
  138.                               bg = 'white', height = 100, width = 100, bd = 2, highlightthickness = 1,\
  139.                               command = lambda arg1 = self.read_dossiers_images[i].strip(), arg2 = self.home : self.phototheque(arg1, home = arg2))
  140.             elif len(self.read_file) == 0 : # Si l'album ne contient pas d'images, l'image par défaut s'affiche
  141.                 self.folder = Button(self.folder_and_label, image = self.new_folder_photo, bg = 'white',\
  142.                               height = 100, width = 100, bd = 2, highlightthickness = 1,\
  143.                               command = lambda arg1 = self.read_dossiers_images[i].strip(), arg2 = self.home : self.phototheque(arg1, home = arg2))
  144.             self.folder_label = Label(self.folder_and_label, bg = 'white', text = self.read_dossiers_images[i].strip(),\
  145.                                 font = ('Times', '11', 'italic')) #Noms de l'album
  146.             self.folder.grid(row = 0, column = 0)
  147.             self.folder_label.grid(row = 1, column = 0)
  148.             # Le clic droit sur le nom de l'album permet de renommer le dossier :
  149.             self.folder_label.bind('<Button-3>', lambda event, arg1 = self.folder_and_label, arg2 = self.folder_label['text']: self.rename(arg1, arg2))
  150.  
  151.  
  152.             if i == len(self.read_dossiers_images) - 1 :
  153.                 # Création du bouton "Nouvel album"
  154.                 self.folder_and_label = LabelFrame(self.can_dossiers, bg = 'white', bd = 0)
  155.                 self.can_dossiers.create_window(self.b, self.a, anchor = 'nw', window = self.folder_and_label)
  156.                 # Appel de le fonction self.warning_empty_entry si le nom de l'album n'est pas renseigné:
  157.                 self.new_folder = Button(self.folder_and_label, image = self.empty_folder_photo, bg = 'white',\
  158.                                   height = 100, width = 100, bd = 2, highlightthickness = 1, command = self.warning_empty_entry)
  159.                 self.new_folder.grid(row = 0, column = 0)
  160.                 # Création du champ d'entrée pour renseigner le nom du nouvel album:
  161.                 self.new_folder_entry = Entry(self.folder_and_label, bg = 'white', width = 10, font = ('Times', '12', 'bold italic'))
  162.                 self.new_folder_entry.grid(row = 1, column = 0)
  163.                 self.new_folder_entry.insert(0, "  Nouveau")
  164.                 # Liaisons du widget : effacement du contenu du champ d'entrée, création du nouvel album
  165.                 self.new_folder_entry.bind('<Button-1>', lambda event : self.new_folder_entry.delete(0, 'end'))
  166.                 self.new_folder_entry.bind('<Return>', self.add_folder)
  167.  
  168. #---------------------------------------------------------------------------------------------------------
  169.  
  170.     def add_folder(self, event):
  171.         "Création d'un nouvel album"
  172.         self.new_label = self.new_folder_entry.get() # Récupération du contenu du champ d'entrée
  173.         # Ouverture du fichier "Dossiers images" :
  174.         with open("dossiers_images", 'r') as self.dossiers_images :
  175.             self.read_dossiers = self.dossiers_images.readlines()
  176.             if self.new_label + '\n' in self.read_dossiers :
  177.                 # L'utilisateur doit donner un nom qui n'est pas déjà attribué :
  178.                 self.warning = tkinter.messagebox.showwarning('Nouvel album', 'Cet album existe déjà.')
  179.                 self.new_folder_entry.delete(0, 'end') # Effacement du champ d'entrée
  180.             else : # Ouverture du fichier "dossiers_images" en mode append et écriture du nom du nouvel album
  181.                 with open("dossiers_images", 'a') as self.dossiers_images:
  182.                     self.dossiers_images.write(self.new_folder_entry.get() + '\n')
  183.                 # Création du nouveau fichier images (vide pour l'instant)
  184.                 with open(self.new_folder_entry.get(), 'w') as self.new_file:
  185.                     # Appel de la méthode photothèque qui ouvre le nouvel album:
  186.                     self.phototheque(self.new_folder_entry.get(), home = self.home)
  187.                    
  188. #---------------------------------------------------------------------------------------------------------
  189.  
  190.     def warning_empty_entry(self):
  191.         """Le champ d'entrée est rouge pendant une seconde pour prévenir
  192.           l'utilisateur qu'il doit renseigner le nom de l'album qu'il souhaite créer."""
  193.         self.new_folder_entry.config(bg = 'red', fg = 'white')
  194.         # Méthode "after":
  195.         self.new_folder_entry.after(1000, lambda : self.new_folder_entry.config(bg = 'white', fg = 'black'))
  196.        
  197. #---------------------------------------------------------------------------------------------------------
  198.  
  199.     def rename(self, folder_and_label, curlabel):
  200.         "Méthode permettant de renommer un dossier"
  201.         self.folder_and_label = folder_and_label
  202.         self.curlabel = curlabel # curlabel = current label (i.e le nom actuel de l'album à renommer)
  203.         # Boucle qui parcourt les albums existants :
  204.         for i in range(0, len(self.can_dossiers.winfo_children())):
  205.             for i2 in self.can_dossiers.winfo_children()[i].winfo_children():
  206.                 self.index_i2 = self.can_dossiers.winfo_children()[i].winfo_children().index(i2)  
  207.                 # si le nom de l'album correspond à la variable self.current label:      
  208.                 if i2.winfo_class() == 'Label' and i2['text'] == self.curlabel:
  209.                     i2.destroy() # Destruction du nom et remplacement par un champ d'entrée:
  210.                     self.entry_replacing_label = Entry(self.can_dossiers.winfo_children()[i], bg = 'white', width = 10)
  211.                     self.entry_replacing_label.grid(row = 1, column = 0)
  212.                     self.index_i(i) # Appel de la méthode "index_i"
  213.                     # Méthode after : Après 4 secondes, appel de la fonction close_entry
  214.                     self.can_dossiers.after(4000, lambda : self.close_entry(self.folder_and_label, self.entry_replacing_label))
  215.                    
  216. #---------------------------------------------------------------------------------------------------------
  217.                    
  218.     def close_entry(self, folder_and_label, entry_replacing_label):
  219.         "Ferme le champ d'entrée si l'utilisateur n'a toujours pas entré de nouveau nom après 4 secondes"
  220.         self.folder_and_label = folder_and_label
  221.         self.entry_replacing_label = entry_replacing_label
  222.         if self.entry_replacing_label.get() == '' :
  223.             self.entry_replacing_label.destroy()
  224.             self.back_folder_label = Label(self.folder_and_label, bg = 'white', text = self.curlabel,\
  225.                                      font = ('Times', '12', 'italic')) #Noms de l'album
  226.             self.back_folder_label.grid(row = 1, column = 0)
  227.             self.back_folder_label.bind('<Button-3>', lambda event, arg1 = self.folder_and_label, arg2 = self.curlabel : self.rename(arg1, arg2))
  228.            
  229. #---------------------------------------------------------------------------------------------------------
  230.  
  231.     def index_i(self, i):
  232.         "Liaison du widget Entry à la méthode new_text"
  233.         self.i = i
  234.         self.can_dossiers.winfo_children()[self.i].winfo_children()[1].bind('<Return>', lambda event : self.new_text(self.i))
  235.        
  236. #---------------------------------------------------------------------------------------------------------
  237.  
  238.     def new_text(self, i):
  239.         "Renommage du dossier"
  240.         self.i = i # Variable itérative
  241.         # Affectation de la nouvelle valeur récupérée dans le widget Entry:
  242.         self.newlabel = self.can_dossiers.winfo_children()[self.i].winfo_children()[1].get()
  243.         with open('dossiers_images', 'r') as self.dossiers : # Ouverture du fichier "dossiers_images"
  244.             self.read_dossiers = self.dossiers.readlines() #Copie du fichier dans une liste
  245.             # Suppression de la ligne contenant le nom actuel de l'album
  246.             # pour éviter l'apparition du message de la ligne 233
  247.             # qui n'a pas lieu d'apparaître s'il s'agit de l'album à renommer:
  248.             self.read_dossiers.remove(self.read_dossiers[self.i])
  249.         if self.newlabel + '\n' in self.read_dossiers : # Si le nouveau nom est déjà dans l'album :
  250.             self.warning = tkinter.messagebox.showwarning('Nouvel album', 'Cet album existe déjà.')
  251.             # Le widget Entry est vidé de son contenu :
  252.             self.can_dossiers.winfo_children()[self.i].winfo_children()[1].delete(0, 'end')
  253.         else :
  254.             # Destruction du widget Entry:
  255.             self.can_dossiers.winfo_children()[self.i].winfo_children()[1].destroy()
  256.             # Instanciation d'un widget Label avec le nouveau nom de l'album :
  257.             self.new_folder_label = Label(self.can_dossiers.winfo_children()[self.i], bg = 'white',\
  258.                                     text = self.newlabel, font = ('Times', '12', 'italic'))
  259.             self.new_folder_label.grid(row = 1, column = 0)
  260.             # Liaison du widget Label avec la méthode self.rename
  261.             # au cas ou l'utilisateur souhaite renommer une deuxième fois son album:
  262.             self.new_folder_label.bind('<Button-3>', lambda event, arg = self.newlabel : self.rename(arg))
  263.             # Renommage de l'album dans le système d'exploitation:
  264.             os.rename(self.curlabel, self.newlabel)
  265.             # Renommage de l'album dans le fichier "dossiers_images":
  266.             with open('dossiers_images', 'r') as self.dossiers:
  267.                 self.read_dossiers = self.dossiers.readlines()
  268.                 for i, element in enumerate (self.read_dossiers) :
  269.                     if self.read_dossiers[i] == self.curlabel + '\n':
  270.                         self.read_dossiers.remove(self.read_dossiers[i])
  271.                         self.read_dossiers[i:i] = [self.newlabel+ '\n']
  272.             # Effacement du fichier contenant l'ancien nom de l'album
  273.             # et réécriture avec le nouveau nom:
  274.             with open('dossiers_images', 'w') as self.dossiers:
  275.                 for i, element  in enumerate (self.read_dossiers) :
  276.                     self.dossiers.write(self.read_dossiers[i])
  277.  
  278. #---------------------------------------------------------------------------------------------------------
  279.  
  280.     def phototheque(self, import_photos, pictures = None, legende = None, apercu_image = None, home = None) :
  281.         "Ouverture de l'album après avoir cliqué sur le bouton"
  282.         self.import_photos = import_photos
  283.         self.pictures = pictures
  284.         self.legende = legende
  285.         self.apercu_image = apercu_image
  286.         self.home = home
  287.         self.back_to_folders = True
  288.        
  289.         # Destruction des éventuels widgets avant d'afficher les images
  290.         if not self.home == None :
  291.             self.home.destroy()
  292.         if not self.legende == None and not self.apercu_image == None:
  293.             self.legende.delete(0, 'end')
  294.             self.apercu_image.destroy()
  295.         if self.pictures != None:
  296.             for self.child in self.pictures.winfo_children():
  297.                 self.child.destroy()
  298.         else :
  299.             self.pictures_defil = Scrollbar(self.main_frame, bg = 'green', relief='ridge', width = 18,\
  300.                                   orient = 'vertical', troughcolor = 'white', activebackground = 'green')
  301.             self.pictures_defil.grid(row=0,column=1, rowspan = 2, sticky='ns')
  302.             self.pictures = Canvas(self.main_frame, bg='white', height = 700, width = 1100, scrollregion = (0,0,10000,10000), highlightbackground = 'green', yscrollcommand = self.pictures_defil.set) 
  303.             self.pictures.grid(row=1, column=0, padx = 30, pady = 10)
  304.             self.pictures.config(scrollregion=self.pictures.bbox('all'))
  305.             self.pictures_defil.config(command=self.pictures.yview)
  306.  
  307.             # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
  308.  
  309.             # Images illustrant les boutons de la barre de tâches :
  310.             self.upload_image = "/upload.png" # Image de la page principale
  311.             self.image_upload = Image.open(self.rep + self.upload_image)
  312.             self.image_upload_size = 70, 70
  313.             self.image_upload.thumbnail(self.image_upload_size) # Redimensionnement de l'image
  314.             self.photo_upload = ImageTk.PhotoImage(self.image_upload, master = self.fenetre)
  315.  
  316.             self.image_corbeille = "/corbeille.png" # Image de la page principale
  317.             self.corbeille_image = Image.open(self.rep + self.image_corbeille)
  318.             self.corbeille_image_size = 64, 64
  319.             self.corbeille_image.thumbnail(self.corbeille_image_size) # Redimensionnement de l'image
  320.             self.photo_corbeille = ImageTk.PhotoImage(self.corbeille_image, master = self.fenetre)
  321.            
  322.             self.image_folder = "/folder_icon.png" # Image de la page principale
  323.             self.folder_image = Image.open(self.rep + self.image_folder)
  324.             self.folder_image_size = 64, 64
  325.             self.folder_image.thumbnail(self.folder_image_size) # Redimensionnement de l'image
  326.             self.photo_folder = ImageTk.PhotoImage(self.folder_image, master = self.fenetre)
  327.  
  328.             self.image_rotate = "/image_rotate.png"
  329.             self.rotate_image = Image.open(self.rep + self.image_rotate)
  330.             self.rotate_image_size = 64, 64
  331.             self.rotate_image.thumbnail(self.rotate_image_size) # Redimensionnement de l'image
  332.             self.photo_rotate = ImageTk.PhotoImage(self.rotate_image, master = self.fenetre)
  333.            
  334.             # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
  335.  
  336.             # Création des boutons (téléversement, corbeille, albums):
  337.             self.icons = LabelFrame(self.main_frame, bg = 'white', bd = 0)
  338.             self.icons.grid(row = 0, sticky = 'w', pady = 20, padx = 20)
  339.             self.import_picture = Button(self.icons,image = self.photo_upload, bd = 1,\
  340.                                   highlightthickness = 1, command = self.importer)
  341.             self.import_picture.grid(row = 0, sticky = 'w', padx = 5)
  342.             self.delete_folder = Button(self.icons,image = self.photo_corbeille, bd = 2,\
  343.                                  highlightthickness = 1, command = self.tout_supprimer)
  344.             self.delete_folder.grid(row = 0, column = 1, sticky = 'w', padx = 5)
  345.             self.open_folder = Button(self.icons,image = self.photo_folder, bd = 2,\
  346.                                highlightthickness = 1, command = lambda arg = self.back_to_folders : self.folders(arg))
  347.             self.open_folder.grid(row = 0, column = 2, sticky = 'w', padx = 5)
  348.             self.legende = Entry(self.icons, width = 60, font = ('Times', '14', 'bold'),\
  349.                            highlightbackground = 'green', disabledbackground = 'white', state = 'disabled')
  350.             self.legende.grid(row = 0, column = 3, sticky = 'w', padx = 5)
  351.        
  352.         self.liste_photos = []
  353.         self.a = 25
  354.         self.b = 10
  355.         self.c = 0
  356.         # Ouverture du fichier contenant les images de l'album sélectionné:
  357.         with open(self.import_photos, 'r') as self.fichier :
  358.             self.readfile = self.fichier.readlines()
  359.             # Compréhensions de liste [liste des images, liste des légendes]
  360.             self.readfile2 = [self.readfile[i][0:self.readfile[i].index('~#~')] for i, element in enumerate(self.readfile)]
  361.             self.readfile3 = [self.readfile[i][(self.readfile[i].index('~#~') + 3):] for i, element in enumerate(self.readfile)]
  362.             for i, element in enumerate(self.readfile2):
  363.                 if self.b > 1070 : # Variables de positionnement des images
  364.                     self.a += 350
  365.                     self.b = 10
  366.                 self.liste_photos.append(self.readfile[i])
  367.                 self.image = Image.open(self.readfile2[i].strip())
  368.                 self.image2 = Image.open(self.readfile2[i].strip())
  369.                 self.photo = Boutons_photos(self.fenetre, self.import_photos, self.main_frame,\
  370.                              self.pictures, self.image, self.image2, self.readfile3[i], self.a,\
  371.                              self. b, self.c, self.liste_photos) # Création des objets boutons-photos
  372.                 self.c+=1   # Variable d'indexation des photos
  373.                 self.photo.creation_bouton() #Appel de la méthode de création des boutons-photos
  374.                 self.b += 270
  375.  
  376. #---------------------------------------------------------------------------------------------------------
  377.  
  378.     def importer(self):
  379.         "Méthode permettant d'importer des photos"
  380.         self.path = tkinter.filedialog.askopenfilename(title="Importer une image",filetypes=[('png files','.png'),('all files','.*')])
  381.         self.apercu = Image.open(self.path)
  382.         self.apercu_size = 128, 128
  383.         self.apercu.thumbnail(self.apercu_size) # Redimensionnement de l'image
  384.         self.apercu_photo = ImageTk.PhotoImage(self.apercu, master = self.fenetre)
  385.         self.legende.config(state = 'normal')
  386.         self.legende.insert(0, "  Saisissez la légende de la photo à importer.")
  387.         self.apercu_image = Label(self.icons, image = self.apercu_photo)
  388.         self.apercu_image.grid(row = 0, column = 4, padx = 5)
  389.         self.legende.bind('<Button-1>', lambda event : self.delete_legende())
  390.        
  391. #---------------------------------------------------------------------------------------------------------
  392.  
  393.     def delete_legende(self):
  394.         "Vide le message qui s'affiche de le champ d'entrée des légendes"
  395.         self.legende.delete(0, 'end')
  396.         self.legende.config(bg = 'white', fg = 'black')
  397.         self.legende.bind('<Return>', lambda event : self.get_legende())
  398.        
  399. #---------------------------------------------------------------------------------------------------------
  400.  
  401.     def get_legende(self):
  402.         "Récupération de la légende entrée par l'utilisateur pour une image téléchargée"    
  403.         self.gotten_legend = self.legende.get()
  404.         self.read_file2 = []
  405.         with open(self.import_photos, 'r') as self.file :
  406.             self.read_file = self.file.readlines()
  407.         for i in self.read_file : # Récupération de toutes les légendes
  408.             i = i[i.index('~#~') + 3:].strip()
  409.             self.read_file2.append(i)
  410.         if self.gotten_legend in self.read_file2: # Messages d'avertissement
  411.             self.warning = tkinter.messagebox.showwarning('Légende', 'Il existe déjà une image "' + self.gotten_legend + '".')
  412.         elif self.gotten_legend.isspace() == True or self.gotten_legend == '' or self.gotten_legend.startswith("  Saisissez") :
  413.             self.warning = tkinter.messagebox.showwarning('Légende', 'Saisissez une légende pour la photo importée.')
  414.         else:
  415.             with open(self.import_photos, 'r') as self.file :
  416.                 self.read_file = self.file.readlines()
  417.             self.read_file.append(self.path + '~#~' + self.gotten_legend + '\n')
  418.             with open(self.import_photos, 'w') as self.file :
  419.                 for i in self.read_file :
  420.                     self.file.write(i) # Réécriture du fichier contenant les images de l'album
  421.             self.phototheque(self.import_photos, self.pictures, self.legende, self.apercu_image) # Appel de la méthode phototheque après avoir chargé la nouvelle photo
  422.  
  423. #---------------------------------------------------------------------------------------------------------
  424.  
  425.     def tout_supprimer(self):
  426.         "Supprime l'album sélectionné"
  427.         self.oui_non = tkinter.messagebox.askyesnocancel("supprimer l'album?", 'Souhaitez-vous vraiment supprimer cet album?\nCette opération est irréversible.')
  428.         if self.oui_non == False or self.oui_non == None :                     
  429.             pass
  430.         elif self.oui_non == True :
  431.             with open('dossiers_images', 'r') as self.folder :
  432.                 self.read_folder = self.folder.readlines()
  433.             for i, element in enumerate(self.read_folder):
  434.                 if self.import_photos == self.read_folder[i].strip():
  435.                       self.read_folder.remove(self.read_folder[i])
  436.             with open('dossiers_images', 'w') as self.folder :
  437.                 for i, element in enumerate(self.read_folder):
  438.                     self.folder.write(self.read_folder[i])
  439.             os.remove(self.rep + '/' + self.import_photos)
  440.             self.back_to_folders = True
  441.             self.folders(self.back_to_folders)
  442.  
  443. #=========================================================================================================
  444.  
  445. class Boutons_photos(Phototheque) :
  446.     "Classe instanciant les 'boutons-photos' et les photos en taille originale"
  447.    
  448. #---------------------------------------------------------------------------------------------------------
  449.    
  450.     def __init__(self, fenetre, import_photos, main_frame, pictures, image, image2, photo_label,a, b, c, liste_photos) :
  451.         "Méthode constructeur"
  452.         Phototheque.__init__(self, fenetre)
  453.         self.import_photos = import_photos
  454.         self.main_frame = main_frame
  455.         self.pictures = pictures
  456.         self.image = image 
  457.         self.image2 = image2
  458.         self.photo_label = photo_label
  459.         self.a = a
  460.         self.b = b
  461.         self.c = c
  462.         self.c2 = None
  463.         self.liste_photos = liste_photos
  464.         self.dico = {}
  465.              
  466. #---------------------------------------------------------------------------------------------------------
  467.  
  468.     def creation_bouton(self) :
  469.         "Méthode de création des 'boutons-photos'"
  470.         self.rep = os.getcwd() # Retourne le répertoire courant
  471.         self.adresse_can2 = []
  472.        
  473.         self.size = 256, 256
  474.         self.image.thumbnail(self.size)
  475.         self.photo = ImageTk.PhotoImage(self.image)
  476.                
  477.         self.cross_image = "/croix.png" # Image de la croix (pour supprimer les images)
  478.         self.image_cross = Image.open(self.rep + self.cross_image)
  479.         self.image_cross_size = 16, 16
  480.         self.image_cross.thumbnail(self.image_cross_size) # Redimensionnement de l'image
  481.         self.cross_photo = ImageTk.PhotoImage(self.image_cross, master = self.fenetre)
  482.        
  483.         self.can2 = Canvas(self.pictures, bg='white', highlightthickness=0, bd = 0)
  484.         self.pictures.create_window(self.b, self.a, anchor = 'nw', window = self.can2)
  485.         # Création d'une liste de deux éléments avec self.c (pour l'indexation)
  486.         # et self.can2(pour la photo et le bouton de suppression)
  487.         self.adresse_can2.append(self.c)       
  488.         self.adresse_can2.append(self.can2)
  489.         self.mini_photo = Button(self.can2, bg='white', bd=0, image=self.photo,\
  490.                           activebackground='green', cursor='hand2', command = self.agrandir_pivoter)
  491.         self.mini_photo.grid(row=0, column = 0, sticky ='n')
  492.         self.cross = Button(self.can2, image = self.cross_photo, highlightthickness = 0,\
  493.                      bd = 0 , cursor='hand2', command = self.supprimer)
  494.         self.cross.grid(row=0, column = 0, sticky = 'ne')
  495.         self.label_photo = Label(self.can2, bg = 'white', text = self.photo_label,\
  496.                            font = ('Times', '12', 'bold'), wraplength = 200, pady = 5)
  497.         self.label_photo.grid(row = 1, sticky='n')
  498.         # Liaison du label à la méthode rename:
  499.         self.label_photo.bind('<Button-3>', lambda event : self.rename_picture(self.label_photo['text'], self.can2))
  500.  
  501. #---------------------------------------------------------------------------------------------------------      
  502.  
  503.     def rename_picture(self, curlabel, can2):
  504.         "Renommage des images"
  505.         self.curlabel = curlabel
  506.         self.can2 = can2
  507.         for i in range(0, len(self.pictures.winfo_children())):
  508.             for i2 in self.pictures.winfo_children()[i].winfo_children():
  509.                 self.index_i2 = self.pictures.winfo_children()[i].winfo_children().index(i2)          
  510.                 if i2.winfo_class() == 'Label' and i2['text'] == self.curlabel:
  511.                     i2.destroy()
  512.                     i2 = Entry(self.can2, bg = 'white', width = 10)
  513.                     i2.grid(row = 1, column = 0)
  514.                     self.pic_index_i(i)
  515.                    
  516. #---------------------------------------------------------------------------------------------------------      
  517.  
  518.     def pic_index_i(self, i):
  519.         "Liaison du widget Entry à la méthode pic_new_text"
  520.         self.i = i
  521.         self.pictures.winfo_children()[self.i].winfo_children()[2].bind('<Return>', lambda event : self.pic_new_text(self.i))
  522.  
  523. #---------------------------------------------------------------------------------------------------------      
  524.  
  525.     def pic_new_text(self, i):
  526.         "Renommage des images"  # Les trois méthodes (rename_picture, pic_index_i et pic_new_text) sont liées.
  527.         self.i = i
  528.         self.pic_newlabel = self.pictures.winfo_children()[self.i].winfo_children()[2].get()
  529.         self.pictures.winfo_children()[self.i].winfo_children()[2].destroy()
  530.         self.in_file = False
  531.         self.new_picture_label = Label(self.pictures.winfo_children()[self.i], bg = 'white', font = ('Times', '12', 'bold'))
  532.         self.new_picture_label.grid(row = 1, column = 0)
  533.         self.new_picture_label.bind('<Button-3>', lambda event, arg1 = self.curlabel, arg2 = self.can2 : self.rename_picture(arg1, arg2))
  534.        
  535.         with open(self.import_photos, 'r') as self.file :
  536.             self.read_file = self.file.readlines()
  537.             self.read_file2 = []
  538.         for i in self.read_file :
  539.             i = i[i.index('~#~') + 3:].strip()
  540.             self.read_file2.append(i)
  541.         if self.pic_newlabel in self.read_file2:
  542.             self.in_file = True
  543.             self.warning = tkinter.messagebox.showwarning('Légende', 'Il existe déjà une image intitulée "' + self.pic_newlabel + '".')
  544.             self.pic_newlabel = self.curlabel
  545.             self.new_picture_label.config(text = self.curlabel)
  546.         if self.in_file == False :
  547.             with open(self.import_photos, 'r') as self.file:
  548.                 self.read_file = self.file.readlines()
  549.             for i, element in enumerate (self.read_file) :
  550.                 if self.read_file[i][self.read_file[i].index("~#~")+3:] == self.curlabel:
  551.                     self.read_file[i] = self.read_file[i].replace(self.curlabel, self.pic_newlabel + '\n') # Remplacement de l'ancienne légende par la nouvelle
  552.             with open(self.import_photos, 'w') as self.file:
  553.                 for i in self.read_file :
  554.                     self.file.write(i)
  555.             self.new_picture_label.config(text = self.pic_newlabel)
  556.         self.phototheque(self.import_photos)
  557.  
  558. #---------------------------------------------------------------------------------------------------------      
  559.            
  560.     def agrandir_pivoter(self):
  561.         "Agrandir ou pivoter la photo?"
  562.         self.image_resize = "/resize.png"
  563.         self.image4 = Image.open(self.rep + self.image_resize)
  564.         self.image4_size = 96, 96
  565.         self.image4.thumbnail(self.image4_size) # Redimensionnement de l'image
  566.         self.photo_resize = ImageTk.PhotoImage(self.image4, master = self.fenetre)
  567.  
  568.         self.image_rotate = "/image_rotate.png"
  569.         self.image5 = Image.open(self.rep + self.image_rotate)
  570.         self.image5_size = 96, 96
  571.         self.image5.thumbnail(self.image5_size) # Redimensionnement de l'image
  572.         self.photo_rotate = ImageTk.PhotoImage(self.image5, master = self.fenetre)
  573.        
  574.         self.choix = Toplevel(name = 'selected', bg  = 'white')
  575.         self.label_agrandir_pivoter = Label(self.choix, bg = 'white', fg = 'black', text = "Voulez-vous agrandir\nou pivoter la photo?", font = ('Times', '14', 'bold'))
  576.         self.label_agrandir_pivoter.grid(row = 0, column = 0, columnspan = 2, padx = 10, pady = 5)
  577.         self.agrandissement = Button(self.choix, image = self.photo_resize, bg = 'black', bd = 2, highlightthickness = 1, command = self.photo_agrandie)
  578.         self.agrandissement.grid(row = 1, column = 0, sticky = 'w', padx = 10, pady = 10)
  579.         self.rotate_image = Button(self.choix, image = self.photo_rotate, bg = 'black', bd = 2, highlightthickness = 1, command = self.rotate)
  580.         self.rotate_image.grid(row = 1, column = 1, sticky = 'w', padx = 10, pady = 10)
  581.        
  582. #---------------------------------------------------------------------------------------------------------      
  583.  
  584.     def photo_agrandie(self) :
  585.         "Méthode permettant d'agrandir les photos"
  586.         self.grande_photo = Toplevel(name = 'selected')
  587.         self.photo2 = ImageTk.PhotoImage(self.image2)
  588.         if self.image2.size[0] > 768 and self.image2.size[1] > 768:
  589.             self.image2_size = 1024, 1024
  590.             self.image2.thumbnail(self.image2_size)
  591.         self.photo2 = ImageTk.PhotoImage(self.image2)
  592.         self.label_photo = Label(self.grande_photo, image = self.photo2)
  593.         self.label_photo.grid()
  594.  
  595. #---------------------------------------------------------------------------------------------------------      
  596.  
  597.     def rotate(self):
  598.         "Pivote l'image"
  599.         self.im2_rotate = self.image2.rotate(270, expand = True)
  600.         with open(self.import_photos, 'r') as self.file :
  601.             self.readfile = self.file.readlines()
  602.         self.filename = self.readfile[self.c][13:self.readfile[self.c].index('~#~')]
  603.         self.im2_rotate.save(self.filename)
  604.         self.phototheque(self.import_photos, self.pictures)
  605.         self.choix.destroy()
  606.  
  607. #---------------------------------------------------------------------------------------------------------      
  608.        
  609.     def supprimer(self) :
  610.         "Méthode permettant de supprimer des photos"
  611.         self.oui_non = tkinter.messagebox.askyesnocancel('supprimer la photo?', 'Souhaitez-vous vraiment supprimer cette photo?')
  612.         if self.oui_non == False or self.oui_non == None :
  613.             pass
  614.         elif self.oui_non == True :
  615.             self.d = 0 # Variable d'indexation
  616.             self.list_can2 = []
  617.             self.picture_path = []
  618.             for can2 in self.pictures.winfo_children() :
  619.                 if can2 != self.mini_photo and can2 != self.cross :
  620.                     self.list_can2.append(self.d)
  621.                     self.d += 1
  622.             for i in range(0, len(self.liste_photos)) :
  623.                 self.sous_liste = []
  624.                 self.sous_liste.append(self.list_can2[i]) # L'index et le chemin de chaque photo sont placés dans la sous-liste elle-même placée dans la liste self.picture_path.
  625.                 self.sous_liste.append(self.liste_photos[i])
  626.                 self.picture_path.append(self.sous_liste)
  627.             j = 0
  628.             while j < len(self.picture_path):
  629.                 if  self.adresse_can2[0] == self.picture_path[j][0] : # On compare l'indice de la photo à supprimer avec les indices de la liste
  630.                     self.picture_path.remove(self.picture_path[j])      # Si il y a concordance, on supprime l'indice et le chemin de la liste
  631.                 j+=1   
  632.             self.can2.destroy() # Destruction de la photo
  633.             with open(self.import_photos, 'w') as self.fichier :
  634.                 for k in range(0, len(self.picture_path)):
  635.                     self.fichier.write(self.picture_path[k][1]) #Réécriture du fichier sans le chemin précédemment supprimé.
  636.             self.phototheque(self.import_photos, self.pictures)
  637.  
  638.  
  639. # ============MAIN PROGRAMM ================================================== :
  640.  
  641. if __name__ == "__main__":
  642.  
  643.     fenetre = Tk()
  644.     fenetre.title('Photothèque')
  645.  
  646.     phototheque = Phototheque(fenetre)
  647.     phototheque.home()
  648.  
  649.     fenetre.mainloop() # Démarrage du réceptionnaire d'événements
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement