Advertisement
Guest User

Untitled

a guest
Jan 17th, 2017
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.67 KB | None | 0 0
  1. #définition de 2 classes : Interface_graphique() et Resultats_recherche()
  2. #raccourci entrée = rechercher, modifier
  3. #fenetres de confirmation pour suppression/modification
  4. #mode sans confirmation (case à cocher depuis la 1e fenetre)
  5. #appuyer sur echap, depuis n'importe quelle fenêtre, fait quitter tout le programme
  6. #après avoir modifié un individu, ce dernier reste en sélection dans l'affichage des résultats recherche
  7. #controle la saisie, renvoie message d'erreur si variables importantes non renseignées ou si variables remplies de manière incohérente
  8. file_name = "test.csv"
  9. #todo : l.215, l.239 (j'ai désactivé ces 2 lignes, elles buguent, j'y ai ajouté un mini descriptif)
  10. #todo : idées à la con : mettre en "avant-plan", implémenter raccourci ctrl+q & ctrl+w
  11.  
  12. ##modules
  13. from tkinter import * # GUI
  14. from tkinter import messagebox
  15. from tkinter.ttk import * # Widgets avec thèmes
  16. import csv
  17. from random import choice, randint
  18. from string import ascii_lowercase
  19. from datetime import *
  20.  
  21. ##liste_de_var
  22. #L'ensemble des variables de chaque fichier est représenté par une liste, dont chaque élément est une variable dudit fichier.
  23. #Cette variable est elle-même une liste, de la forme suivante :
  24. #["nom de la variable", "type de la variable", **paramètres supplémentaires, suivant le type de la variable**, "booleen:variable importante"]
  25. #Les différents types sont les suivants :
  26.  
  27. #"d" : date ; on précisera en paramètre supplémentaire si la date est une date de début ("dd"),
  28. #si c'est une date de fin ("df"), ou si c'est une simple date ("d")
  29. #"int" : entier
  30. #"str" : chaîne de caractères
  31. #"ld" : liste déroulante
  32.  
  33. #Par exemple, la variable "Situation de la demande" sera codée de la façon suivante :
  34. #["Situation de la demande", "ld", ["", "Active", "Annulée", "Fermée", "Pourvue"]]
  35. #Ici, le troisième élément de la liste représente donc les modalités de la variable.
  36.  
  37. #En revanche, la variable "Nom du stagiaire" sera codée de la façon suivante :
  38. #["Nom du stagiaire", "str"]
  39. #Ici, il n'y a pas de paramètre supplémentaire à ajouter, la liste ne comprend donc que 2 éléments et non 3.
  40.  
  41.  
  42. Var_stages=[["Situation de la demande","ld",["","Active","Annulée","Fermée","Pourvue"],True],
  43. ["Nombre stagiaire","int",True],
  44. ["Nom du stagiaire","str",True],
  45. ["Prénom du stagiaire","str",True],
  46. ["Rémunération","ld",["","Oui","Non"],True],
  47. ["Site","ld",["","Paris","Arcueil","Angers"],True],
  48. ["Structure","str",True],
  49. ["Unité","str",True],
  50. ["Niveau études","ld",["","Collège","Lycée","Bac +1","Bac +2","Licence","Master 1","Master 2","Master Spécialisé"],True],
  51. ["Domaine études","str",True],
  52. ["Durée","int"],
  53. ["Date de début","d","dd",True],
  54. ["Date de fin","d","df",True],
  55. ["CHR","str",False],
  56. ["Indemnités de stage (brut)","int",False],
  57. ["N°TS","str",False],
  58. ["Nom responsable hierarchique","str",False],
  59. ["Nom tuteur","str",False],
  60. ["Demande validée","str",False],
  61. ["Transmission Dossier Paie/GA","str",False],
  62. ["Convention","str",False],
  63. ["Centre de formation","str",False],
  64. ["Adresse","str",False],
  65. ["Demande de badge","str",False],
  66. ["Commentaires","str",False]]
  67. Var_CDD = []
  68. Var_alternants = []
  69. Var_interim = []
  70. from openpyxl import load_workbook, Workbook
  71. def recuperer_liste_de_var():
  72. debut_nom_fichier = ["CCD_2016.xls", "alternants_2016.xlsx", "stages_2016.xlsx"]
  73. for file_name in debut_nom_fichier:
  74. wb = load_workbook(filename = filename)
  75. #for colum
  76. return None
  77.  
  78. def test():
  79. wb = load_workbook("alternants_2016.xlsx")
  80. # ws = wb.sheet(0)
  81. # print(ws[0][0])
  82.  
  83. def init_wb():
  84. """à éxécuter sans modération"""
  85. global wb_alt, wb_cdd, wb_int
  86. try:
  87. wb_alt
  88. except NameError:
  89. wb_alt = load_workbook("alternants_2016.xlsx")
  90. wb_cdd = load_workbook("CDD_2016.xlsx")
  91. wb_int = load_workbook("Int_2016.xlsx")
  92.  
  93. def ebauche_liste_de_var(wb):
  94. """renvoie ebauche de var_fichier"""
  95. ebauche_var = []
  96. for col in range(1,wb.worksheets[0].max_column):
  97. ebauche_var.append([wb.worksheets[0].cell(row = 2, column = col).value])
  98. for var in ebauche_var:
  99. if est_inclus("date", var[0]):
  100. if est_inclus("début", var[O]):
  101. var.append("d","dd")
  102. elif est_inclus("fin", var[0]):
  103. var.append("d","df")
  104. else:
  105. var.append("d","d")
  106. else:
  107. var.append("str")
  108. return ebauche_var
  109.  
  110. def valeurs_ld(wb):
  111. if False:
  112. valeurs = []
  113. for col in range(1,wb.worksheets[0].max_column):
  114. if wb.worksheets[1].cell(row = 2, column = col).value != None:
  115. if wb.worksheets[1].cell(row = 2, column = col).value != "":
  116. return None
  117.  
  118.  
  119. ##ne pas appeler ce module csv
  120. def read_line(line_id):
  121. with open(file_name,'r') as myfile:
  122. r = csv.reader(myfile, delimiter=';', quotechar='"', lineterminator='\n')
  123. lines=[l for l in r]
  124. return lines[line_id]
  125.  
  126. def add_line(new_line):
  127. """ajoute ligne à la fin du csv"""
  128. #on lit le fichier en mode "append"
  129. with open(file_name,'a') as myfile:
  130. w = csv.writer(myfile, delimiter=';', quotechar='"', lineterminator='\n')
  131. w.writerow(new_line)
  132. return None
  133.  
  134. def mod_line(line_id, new_line):
  135. """remplace la ligne d'indice line_id par new_line"""
  136. #on lit le fichier en mémoire
  137. with open(file_name,'r') as myfile:
  138. r = csv.reader(myfile, delimiter=';', quotechar='"', lineterminator='\n')
  139. lines=[l for l in r]
  140. lines[line_id]=new_line
  141. # puis on le modifie (toujours en mémoire), avant d'en réécrire toutes les lignes.
  142. with open(file_name,'w') as myfile:
  143. w = csv.writer(myfile, delimiter=';', quotechar='"', lineterminator='\n')
  144. w.writerows(lines)
  145. return None
  146.  
  147. def del_line(line_id):
  148. """supprime la ligne d'indice line_id"""
  149. # on lit le fichier en mémoire
  150. with open(file_name,'r') as myfile:
  151. r = csv.reader(myfile, delimiter=';', quotechar='"', lineterminator='\n')
  152. lines=[l for l in r]
  153. lines.pop(line_id)
  154. # puis on le modifie (toujours en mémoire), avant d'en réécrire toutes les lignes.
  155. with open(file_name,'w') as myfile:
  156. w = csv.writer(myfile, delimiter=';', quotechar='"', lineterminator='\n')
  157. w.writerows(lines)
  158. return None
  159.  
  160. ##outils de test
  161. def randomword(length):
  162. return ''.join(choice(ascii_lowercase) for i in range(length))
  163.  
  164. def creer_exemples(n_indiv, liste_de_var, annee):
  165. """retourne n_indiv individus : séquences 'relativement correctes' (de valeurs) stockées sous forme de listes à 25 éléments"""
  166. L = []
  167. for i in range(n_indiv): #juste un bête *n_indiv
  168. indiv = []
  169. #cette boucle remplit indiv avec des valeurs suffisamment cohérentes pour faire tourner tout le programme
  170. for variable in liste_de_var: #(i+1)-eme variable[j] = Lvar_stage[i][j]
  171. if variable[1] == "str":
  172. indiv.append(randomword(8))
  173. elif variable[1] == "int":
  174. indiv.append(randint(1,180))
  175. elif variable[1] == "ld":
  176. indice_aleatoire = randint(0,len(variable[2])-1)
  177. indiv.append(variable[2][indice_aleatoire])
  178. elif variable[1] == "d":
  179. indiv.append(str(randint(1,28))+"/"+str(randint(1,12))+"/"+str(annee))
  180. if not(datetime.strptime(indiv[11], '%d/%m/%Y')<datetime.strptime(indiv[12], '%d/%m/%Y')):
  181. indiv[12], indiv[11] = indiv[11], indiv[12]
  182. L.append(indiv)
  183. L.append(["exemple" for i in range(len(liste_de_var))])
  184. return L
  185.  
  186. def nouveau_fichier_test(n_indiv, liste_de_var, annee):
  187. nom_fichier = "stages_" + str(annee) + ".csv"
  188. """crée 'test.csv' : données aléatoires d'individus"""
  189. with open(nom_fichier,'w') as file:
  190. writer = csv.writer(file, delimiter=";",lineterminator='\n')
  191. writer.writerow([liste_de_var[i][0] for i in range(len(liste_de_var))])
  192. writer.writerows(creer_exemples(n_indiv, liste_de_var, annee))
  193. return None
  194.  
  195. ##main
  196. def est_inclus(str1, str2):
  197. """True si str1 est inclus dans str2, False sinon"""
  198. diff = len(str2) - len(str1)
  199. if diff < 0:
  200. return False
  201. elif diff == 0:
  202. return (str1 == str2)
  203. elif diff > 0:
  204. return(est_inclus(str1,str2[1:]) or est_inclus(str1,str2[:-1]))
  205.  
  206. def est_dans(elem_candidat,list):
  207. """True si elem_candidat est dans list, False sinon"""
  208. reponse = False
  209. for elem in list:
  210. if elem == elem_candidat:
  211. reponse = True
  212. break
  213. return reponse
  214.  
  215. def reponse_recherche(criteres):
  216. """Renvoie les résultats de la recherche"""
  217. "Liste dont les éléments sont de la forme [[val1, ... , val25], line_id]"
  218. Lindiv_et_nligne = []
  219. with open(file_name,'r') as myfile:
  220. reader = csv.reader(myfile, delimiter=';', quotechar='"', lineterminator='\n')
  221. lines=[l for l in reader]
  222. for i in range(1,len(lines)): #on commence à 1 pour écarter la ligne des intitulés de variables
  223. for j in range(len(liste_de_var)): #j comptera presque le nombre de critères remplis
  224. if not(est_inclus(criteres[j],lines[i][j])) and (criteres[j] != ""): #(match critère ou critère inactif)
  225. j = 0
  226. break
  227. if j == len(liste_de_var) - 1:
  228. Lindiv_et_nligne.append([lines[i],i])
  229. return Lindiv_et_nligne
  230.  
  231. def pop_up_confirmer():
  232. """renvoie True si l'utilisateur clique sur 'OK', False sinon"""
  233. return messagebox.askokcancel("Demande de confirmation", "Êtes-vous sûr de vouloir continuer ?")
  234.  
  235. def est_entier(s):
  236. """Verifier qu'un string est un entier ou est vide"""
  237. if s == "":
  238. return True
  239. else:
  240. try:
  241. int(s)
  242. return True
  243. except Exception:
  244. return False
  245.  
  246. def est_date(d):
  247. """Verifier qu'un string est soit vide soit un date sous la forme jour/mois/annee"""
  248. if d == "":
  249. return True
  250. else:
  251. try:
  252. datetime.strptime(d, '%d/%m/%Y')
  253. return True
  254. except Exception:
  255. return False
  256.  
  257. def controle_type(indiv, liste_de_var):
  258. """vérifie la cohérence des valeurs de l'individu 'indiv' conformément à la liste de variables 'liste_var'"""
  259. Erreurs=[] #liste de booléens : Erreurs[i] vaut True s'il y a une erreur de saisie sur indiv[i], False sinon.
  260. dates_inversees = False #vaut True si la date de fin est antérieure à la date de début
  261. #on teste toutes les variables suivant leur type :
  262. for i in range(len(liste_de_var)):
  263. if est_dans(liste_de_var[i][1], ["str", "ld"]):
  264. Erreurs.append(False)
  265. elif liste_de_var[i][1]=="int":
  266. Erreurs.append(not(est_entier(indiv[i])))
  267. elif liste_de_var[i][1]=="d":
  268. Erreurs.append(not(est_date(indiv[i])))
  269. if liste_de_var[i][2]=="dd":
  270. date_debut=indiv[i]
  271. elif liste_de_var[i][2]=="df":
  272. date_fin=indiv[i]
  273. #on teste ensuite si la date de début est bien antérieure à la date de fin
  274. try:
  275. dates_inversees = datetime.strptime(date_debut, "%d/%m/%Y") > datetime.strptime(date_fin, "%d/%m/%Y")
  276. except ValueError:
  277. pass
  278. return (Erreurs,dates_inversees)
  279.  
  280. def controle_est_vide(indiv, liste_de_var):
  281. """vérifie que les variables importantes ne sont pas vides"""
  282. est_vide = [] #est_vide[i] = True si indiv[i] = "" (champ laissé vide)
  283. for i in range(len(liste_de_var)):
  284. if liste_de_var[i][-1]:
  285. est_vide.append(indiv[i] == "")
  286. elif not(liste_de_var[i][-1]):
  287. est_vide.append(False) #on considère que pour les variables non importantes, laisser vide leurs champs respectifs n'est pas une erreur
  288. return est_vide
  289.  
  290.  
  291. class Menu_principal(Tk):
  292. dic_var = {"":None, "CDD":Var_CDD, "Alternants":Var_alternants, "Stages":Var_stages, "Intérim":Var_interim }
  293. dic_code_fichier = {"CDD":"CCD_", "Alternants":"alternants_", "Stages":"stages_", "Intérim":"Int_"}
  294. annees = [str(i) for i in range(2016, 2051)]
  295. """Affiche le menu principal"""
  296. dev = False
  297. def __init__(self, dev = False):
  298. self.dev = dev
  299. self.root = Tk()
  300. self.root.title("Menu principal")
  301.  
  302. #Widgets
  303. self.choix_fichier = Combobox(self.root,exportselection=0, state="readonly")
  304. self.choix_fichier["values"] = list(self.dic_var.keys())
  305. self.choix_fichier.pack()
  306.  
  307. self.choix_annee = Combobox(self.root, exportselection = 0, state = "readonly")
  308. self.choix_annee["values"] = self.annees
  309. self.choix_annee.set(2017)
  310. self.choix_annee.pack()
  311.  
  312.  
  313. Button(self.root, text="Ajouter un individu", command = lambda : self.bouton_ig_ajout()).pack()
  314. Button(self.root, text="Modifier un individu", command = lambda : self.bouton_ig_rech()).pack()
  315.  
  316. if self.dev == True:
  317. self.brouillon_dev()
  318.  
  319. self.root.mainloop()
  320.  
  321. def init_var(self):
  322. """charge les variables sous la forme d'une liste"""
  323. self.liste_de_var = self.dic_var[self.choix_fichier.get()]
  324. return None
  325.  
  326. def brouillon_dev(self):
  327. #Button(self.root, text = "test : cree fichier csv avec valeurs aléatoires selon saisie", command = lambda nouveau_fichier_test(30, )
  328. return None
  329.  
  330. def code_fichier(self):
  331. """renvoie le code fichier en fonction du choix de l'utilisateur ; exemple : CDD_"""
  332. return self.dic_code_fichier[self.choix_fichier.get()]
  333.  
  334. def file_name(self):
  335. """renvoie le nom du fichier associé à la saisie"""
  336. annee = self.choix_annee.get()
  337. return (self.code_fichier() + annee + ".csv")
  338.  
  339. def bouton_ig_ajout(self):
  340. self.init_var()
  341. utilisateur_veut_nouveau_fichier = self.pop_up_fichier_inexistant()
  342. if utilisateur_veut_nouveau_fichier == None:
  343. Interface_graphique(fichier = self.file_name(), which = "a", lowertk = self)
  344. elif utilisateur_veut_nouveau_fichier:
  345. self.nouveau_fichier()
  346. Interface_graphique(fichier = self.file_name(), which = "a", lowertk = self)
  347. return None
  348.  
  349. def bouton_ig_rech(self):
  350. self.init_var()
  351. utilisateur_veut_nouveau_fichier = self.pop_up_fichier_inexistant()
  352. if utilisateur_veut_nouveau_fichier == None:
  353. Interface_graphique(fichier = self.file_name(), which = "r", lowertk = self)
  354. elif utilisateur_veut_nouveau_fichier:
  355. self.nouveau_fichier()
  356. return None
  357.  
  358. def fichier_existe(self):
  359. try:
  360. with open(self.file_name()):
  361. return True
  362. except IOError:
  363. return False
  364.  
  365. def pop_up_fichier_inexistant(self):
  366. if self.fichier_existe():
  367. return None
  368. elif not(self.fichier_existe()):
  369. return messagebox.askyesnocancel("Information", "Le fichier sélectionné n'existe pas. Voulez-vous en initialiser un nouveau ?")
  370.  
  371. def nouveau_fichier(self):
  372. """crée fichier csv vide (avec variables en 1e ligne)"""
  373. with open(self.file_name(),'w') as file:
  374. writer = csv.writer(file, delimiter=";",lineterminator='\n')
  375. writer.writerow([self.liste_de_var[i][0] for i in range(len(self.liste_de_var))])
  376. return messagebox.showinfo("Information", "Fichier créé")
  377.  
  378.  
  379. class Interface_graphique(Tk): #dans la suite : ig correspondra à interface graphique
  380. """Affiche une interface graphique"""
  381. dev = False
  382. def __init__(self, fichier = file_name, which = "r", lowertk = None, line_id_a_modif = None, index_liste = None):
  383. """Interface de recherche ou interface de modification"""
  384. if lowertk != None:
  385. self.lowertk = lowertk #permet d'appeler le Tk "master"
  386. self.dev = self.lowertk.dev
  387. self.root = Toplevel()
  388. self.liste_de_var = self.lowertk.liste_de_var
  389. elif lowertk == None: #ne devrait jamais arriver
  390. messagebox.showerror("Erreur critique", "lowertk == None")
  391.  
  392. if which == "r" : #charge ig de recherche
  393. self.ig_rech()
  394. elif which == "a" : #charge ig d'ajout
  395. self.ig_ajout()
  396. elif which == "m" : #charge ig de modification
  397. self.ig_modif(line_id_a_modif, index_liste)
  398.  
  399. for i in range(len(liste_de_var)): #on a déjà grid les labels avec self.creer_Tkobjets()
  400. self.Tkobjets[i].grid(row=i,column=1)
  401. self.root.bind('<Return>', lambda e: self.raccourci_entree())
  402. self.root.mainloop()
  403.  
  404. def creer_Tkobjets(self):
  405. """Retourne les différents objets de saisie + grid les labels associes"""
  406. L = []
  407. for i in range(len(self.liste_de_var)):
  408. Label(self.root,text=self.liste_de_var[i][0]).grid(row=i,column=0,sticky=W)
  409. if self.liste_de_var[i][1]=="ld":
  410. L.append(Combobox(self.root,exportselection=0, width = 17 ,state="readonly"))
  411. L[i]["values"] = self.liste_de_var[i][2]
  412. L[i].set(self.liste_de_var[i][2][0])
  413. else: #on aurait pu utiliser elif est_dans(self.liste_de_var[i][1], ["str","int","d"]):
  414. L.append(Entry(self.root))
  415. return L
  416.  
  417. def saisie(self): #fusion de criteres et saisie_modif
  418. """Renvoie valeurs saisies par l'utilisateur sous le format [val1, ... , val25]"""
  419. return [objet.get() for objet in self.Tkobjets]
  420.  
  421. def afficher_erreur(self,erreur):
  422. """Affiche message d'erreur si saisie incohérente ; retourne True si erreur, False sinon"""
  423. msg = ""
  424. if erreur == "type":
  425. Erreurs, dates_inversees = controle_type(self.saisie(), self.liste_de_var)
  426. if dates_inversees: #on remet dans le bon sens
  427. val11 = self.Tkobjets[11].get()
  428. val12 = self.Tkobjets[12].get()
  429. self.Tkobjets[11].delete(0, END)
  430. self.Tkobjets[12].delete(0, END)
  431. self.Tkobjets[11].insert(0, val12)
  432. self.Tkobjets[12].insert(0, val11)
  433. elif erreur =="rempli":
  434. Erreurs = controle_est_vide(self.saisie(),self.liste_de_var)
  435. n_erreurs = sum(Erreurs) #Erreurs = [True/False, ... , True/False] avec : True = 1, False = 0
  436. if n_erreurs == 0:
  437. return False
  438. elif n_erreurs == 1:
  439. msg = "La variable " + self.liste_de_var[Erreurs.index(True)][0] + " est mal renseignée."
  440. elif n_erreurs > 1:
  441. msg_var = "" #stocke les noms des variables présentant des valeurs incohérentes
  442. for i in range(len(self.liste_de_var)):
  443. if Erreurs[i]:
  444. if n_erreurs > 1:
  445. msg_var = msg_var + " " + self.liste_de_var[i][0] + ","
  446. n_erreurs -= 1 #après cette ligne, il reste encore n_erreurs variables à ajouter à msg_var
  447. elif n_erreurs == 1: # il reste une seule variable
  448. msg_var = msg_var + " et " + self.liste_de_var[i][0]
  449. msg = "Les variables" + msg_var + " sont mal renseignées."
  450. if erreur == "rempli":
  451. n_erreurs = sum(Erreurs)
  452. if n_erreurs == 1:
  453. msg = msg + " (Cette variable ne peut être laissée vide)"
  454. elif n_erreurs > 1:
  455. msg = msg + " (Ces variables ne peuvent être laissées vides)"
  456. messagebox.showerror('Erreur',msg)
  457. return True
  458.  
  459. def raccourci_entree(self):
  460. """Doit déterminer s'il faut lancer bouton_modif ou bouton_rech ou bouton_ajout lorsque l'utilisateur appuie sur la touche entree"""
  461. if self.root.title() == "Saisie de recherche":
  462. self.bouton_rech()
  463. elif self.root.title() == "Saisie de modification":
  464. self.bouton_modif()
  465. elif self.root.title() == "Saisie d'ajout":
  466. self.bouton_ajout()
  467. return None
  468.  
  469. ##interface de recherche
  470. def ig_rech(self):
  471. self.root.title("Saisie de recherche")
  472. self.root.bind('<Escape>', lambda e: self.root.destroy()) #s'execute lorsqu'on appuie sur Echap
  473. self.hardcore = IntVar() #création de "variable-retour" pour Checkbutton
  474.  
  475. #Widgets
  476. self.Tkobjets = self.creer_Tkobjets()
  477. Button(self.root, text="Rechercher",command = lambda : self.bouton_rech()).grid(row=0,column=3)
  478. Checkbutton(self.root, variable = self.hardcore, text = "Ne pas demander de confirmation").grid(row = 1, column = 3)
  479. return None
  480.  
  481. def bouton_rech(self):
  482. self.root.withdraw() #fait disparaître self.root (et tous ses widgets) ; pour le faire réapparaître, utiliser self.deiconify() ; le pb : quand utiliser self.deiconify() ??
  483. erreur_types = self.afficher_erreur(erreur = "type")
  484. if not(erreur_types):
  485. Resultats_recherche(saisie_recherche = self)
  486. return None
  487.  
  488. def elem_list(self):
  489. """Retourne iterable pour remplir la listbox de Resultats_recherche, recalcule resultats recherche"""
  490. a_afficher = reponse_recherche(self.saisie()) #est une liste dont les éléments sont de la forme [[val1, ... , val25], nligne]
  491. elem_list=[]
  492. for i in range(len(a_afficher)):
  493. elem="| "
  494. for j in range(len(self.liste_de_var)):
  495. elem=elem+a_afficher[i][0][j]+" | " # a_afficher[i][0][j] = val(j+1)
  496. elem_list.append(elem)
  497. return elem_list
  498.  
  499. ##interface d'ajout
  500. def ig_ajout(self):
  501. self.root.title("Saisie d'ajout")
  502. self.root.bind('<Escape>', lambda e: self.root.destroy())
  503. self.hardcore = IntVar() #création de "variable-retour" pour Checkbutton
  504.  
  505. #Widgets
  506. self.Tkobjets = self.creer_Tkobjets()
  507. Checkbutton(self.root, variable = self.hardcore, text = "Ne pas demander de confirmation").grid(row = 1, column = 3)
  508. Button(self.root, text="Ajouter",command = lambda : self.bouton_ajout()).grid(row=0,column=3)
  509. Button(self.root,text="pour test : valeurs aléatoires quasi-cohérentes", command = lambda : self.preremplir_formulaire_modif()).grid(row = 5, column = 3)
  510. return None
  511.  
  512. def bouton_ajout(self):
  513. """Si confirmation, rend effectif la saisie de l'utilisateur"""
  514. erreur_rempli = self.afficher_erreur(erreur = "rempli")
  515. if not(erreur_rempli):
  516. erreur_types = self.afficher_erreur(erreur = "type")
  517. if not(erreur_types):
  518. if self.hardcore.get() or pop_up_confirmer():
  519. add_line(self.saisie())
  520. return None
  521.  
  522. ##interface de modification
  523. def ig_modif(self, line_id_a_modif, index_liste):
  524. #ces valeurs sont constantes dans interface de modif
  525. self.line_id_a_modif = line_id_a_modif
  526. self.index_liste = index_liste
  527. self.root.title("Saisie de modification")
  528. self.root.bind('<Escape>', lambda e: self.lowertk.lowertk.root.destroy())
  529. #todo : self.protocol("WM_DELETE_WINDOW", self.confirmer_sortie()) #permet de lancer self.confirmer_sortie() lorsqu'une fenêtre se ferme ; le pb c'est qu'elles se ferment toutes fréquemment
  530.  
  531. #Widgets
  532. self.Tkobjets = self.creer_Tkobjets()
  533. self.preremplir_formulaire_modif() #charge les données du csv quant à l'individu ciblé
  534. Button(self.root, text="Modifier",command = lambda : self.bouton_modif()).grid(row=0,column=3)
  535. return None
  536.  
  537. def bouton_modif(self):
  538. """Si confirmation, rend effectif la saisie de l'utilisateur"""
  539. erreur_rempli = self.afficher_erreur(erreur = "rempli")
  540. if not(erreur_rempli):
  541. erreur_types = self.afficher_erreur(erreur = "type")
  542. if not(erreur_types):
  543. if self.lowertk.lowertk.hardcore.get() or pop_up_confirmer():
  544. mod_line(self.line_id_a_modif, self.saisie())
  545. self.lowertk.update_liste()
  546. self.lowertk.liste.selection_set(self.index_liste)
  547. return None
  548.  
  549. def preremplir_formulaire_modif(self):
  550. """Preremplit avec valeurs du csv"""
  551. ligne_select = read_line(self.line_id_a_modif)
  552. for i in range(len(self.liste_de_var)):
  553. if self.liste_de_var[i][1]=="ld":
  554. for item in self.liste_de_var[i][2]:
  555. if est_dans(ligne_select[i],self.liste_de_var[i][2]): #pour éviter bug (sur Listbox) si données mal renseignées dans le csv
  556. self.Tkobjets[i].set(ligne_select[i]) #on fixe à la valeur du csv
  557. else:
  558. self.Tkobjets[i].insert(0,ligne_select[i]) #idem
  559. return None
  560.  
  561. def confirmer_sortie(self):
  562. if self.saisie() != read_line(self.line_id_a_modif):
  563. messagebox.askokcancel("Confirmation", "Êtes-vous sûr de vouloir quitter sans enregistrer les modifications ?")
  564.  
  565.  
  566. class Resultats_recherche(Tk):
  567. """Affiche les resultats de la recherche dans une Listbox"""
  568. dev = False
  569. def __init__(self, saisie_recherche, dev = False):
  570. "Listbox + 2 boutons si resultats, messagebox sinon"
  571. self.lowertk = saisie_recherche
  572. self.dev = self.lowertk.dev
  573. if self.lowertk.elem_list() != []: #Listbox etc ne se lancent que si des individus correspondent à la requête
  574. self.liste_de_var = self.lowertk.liste_de_var
  575. self.root = Toplevel()
  576. self.root.title("Résultats de la recherche")
  577.  
  578. #creation de la Listbox
  579. self.liste = self.remplir_listbox()
  580. self.liste.pack()
  581.  
  582. #Widgets
  583. Button(self.root, text="Modifier",command=lambda:self.bouton_ig_modif()).pack()
  584. Button(self.root, text="Supprimer",command=lambda:self.bouton_suppr()).pack()
  585. self.root.bind('<Escape>', lambda e: self.lowertk.root.destroy())
  586. self.root.mainloop()
  587. else:
  588. messagebox.showinfo("Résultats de la recherche","Aucun individu ne répond à la requête")
  589.  
  590. def remplir_listbox(self):
  591. """Cree la Listbox"""
  592. elem_list = self.lowertk.elem_list()
  593. listbox = Listbox(self.root, height=len(elem_list), width = max(len(ligne) for ligne in elem_list), exportselection=0)
  594. for item in elem_list:
  595. listbox.insert(END,item)
  596. return listbox
  597.  
  598. def line_id(self):
  599. """Renvoie line_id dans csv de la selection"""
  600. choisi = self.liste.get(ACTIVE)
  601. n0 = self.lowertk.elem_list().index(choisi) #indice dans la listbox de la sélection
  602. line_id = reponse_recherche(self.lowertk.saisie())[n0][1] #indice dans le csv
  603. return line_id
  604.  
  605. def index_liste(self):
  606. """Renvoie index dans la liste de la selection"""
  607. return self.liste.curselection()
  608.  
  609. def bouton_ig_modif(self):
  610. """Ouvre interface graphique pour modifier individu selectionne et renvoie line_id, index_liste"""
  611. Interface_graphique(which = "m", lowertk = self, line_id_a_modif = self.line_id(), index_liste = self.index_liste())
  612. return None
  613.  
  614. def bouton_suppr(self):
  615. """Si confirmation, supprime la selection de la Listbox"""
  616. if self.lowertk.hardcore.get() or pop_up_confirmer():
  617. del_line(self.line_id())
  618. self.update_liste()
  619. return None
  620.  
  621. def update_liste(self):
  622. """Actualise la Listbox"""
  623. elem_list = self.lowertk.elem_list()
  624. self.liste.delete(0,END)
  625. for item in elem_list:
  626. self.liste.insert(END,item)
  627. return None
  628.  
  629. def fermeture_imminente(self):
  630. if messagebox.askokcancel("Quitter", "Voulez-vous quitter ?"):
  631. self.lowertk.root.destroy()
  632. return None
  633.  
  634.  
  635.  
  636. ##exécution
  637. liste_de_var = Var_stages
  638. nouveau_fichier_test(30,liste_de_var, 2017)
  639. Menu_principal(dev = True)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement