Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python3
- # -*- coding: utf8 -*-
- # Copyright © 2016 Ordinosor <https://twitter.com/Ordinosor>
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>
- #==== IMPORTATION DES MODULES ============================================================================
- from tkinter import* # Importation du module tkinter
- import os
- from PIL import Image, ImageTk # Module PIL (traitement des images importées)
- import tkinter.messagebox
- import tkinter.filedialog
- #=========================================================================================================
- class Phototheque(object) :
- "Classe instanciant la page 'Photothèque'"
- #---------------------------------------------------------------------------------------------------------
- def __init__(self, fenetre):
- "Méthode constructeur"
- self.fenetre = fenetre
- #---------------------------------------------------------------------------------------------------------
- def home(self):
- "Page d'accueil"
- self.rep = os.getcwd() # Retourne le répertoire courant
- self.main_frame = Frame(self.fenetre, bg = 'white') # Cadre principal
- self.main_frame.grid() # Gestionnaire de positionnement
- self.home = LabelFrame(self.main_frame, text=' MA PHOTOTHÈQUE ', labelanchor='n',\
- font='Times 40 italic', bg='white', relief='ridge', bd=3, padx=20, pady=20) # Titre
- self.home.grid(row = 0, padx = 300, pady = 60)
- self.home_image = "/default_image.png" # Image de la page principale
- self.image_home = Image.open(self.rep + self.home_image)
- self.image_home_size = 512, 512
- self.image_home.thumbnail(self.image_home_size) # Redimensionnement de l'image
- self.home_photo = ImageTk.PhotoImage(self.image_home, master = self.fenetre)
- self.titre = Button(self.home, image=self.home_photo, bg = 'green', relief = 'ridge',\
- bd=2, padx = 40, cursor = 'hand2', command = self.folders)
- self.titre.grid(padx = 100, sticky ='nsew') # Bouton de la page d'accueil
- # qui donne accès à la page des albums
- #---------------------------------------------------------------------------------------------------------
- def folders(self, back_to_folders = None):
- "Dossiers créés"
- self.back_to_folders = back_to_folders # Variable servant à afficher proprement la page
- # lorsque l'utilisateur était dans un dossier qu'il a refermé.
- self.image_folder = "/folder_icon.png" # Image de la page principale
- self.folder_image = Image.open(self.rep + self.image_folder)
- self.folder_image_size = 128, 128
- self.folder_image.thumbnail(self.folder_image_size) # Redimensionnement de l'image
- self.photo_folder = ImageTk.PhotoImage(self.folder_image, master = self.fenetre)
- if self.back_to_folders == True : # Si l'utilisateur revient sur la page des albums
- for self.child in self.main_frame.winfo_children():
- self.child.destroy()
- self.home = LabelFrame(self.main_frame, labelanchor='n', font='Times 40 italic', bg='white',\
- relief='ridge', bd=3, padx=20, pady=20)
- self.home.grid(row = 0, padx = 300, pady = 60)
- for self.child in self.home.winfo_children():
- if self.child.winfo_class() == 'Button':
- self.child.destroy()
- self.home.config(text = ' Mes albums ')
- self.home.grid(padx = 200)
- self.can_dossiers_defil = Scrollbar(self.main_frame, bg = 'green', relief='ridge',\
- width = 18, orient = 'vertical', troughcolor = 'white', activebackground = 'green')
- self.can_dossiers_defil.grid(row=0,column=1, rowspan = 2, sticky='ns') # Barre de défilement
- self.can_dossiers = Canvas(self.home, bg = 'white', highlightthickness = 0 ,\
- scrollregion = (0,0,5000,5000),height = 500, width = 700, \
- yscrollcommand = self.can_dossiers_defil.set)
- self.can_dossiers.grid(row = 0, column = 0)
- self.can_dossiers.grid_propagate(0)
- self.can_dossiers_defil.config(command=self.can_dossiers.yview)
- with open("dossiers_images", 'r') as self.dossiers_images : # Ouverture fichier
- self.read_dossiers_images = self.dossiers_images.readlines()
- self.a = 5 # Variables de positionnement des images dans le canvas
- self.b = 10
- self.list_buttons_images = [] # Liste qui contient les images illustrant les boutons de chaque album créé
- self.list_labels_images = [] # Liste qui contient les noms des albums créés
- self.empty_folder_image = "/empty_folder.png" # image représentant un album vide (Bouton "Nouvel album")
- self.image_empty_folder = Image.open(self.rep + self.empty_folder_image)
- self.image_empty_folder_size = 100, 100
- self.image_empty_folder.thumbnail(self.image_empty_folder_size) # Redimensionnement de l'image
- self.empty_folder_photo = ImageTk.PhotoImage(self.image_empty_folder, master = self.fenetre)
- self.new_folder_image = "/default_image.png" # Image illustrant un dossier créé mais qui ne contient aucune image
- self.image_new_folder = Image.open(self.rep + self.new_folder_image)
- self.new_folder_size = 128, 128
- self.image_new_folder.thumbnail(self.new_folder_size)
- self.new_folder_photo = ImageTk.PhotoImage(self.image_new_folder, master = self.fenetre)
- self.new_label = str()
- for i, element in enumerate(self.read_dossiers_images): # Parcours de la liste des albums créés
- self.list_labels_images.append(self.read_dossiers_images[i].strip()) # Ajout de chaque nom d'album
- self.folder_and_label = LabelFrame(self.can_dossiers, bg = 'white', bd = 0) # Création des cadres (Boutons + Labels)
- #Placement des cadres dans le canvas
- self.can_dossiers.create_window(self.b, self.a, anchor = 'nw', window = self.folder_and_label)
- self.b += 140 # Incrémentation de la variable des colonnes
- if self.b > 680 :
- self.a += 185 # Incrémentation de la variable des lignes
- self.b = 10
- with open(self.read_dossiers_images[i].strip(), 'r') as self.file: # Ouverture du fichier de chaque album en mode lecture.
- self.read_file = self.file.readlines()
- if len(self.read_file) > 0 : # Si l'album contient des images, la 1ère image illustre le bouton.
- self.read_file_image = self.read_file[0][0:self.read_file[0].index('~#~')]
- self.image_read_file = Image.open(self.read_file[0][0:self.read_file[0].index('~#~')])
- self.image_read_file_size = 160, 160
- self.image_read_file.thumbnail(self.image_read_file_size) # Redimensionnement de l'image
- self.read_file_photo = ImageTk.PhotoImage(self.image_read_file, master = self.fenetre)
- self.list_buttons_images.append(self.read_file_photo)
- self.folder = Button(self.folder_and_label, image = self.list_buttons_images[i],\
- bg = 'white', height = 100, width = 100, bd = 2, highlightthickness = 1,\
- command = lambda arg1 = self.read_dossiers_images[i].strip(), arg2 = self.home : self.phototheque(arg1, home = arg2))
- elif len(self.read_file) == 0 : # Si l'album ne contient pas d'images, l'image par défaut s'affiche
- self.folder = Button(self.folder_and_label, image = self.new_folder_photo, bg = 'white',\
- height = 100, width = 100, bd = 2, highlightthickness = 1,\
- command = lambda arg1 = self.read_dossiers_images[i].strip(), arg2 = self.home : self.phototheque(arg1, home = arg2))
- self.folder_label = Label(self.folder_and_label, bg = 'white', text = self.read_dossiers_images[i].strip(),\
- font = ('Times', '11', 'italic')) #Noms de l'album
- self.folder.grid(row = 0, column = 0)
- self.folder_label.grid(row = 1, column = 0)
- # Le clic droit sur le nom de l'album permet de renommer le dossier :
- self.folder_label.bind('<Button-3>', lambda event, arg1 = self.folder_and_label, arg2 = self.folder_label['text']: self.rename(arg1, arg2))
- if i == len(self.read_dossiers_images) - 1 :
- # Création du bouton "Nouvel album"
- self.folder_and_label = LabelFrame(self.can_dossiers, bg = 'white', bd = 0)
- self.can_dossiers.create_window(self.b, self.a, anchor = 'nw', window = self.folder_and_label)
- # Appel de le fonction self.warning_empty_entry si le nom de l'album n'est pas renseigné:
- self.new_folder = Button(self.folder_and_label, image = self.empty_folder_photo, bg = 'white',\
- height = 100, width = 100, bd = 2, highlightthickness = 1, command = self.warning_empty_entry)
- self.new_folder.grid(row = 0, column = 0)
- # Création du champ d'entrée pour renseigner le nom du nouvel album:
- self.new_folder_entry = Entry(self.folder_and_label, bg = 'white', width = 10, font = ('Times', '12', 'bold italic'))
- self.new_folder_entry.grid(row = 1, column = 0)
- self.new_folder_entry.insert(0, " Nouveau")
- # Liaisons du widget : effacement du contenu du champ d'entrée, création du nouvel album
- self.new_folder_entry.bind('<Button-1>', lambda event : self.new_folder_entry.delete(0, 'end'))
- self.new_folder_entry.bind('<Return>', self.add_folder)
- #---------------------------------------------------------------------------------------------------------
- def add_folder(self, event):
- "Création d'un nouvel album"
- self.new_label = self.new_folder_entry.get() # Récupération du contenu du champ d'entrée
- # Ouverture du fichier "Dossiers images" :
- with open("dossiers_images", 'r') as self.dossiers_images :
- self.read_dossiers = self.dossiers_images.readlines()
- if self.new_label + '\n' in self.read_dossiers :
- # L'utilisateur doit donner un nom qui n'est pas déjà attribué :
- self.warning = tkinter.messagebox.showwarning('Nouvel album', 'Cet album existe déjà.')
- self.new_folder_entry.delete(0, 'end') # Effacement du champ d'entrée
- else : # Ouverture du fichier "dossiers_images" en mode append et écriture du nom du nouvel album
- with open("dossiers_images", 'a') as self.dossiers_images:
- self.dossiers_images.write(self.new_folder_entry.get() + '\n')
- # Création du nouveau fichier images (vide pour l'instant)
- with open(self.new_folder_entry.get(), 'w') as self.new_file:
- # Appel de la méthode photothèque qui ouvre le nouvel album:
- self.phototheque(self.new_folder_entry.get(), home = self.home)
- #---------------------------------------------------------------------------------------------------------
- def warning_empty_entry(self):
- """Le champ d'entrée est rouge pendant une seconde pour prévenir
- l'utilisateur qu'il doit renseigner le nom de l'album qu'il souhaite créer."""
- self.new_folder_entry.config(bg = 'red', fg = 'white')
- # Méthode "after":
- self.new_folder_entry.after(1000, lambda : self.new_folder_entry.config(bg = 'white', fg = 'black'))
- #---------------------------------------------------------------------------------------------------------
- def rename(self, folder_and_label, curlabel):
- "Méthode permettant de renommer un dossier"
- self.folder_and_label = folder_and_label
- self.curlabel = curlabel # curlabel = current label (i.e le nom actuel de l'album à renommer)
- # Boucle qui parcourt les albums existants :
- for i in range(0, len(self.can_dossiers.winfo_children())):
- for i2 in self.can_dossiers.winfo_children()[i].winfo_children():
- self.index_i2 = self.can_dossiers.winfo_children()[i].winfo_children().index(i2)
- # si le nom de l'album correspond à la variable self.current label:
- if i2.winfo_class() == 'Label' and i2['text'] == self.curlabel:
- i2.destroy() # Destruction du nom et remplacement par un champ d'entrée:
- self.entry_replacing_label = Entry(self.can_dossiers.winfo_children()[i], bg = 'white', width = 10)
- self.entry_replacing_label.grid(row = 1, column = 0)
- self.index_i(i) # Appel de la méthode "index_i"
- # Méthode after : Après 4 secondes, appel de la fonction close_entry
- self.can_dossiers.after(4000, lambda : self.close_entry(self.folder_and_label, self.entry_replacing_label))
- #---------------------------------------------------------------------------------------------------------
- def close_entry(self, folder_and_label, entry_replacing_label):
- "Ferme le champ d'entrée si l'utilisateur n'a toujours pas entré de nouveau nom après 4 secondes"
- self.folder_and_label = folder_and_label
- self.entry_replacing_label = entry_replacing_label
- if self.entry_replacing_label.get() == '' :
- self.entry_replacing_label.destroy()
- self.back_folder_label = Label(self.folder_and_label, bg = 'white', text = self.curlabel,\
- font = ('Times', '12', 'italic')) #Noms de l'album
- self.back_folder_label.grid(row = 1, column = 0)
- self.back_folder_label.bind('<Button-3>', lambda event, arg1 = self.folder_and_label, arg2 = self.curlabel : self.rename(arg1, arg2))
- #---------------------------------------------------------------------------------------------------------
- def index_i(self, i):
- "Liaison du widget Entry à la méthode new_text"
- self.i = i
- self.can_dossiers.winfo_children()[self.i].winfo_children()[1].bind('<Return>', lambda event : self.new_text(self.i))
- #---------------------------------------------------------------------------------------------------------
- def new_text(self, i):
- "Renommage du dossier"
- self.i = i # Variable itérative
- # Affectation de la nouvelle valeur récupérée dans le widget Entry:
- self.newlabel = self.can_dossiers.winfo_children()[self.i].winfo_children()[1].get()
- with open('dossiers_images', 'r') as self.dossiers : # Ouverture du fichier "dossiers_images"
- self.read_dossiers = self.dossiers.readlines() #Copie du fichier dans une liste
- # Suppression de la ligne contenant le nom actuel de l'album
- # pour éviter l'apparition du message de la ligne 233
- # qui n'a pas lieu d'apparaître s'il s'agit de l'album à renommer:
- self.read_dossiers.remove(self.read_dossiers[self.i])
- if self.newlabel + '\n' in self.read_dossiers : # Si le nouveau nom est déjà dans l'album :
- self.warning = tkinter.messagebox.showwarning('Nouvel album', 'Cet album existe déjà.')
- # Le widget Entry est vidé de son contenu :
- self.can_dossiers.winfo_children()[self.i].winfo_children()[1].delete(0, 'end')
- else :
- # Destruction du widget Entry:
- self.can_dossiers.winfo_children()[self.i].winfo_children()[1].destroy()
- # Instanciation d'un widget Label avec le nouveau nom de l'album :
- self.new_folder_label = Label(self.can_dossiers.winfo_children()[self.i], bg = 'white',\
- text = self.newlabel, font = ('Times', '12', 'italic'))
- self.new_folder_label.grid(row = 1, column = 0)
- # Liaison du widget Label avec la méthode self.rename
- # au cas ou l'utilisateur souhaite renommer une deuxième fois son album:
- self.new_folder_label.bind('<Button-3>', lambda event, arg = self.newlabel : self.rename(arg))
- # Renommage de l'album dans le système d'exploitation:
- os.rename(self.curlabel, self.newlabel)
- # Renommage de l'album dans le fichier "dossiers_images":
- with open('dossiers_images', 'r') as self.dossiers:
- self.read_dossiers = self.dossiers.readlines()
- for i, element in enumerate (self.read_dossiers) :
- if self.read_dossiers[i] == self.curlabel + '\n':
- self.read_dossiers.remove(self.read_dossiers[i])
- self.read_dossiers[i:i] = [self.newlabel+ '\n']
- # Effacement du fichier contenant l'ancien nom de l'album
- # et réécriture avec le nouveau nom:
- with open('dossiers_images', 'w') as self.dossiers:
- for i, element in enumerate (self.read_dossiers) :
- self.dossiers.write(self.read_dossiers[i])
- #---------------------------------------------------------------------------------------------------------
- def phototheque(self, import_photos, pictures = None, legende = None, apercu_image = None, home = None) :
- "Ouverture de l'album après avoir cliqué sur le bouton"
- self.import_photos = import_photos
- self.pictures = pictures
- self.legende = legende
- self.apercu_image = apercu_image
- self.home = home
- self.back_to_folders = True
- # Destruction des éventuels widgets avant d'afficher les images
- if not self.home == None :
- self.home.destroy()
- if not self.legende == None and not self.apercu_image == None:
- self.legende.delete(0, 'end')
- self.apercu_image.destroy()
- if self.pictures != None:
- for self.child in self.pictures.winfo_children():
- self.child.destroy()
- else :
- self.pictures_defil = Scrollbar(self.main_frame, bg = 'green', relief='ridge', width = 18,\
- orient = 'vertical', troughcolor = 'white', activebackground = 'green')
- self.pictures_defil.grid(row=0,column=1, rowspan = 2, sticky='ns')
- self.pictures = Canvas(self.main_frame, bg='white', height = 700, width = 1100, scrollregion = (0,0,10000,10000), highlightbackground = 'green', yscrollcommand = self.pictures_defil.set)
- self.pictures.grid(row=1, column=0, padx = 30, pady = 10)
- self.pictures.config(scrollregion=self.pictures.bbox('all'))
- self.pictures_defil.config(command=self.pictures.yview)
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
- # Images illustrant les boutons de la barre de tâches :
- self.upload_image = "/upload.png" # Image de la page principale
- self.image_upload = Image.open(self.rep + self.upload_image)
- self.image_upload_size = 70, 70
- self.image_upload.thumbnail(self.image_upload_size) # Redimensionnement de l'image
- self.photo_upload = ImageTk.PhotoImage(self.image_upload, master = self.fenetre)
- self.image_corbeille = "/corbeille.png" # Image de la page principale
- self.corbeille_image = Image.open(self.rep + self.image_corbeille)
- self.corbeille_image_size = 64, 64
- self.corbeille_image.thumbnail(self.corbeille_image_size) # Redimensionnement de l'image
- self.photo_corbeille = ImageTk.PhotoImage(self.corbeille_image, master = self.fenetre)
- self.image_folder = "/folder_icon.png" # Image de la page principale
- self.folder_image = Image.open(self.rep + self.image_folder)
- self.folder_image_size = 64, 64
- self.folder_image.thumbnail(self.folder_image_size) # Redimensionnement de l'image
- self.photo_folder = ImageTk.PhotoImage(self.folder_image, master = self.fenetre)
- self.image_rotate = "/image_rotate.png"
- self.rotate_image = Image.open(self.rep + self.image_rotate)
- self.rotate_image_size = 64, 64
- self.rotate_image.thumbnail(self.rotate_image_size) # Redimensionnement de l'image
- self.photo_rotate = ImageTk.PhotoImage(self.rotate_image, master = self.fenetre)
- # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
- # Création des boutons (téléversement, corbeille, albums):
- self.icons = LabelFrame(self.main_frame, bg = 'white', bd = 0)
- self.icons.grid(row = 0, sticky = 'w', pady = 20, padx = 20)
- self.import_picture = Button(self.icons,image = self.photo_upload, bd = 1,\
- highlightthickness = 1, command = self.importer)
- self.import_picture.grid(row = 0, sticky = 'w', padx = 5)
- self.delete_folder = Button(self.icons,image = self.photo_corbeille, bd = 2,\
- highlightthickness = 1, command = self.tout_supprimer)
- self.delete_folder.grid(row = 0, column = 1, sticky = 'w', padx = 5)
- self.open_folder = Button(self.icons,image = self.photo_folder, bd = 2,\
- highlightthickness = 1, command = lambda arg = self.back_to_folders : self.folders(arg))
- self.open_folder.grid(row = 0, column = 2, sticky = 'w', padx = 5)
- self.legende = Entry(self.icons, width = 60, font = ('Times', '14', 'bold'),\
- highlightbackground = 'green', disabledbackground = 'white', state = 'disabled')
- self.legende.grid(row = 0, column = 3, sticky = 'w', padx = 5)
- self.liste_photos = []
- self.a = 25
- self.b = 10
- self.c = 0
- # Ouverture du fichier contenant les images de l'album sélectionné:
- with open(self.import_photos, 'r') as self.fichier :
- self.readfile = self.fichier.readlines()
- # Compréhensions de liste [liste des images, liste des légendes]
- self.readfile2 = [self.readfile[i][0:self.readfile[i].index('~#~')] for i, element in enumerate(self.readfile)]
- self.readfile3 = [self.readfile[i][(self.readfile[i].index('~#~') + 3):] for i, element in enumerate(self.readfile)]
- for i, element in enumerate(self.readfile2):
- if self.b > 1070 : # Variables de positionnement des images
- self.a += 350
- self.b = 10
- self.liste_photos.append(self.readfile[i])
- self.image = Image.open(self.readfile2[i].strip())
- self.image2 = Image.open(self.readfile2[i].strip())
- self.photo = Boutons_photos(self.fenetre, self.import_photos, self.main_frame,\
- self.pictures, self.image, self.image2, self.readfile3[i], self.a,\
- self. b, self.c, self.liste_photos) # Création des objets boutons-photos
- self.c+=1 # Variable d'indexation des photos
- self.photo.creation_bouton() #Appel de la méthode de création des boutons-photos
- self.b += 270
- #---------------------------------------------------------------------------------------------------------
- def importer(self):
- "Méthode permettant d'importer des photos"
- self.path = tkinter.filedialog.askopenfilename(title="Importer une image",filetypes=[('png files','.png'),('all files','.*')])
- self.apercu = Image.open(self.path)
- self.apercu_size = 128, 128
- self.apercu.thumbnail(self.apercu_size) # Redimensionnement de l'image
- self.apercu_photo = ImageTk.PhotoImage(self.apercu, master = self.fenetre)
- self.legende.config(state = 'normal')
- self.legende.insert(0, " Saisissez la légende de la photo à importer.")
- self.apercu_image = Label(self.icons, image = self.apercu_photo)
- self.apercu_image.grid(row = 0, column = 4, padx = 5)
- self.legende.bind('<Button-1>', lambda event : self.delete_legende())
- #---------------------------------------------------------------------------------------------------------
- def delete_legende(self):
- "Vide le message qui s'affiche de le champ d'entrée des légendes"
- self.legende.delete(0, 'end')
- self.legende.config(bg = 'white', fg = 'black')
- self.legende.bind('<Return>', lambda event : self.get_legende())
- #---------------------------------------------------------------------------------------------------------
- def get_legende(self):
- "Récupération de la légende entrée par l'utilisateur pour une image téléchargée"
- self.gotten_legend = self.legende.get()
- self.read_file2 = []
- with open(self.import_photos, 'r') as self.file :
- self.read_file = self.file.readlines()
- for i in self.read_file : # Récupération de toutes les légendes
- i = i[i.index('~#~') + 3:].strip()
- self.read_file2.append(i)
- if self.gotten_legend in self.read_file2: # Messages d'avertissement
- self.warning = tkinter.messagebox.showwarning('Légende', 'Il existe déjà une image "' + self.gotten_legend + '".')
- elif self.gotten_legend.isspace() == True or self.gotten_legend == '' or self.gotten_legend.startswith(" Saisissez") :
- self.warning = tkinter.messagebox.showwarning('Légende', 'Saisissez une légende pour la photo importée.')
- else:
- with open(self.import_photos, 'r') as self.file :
- self.read_file = self.file.readlines()
- self.read_file.append(self.path + '~#~' + self.gotten_legend + '\n')
- with open(self.import_photos, 'w') as self.file :
- for i in self.read_file :
- self.file.write(i) # Réécriture du fichier contenant les images de l'album
- 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
- #---------------------------------------------------------------------------------------------------------
- def tout_supprimer(self):
- "Supprime l'album sélectionné"
- self.oui_non = tkinter.messagebox.askyesnocancel("supprimer l'album?", 'Souhaitez-vous vraiment supprimer cet album?\nCette opération est irréversible.')
- if self.oui_non == False or self.oui_non == None :
- pass
- elif self.oui_non == True :
- with open('dossiers_images', 'r') as self.folder :
- self.read_folder = self.folder.readlines()
- for i, element in enumerate(self.read_folder):
- if self.import_photos == self.read_folder[i].strip():
- self.read_folder.remove(self.read_folder[i])
- with open('dossiers_images', 'w') as self.folder :
- for i, element in enumerate(self.read_folder):
- self.folder.write(self.read_folder[i])
- os.remove(self.rep + '/' + self.import_photos)
- self.back_to_folders = True
- self.folders(self.back_to_folders)
- #=========================================================================================================
- class Boutons_photos(Phototheque) :
- "Classe instanciant les 'boutons-photos' et les photos en taille originale"
- #---------------------------------------------------------------------------------------------------------
- def __init__(self, fenetre, import_photos, main_frame, pictures, image, image2, photo_label,a, b, c, liste_photos) :
- "Méthode constructeur"
- Phototheque.__init__(self, fenetre)
- self.import_photos = import_photos
- self.main_frame = main_frame
- self.pictures = pictures
- self.image = image
- self.image2 = image2
- self.photo_label = photo_label
- self.a = a
- self.b = b
- self.c = c
- self.c2 = None
- self.liste_photos = liste_photos
- self.dico = {}
- #---------------------------------------------------------------------------------------------------------
- def creation_bouton(self) :
- "Méthode de création des 'boutons-photos'"
- self.rep = os.getcwd() # Retourne le répertoire courant
- self.adresse_can2 = []
- self.size = 256, 256
- self.image.thumbnail(self.size)
- self.photo = ImageTk.PhotoImage(self.image)
- self.cross_image = "/croix.png" # Image de la croix (pour supprimer les images)
- self.image_cross = Image.open(self.rep + self.cross_image)
- self.image_cross_size = 16, 16
- self.image_cross.thumbnail(self.image_cross_size) # Redimensionnement de l'image
- self.cross_photo = ImageTk.PhotoImage(self.image_cross, master = self.fenetre)
- self.can2 = Canvas(self.pictures, bg='white', highlightthickness=0, bd = 0)
- self.pictures.create_window(self.b, self.a, anchor = 'nw', window = self.can2)
- # Création d'une liste de deux éléments avec self.c (pour l'indexation)
- # et self.can2(pour la photo et le bouton de suppression)
- self.adresse_can2.append(self.c)
- self.adresse_can2.append(self.can2)
- self.mini_photo = Button(self.can2, bg='white', bd=0, image=self.photo,\
- activebackground='green', cursor='hand2', command = self.agrandir_pivoter)
- self.mini_photo.grid(row=0, column = 0, sticky ='n')
- self.cross = Button(self.can2, image = self.cross_photo, highlightthickness = 0,\
- bd = 0 , cursor='hand2', command = self.supprimer)
- self.cross.grid(row=0, column = 0, sticky = 'ne')
- self.label_photo = Label(self.can2, bg = 'white', text = self.photo_label,\
- font = ('Times', '12', 'bold'), wraplength = 200, pady = 5)
- self.label_photo.grid(row = 1, sticky='n')
- # Liaison du label à la méthode rename:
- self.label_photo.bind('<Button-3>', lambda event : self.rename_picture(self.label_photo['text'], self.can2))
- #---------------------------------------------------------------------------------------------------------
- def rename_picture(self, curlabel, can2):
- "Renommage des images"
- self.curlabel = curlabel
- self.can2 = can2
- for i in range(0, len(self.pictures.winfo_children())):
- for i2 in self.pictures.winfo_children()[i].winfo_children():
- self.index_i2 = self.pictures.winfo_children()[i].winfo_children().index(i2)
- if i2.winfo_class() == 'Label' and i2['text'] == self.curlabel:
- i2.destroy()
- i2 = Entry(self.can2, bg = 'white', width = 10)
- i2.grid(row = 1, column = 0)
- self.pic_index_i(i)
- #---------------------------------------------------------------------------------------------------------
- def pic_index_i(self, i):
- "Liaison du widget Entry à la méthode pic_new_text"
- self.i = i
- self.pictures.winfo_children()[self.i].winfo_children()[2].bind('<Return>', lambda event : self.pic_new_text(self.i))
- #---------------------------------------------------------------------------------------------------------
- def pic_new_text(self, i):
- "Renommage des images" # Les trois méthodes (rename_picture, pic_index_i et pic_new_text) sont liées.
- self.i = i
- self.pic_newlabel = self.pictures.winfo_children()[self.i].winfo_children()[2].get()
- self.pictures.winfo_children()[self.i].winfo_children()[2].destroy()
- self.in_file = False
- self.new_picture_label = Label(self.pictures.winfo_children()[self.i], bg = 'white', font = ('Times', '12', 'bold'))
- self.new_picture_label.grid(row = 1, column = 0)
- self.new_picture_label.bind('<Button-3>', lambda event, arg1 = self.curlabel, arg2 = self.can2 : self.rename_picture(arg1, arg2))
- with open(self.import_photos, 'r') as self.file :
- self.read_file = self.file.readlines()
- self.read_file2 = []
- for i in self.read_file :
- i = i[i.index('~#~') + 3:].strip()
- self.read_file2.append(i)
- if self.pic_newlabel in self.read_file2:
- self.in_file = True
- self.warning = tkinter.messagebox.showwarning('Légende', 'Il existe déjà une image intitulée "' + self.pic_newlabel + '".')
- self.pic_newlabel = self.curlabel
- self.new_picture_label.config(text = self.curlabel)
- if self.in_file == False :
- with open(self.import_photos, 'r') as self.file:
- self.read_file = self.file.readlines()
- for i, element in enumerate (self.read_file) :
- if self.read_file[i][self.read_file[i].index("~#~")+3:] == self.curlabel:
- self.read_file[i] = self.read_file[i].replace(self.curlabel, self.pic_newlabel + '\n') # Remplacement de l'ancienne légende par la nouvelle
- with open(self.import_photos, 'w') as self.file:
- for i in self.read_file :
- self.file.write(i)
- self.new_picture_label.config(text = self.pic_newlabel)
- self.phototheque(self.import_photos)
- #---------------------------------------------------------------------------------------------------------
- def agrandir_pivoter(self):
- "Agrandir ou pivoter la photo?"
- self.image_resize = "/resize.png"
- self.image4 = Image.open(self.rep + self.image_resize)
- self.image4_size = 96, 96
- self.image4.thumbnail(self.image4_size) # Redimensionnement de l'image
- self.photo_resize = ImageTk.PhotoImage(self.image4, master = self.fenetre)
- self.image_rotate = "/image_rotate.png"
- self.image5 = Image.open(self.rep + self.image_rotate)
- self.image5_size = 96, 96
- self.image5.thumbnail(self.image5_size) # Redimensionnement de l'image
- self.photo_rotate = ImageTk.PhotoImage(self.image5, master = self.fenetre)
- self.choix = Toplevel(name = 'selected', bg = 'white')
- self.label_agrandir_pivoter = Label(self.choix, bg = 'white', fg = 'black', text = "Voulez-vous agrandir\nou pivoter la photo?", font = ('Times', '14', 'bold'))
- self.label_agrandir_pivoter.grid(row = 0, column = 0, columnspan = 2, padx = 10, pady = 5)
- self.agrandissement = Button(self.choix, image = self.photo_resize, bg = 'black', bd = 2, highlightthickness = 1, command = self.photo_agrandie)
- self.agrandissement.grid(row = 1, column = 0, sticky = 'w', padx = 10, pady = 10)
- self.rotate_image = Button(self.choix, image = self.photo_rotate, bg = 'black', bd = 2, highlightthickness = 1, command = self.rotate)
- self.rotate_image.grid(row = 1, column = 1, sticky = 'w', padx = 10, pady = 10)
- #---------------------------------------------------------------------------------------------------------
- def photo_agrandie(self) :
- "Méthode permettant d'agrandir les photos"
- self.grande_photo = Toplevel(name = 'selected')
- self.photo2 = ImageTk.PhotoImage(self.image2)
- if self.image2.size[0] > 768 and self.image2.size[1] > 768:
- self.image2_size = 1024, 1024
- self.image2.thumbnail(self.image2_size)
- self.photo2 = ImageTk.PhotoImage(self.image2)
- self.label_photo = Label(self.grande_photo, image = self.photo2)
- self.label_photo.grid()
- #---------------------------------------------------------------------------------------------------------
- def rotate(self):
- "Pivote l'image"
- self.im2_rotate = self.image2.rotate(270, expand = True)
- with open(self.import_photos, 'r') as self.file :
- self.readfile = self.file.readlines()
- self.filename = self.readfile[self.c][13:self.readfile[self.c].index('~#~')]
- self.im2_rotate.save(self.filename)
- self.phototheque(self.import_photos, self.pictures)
- self.choix.destroy()
- #---------------------------------------------------------------------------------------------------------
- def supprimer(self) :
- "Méthode permettant de supprimer des photos"
- self.oui_non = tkinter.messagebox.askyesnocancel('supprimer la photo?', 'Souhaitez-vous vraiment supprimer cette photo?')
- if self.oui_non == False or self.oui_non == None :
- pass
- elif self.oui_non == True :
- self.d = 0 # Variable d'indexation
- self.list_can2 = []
- self.picture_path = []
- for can2 in self.pictures.winfo_children() :
- if can2 != self.mini_photo and can2 != self.cross :
- self.list_can2.append(self.d)
- self.d += 1
- for i in range(0, len(self.liste_photos)) :
- self.sous_liste = []
- 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.
- self.sous_liste.append(self.liste_photos[i])
- self.picture_path.append(self.sous_liste)
- j = 0
- while j < len(self.picture_path):
- if self.adresse_can2[0] == self.picture_path[j][0] : # On compare l'indice de la photo à supprimer avec les indices de la liste
- self.picture_path.remove(self.picture_path[j]) # Si il y a concordance, on supprime l'indice et le chemin de la liste
- j+=1
- self.can2.destroy() # Destruction de la photo
- with open(self.import_photos, 'w') as self.fichier :
- for k in range(0, len(self.picture_path)):
- self.fichier.write(self.picture_path[k][1]) #Réécriture du fichier sans le chemin précédemment supprimé.
- self.phototheque(self.import_photos, self.pictures)
- # ============MAIN PROGRAMM ================================================== :
- if __name__ == "__main__":
- fenetre = Tk()
- fenetre.title('Photothèque')
- phototheque = Phototheque(fenetre)
- phototheque.home()
- fenetre.mainloop() # Démarrage du réceptionnaire d'événements
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement