Kaadem-85

phototheque.py

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