######################################### ### Définition du programme principal ### ######################################### ################################################################## ### Importation des modules utiles import tkinter import sys import menu import classes import apropos import limites ################################################################## ### Définition des fonctions d'affectation des molécules à partir des menus déroulants def norma_name(nom_mol): '''Renvoie le nom de la molécule sans accents et autres trucs gênants.''' return(nom_mol.replace("é", "e").replace("è", "e").replace("ê", "e")) ### Définition de la fonction d'ouverture des fichiers correspondants aux ### molécules sélectionnées def ouverture(mol1, mol2): sys.path.append("fichiers_molecules") return(__import__(norma_name(mol1)), __import__(norma_name(mol2))) ### Définition de la fonction servant à sélectionner les orbitales ### qui interagiront (les plus proches en énergie) def comparaison_et_selection_des_OF(fichier1, fichier2): '''Renvoie la liste des deux OF qui vont interagir à partir des fichiers des molécules''' energieHO1 = fichier1.molecule.HO.energie energieBV1 = fichier1.molecule.BV.energie energieHO2 = fichier2.molecule.HO.energie energieBV2 = fichier2.molecule.BV.energie if abs(energieHO1 - energieBV2) < abs(energieBV1 - energieHO2): return([fichier1.molecule.HO, fichier2.molecule.BV]) else: return([fichier1.molecule.BV, fichier2.molecule.HO]) ### Définition de la fonction servant à déterminer quelle sera l'interaction principale def interaction_principale(liste_des_deux_OF): '''Renvoie une liste de structure [[OF1, atome_de_plus gros coefficient de l'OF1], [...]]''' orb_mol1 = liste_des_deux_OF[0] orb_mol2 = liste_des_deux_OF[1] couples1 = orb_mol1.tableau_de_coeffs.couple_atome_coeff couples2 = orb_mol2.tableau_de_coeffs.couple_atome_coeff coeff_max_1 = 0 for i in range(1, len(couples1)): if abs(couples1[i][1]) >= coeff_max_1: coeff_max_1 = abs(couples1[i][1]) atome1 = couples1[i][0] coeff_max_2 = 0 for i in range(1, len(couples2)): if abs(couples2[i][1]) >= coeff_max_2: coeff_max_2 = abs(couples2[i][1]) atome2 = couples2[i][0] return([[orb_mol1, atome1], [orb_mol2, atome2]]) ### Définition de la fonction servant à déterminer quelle sera l'interaction secondaire et ### si elle sera favorable def interaction_secondaire(liste_des_deux_OF): '''Renvoie une liste de structure \n [favorable ou non (format str),\n [OF1, atome de l'interaction secondaire de l'OF1],\n [OF2, atome de l'interaction secondaire de l'OF2]]''' orb_mol1 = liste_des_deux_OF[0] orb_mol2 = liste_des_deux_OF[1] couples1 = orb_mol1.tableau_de_coeffs.couple_atome_coeff couples2 = orb_mol2.tableau_de_coeffs.couple_atome_coeff coeff_max_1 = 0 for i in range(1, len(couples1)): if abs(couples1[i][1]) >= abs(coeff_max_1): coeff_max_1 = couples1[i][1] atome_max1 = couples1[i][0] coeff_max_2 = 0 for i in range(1, len(couples2)): if abs(couples2[i][1]) >= abs(coeff_max_2): coeff_max_2 = couples2[i][1] atome_max2 = couples2[i][0] couples1.remove([atome_max1, coeff_max_1]) couples2.remove([atome_max2, coeff_max_2]) coeff_sec_1 = 0 for i in range(1, len(couples1)): if abs(couples1[i][1]) >= abs(coeff_sec_1): coeff_sec_1 = couples1[i][1] atome_sec1 = couples1[i][0] coeff_sec_2 = 0 for i in range(1, len(couples2)): if abs(couples2[i][1]) >= abs(coeff_sec_2): coeff_sec_2 = couples2[i][1] atome_sec2 = couples2[i][0] if (coeff_max_1 * coeff_max_2 > 0 and coeff_sec_1 * coeff_sec_2 > 0) or \ (coeff_max_1 * coeff_max_2 < 0 and coeff_sec_1 * coeff_sec_2 < 0): fav_ou_pas = 'favorable' else: fav_ou_pas = 'défavorable' return([fav_ou_pas, [orb_mol1, atome_sec1], [orb_mol2, atome_sec2]]) ### Définition de la fonction principale, exécutée lors de l'appui du bouton "Combiner" def fonction_principale(): '''Ouvre la fenêtre de résultat de la tentative d'interaction entre les deux molécules sélectionnées''' molecule1 = norma_name(menu_choix_molecule1.get(tkinter.ACTIVE)) molecule2 = norma_name(menu_choix_molecule2.get(tkinter.ACTIVE)) fichiers = ouverture(molecule1, molecule2) fichier_molecule1 = fichiers[0] fichier_molecule2 = fichiers[1] principale = interaction_principale(comparaison_et_selection_des_OF(fichier_molecule1, fichier_molecule2)) secondaire = interaction_secondaire(comparaison_et_selection_des_OF(fichier_molecule1, fichier_molecule2)) fenetre_result = tkinter.Toplevel() fenetre_result.title("Résultat de l'interaction") fenetre_result.focus_force() # Ligne 1 : on affiche les noms des molécules tkinter.Label(fenetre_result, text = fichier_molecule1.molecule.nom, font=("Arial",25)).grid(row = 0, column = 0) tkinter.Label(fenetre_result, text = fichier_molecule2.molecule.nom, font=("Arial",25)).grid(row = 0, column = 2) # Ligne 2 : on affiche par quelle orbitale (HO ou BV) elles pourraient réagir tkinter.Label(fenetre_result, text = "(Réaction par sa " + principale[0][0].nature + ")").grid(row = 1, column = 0) tkinter.Label(fenetre_result, text = "(Réaction par sa " + principale[1][0].nature + ")").grid(row = 1, column = 2) # Ligne 3 : on affiche les images des molécules pre_image1 = tkinter.PhotoImage(file = "images/" + molecule1 + ".gif") largeur1 = pre_image1.width() ; hauteur1 = pre_image1.height() fond1 = tkinter.Canvas(fenetre_result, width = 300, height = 300, bg = 'white') fond1.grid(row = 2, column = 0) image1 = fond1.create_image(150, 150, image = pre_image1) pre_image2 = tkinter.PhotoImage(file = "images/" + molecule2 + ".gif") largeur2 = pre_image2.width() ; hauteur2 = pre_image2.height() fond2 = tkinter.Canvas(fenetre_result, width = 300, height = 300, bg = 'white') fond2.grid(row = 2, column = 2) image2 = fond2.create_image(150, 150, image = pre_image2) # Lignes 4 et 5 : On indique quels atomes de chaque molécule interagissent prim1 = 'Interaction principale : atome ' + principale[0][1].nature_lettres() + ' n°' + str(principale[0][1].numero) tkinter.Label(fenetre_result, text = prim1).grid(row = 4, column = 0) prim2 = 'Interaction principale : atome ' + principale[1][1].nature_lettres() + ' n°' + str(principale[1][1].numero) tkinter.Label(fenetre_result, text = prim2).grid(row = 4, column = 2) sec1 = 'Interaction secondaire (' + secondaire[0] + ') : atome ' + secondaire[1][1].nature_lettres() + \ ' n°' + str(secondaire[1][1].numero) tkinter.Label(fenetre_result, text = sec1).grid(row = 5, column = 0) sec2 = 'Interaction secondaire (' + secondaire[0] + ') : atome ' + secondaire[2][1].nature_lettres() + \ ' n°' + str(secondaire[2][1].numero) tkinter.Label(fenetre_result, text = sec2).grid(row = 5, column = 2) # Ligne 6 : on qualifie l'intensité de l'interaction envisagée ecart_E = abs(principale[0][0].energie - principale[1][0].energie) texte_interaction = "L'écart énergétique est de " + str(ecart_E) + " eV." txt = tkinter.Label(fenetre_result, text = texte_interaction) txt.grid(row = 6, column = 0, columnspan = 3) #Ligne 7 : Bouton retour pour quitter la fenêtre tkinter.Button(fenetre_result, text = "Retour", command = fenetre_result.destroy).grid(row = 7, column = 0, columnspan = 3) fenetre_result.resizable(width = False, height = False) #Séparateur entre les deux colonnes espace = tkinter.Frame(fenetre_result, width = 20) espace.grid(row = 0, column = 1) fenetre_result.mainloop() # Sans cette mainloop l'image n'est pas affichée... ################################################################## ### Création de la structure de l'interface ## Création de la fenêtre "conteneur" fenetre = tkinter.Tk() fenetre.title("Simulateur de réactions") fenetre.geometry("725x305+100+50") fenetre.resizable(width = False, height = False) ## Ligne 1 : bouton quitter en haut à droite bouton_quitter = tkinter.Button(fenetre, text="Quitter", command=fenetre.destroy) bouton_quitter.config(cursor = 'hand2') bouton_quitter.grid(row = 1, column = 5, sticky = (tkinter.N, tkinter.E)) ## Ligne 3 : Les deux menus déroulants de choix des molécules # Les fonctions servant à afficher les noms en dessous def sel_mol1(rien): try: fenetre.grid_slaves(row = 4, column = 2)[0].destroy() tkinter.Label(fenetre, text = menu_choix_molecule1.get(menu_choix_molecule1.curselection()[0]), font = ("Arial",18)).grid(row = 4, column = 2) except IndexError: tkinter.Label(fenetre, text = menu_choix_molecule1.get(menu_choix_molecule1.curselection()[0]), font = ("Arial",18)).grid(row = 4, column = 2) def sel_mol2(rien): try: fenetre.grid_slaves(row = 4, column = 4)[0].destroy() tkinter.Label(fenetre, text = menu_choix_molecule2.get(menu_choix_molecule2.curselection()[0]), font = ("Arial",18)).grid(row = 4, column = 4) except IndexError: tkinter.Label(fenetre, text = menu_choix_molecule2.get(menu_choix_molecule2.curselection()[0]), font = ("Arial",18)).grid(row = 4, column = 4) # Les listes déroulantes en elles-mêmes cadre_liste1 = tkinter.Frame(fenetre) cadre_liste1.grid(row = 3, column = 2, padx = 20, pady = 10) scrollbar1 = tkinter.Scrollbar(cadre_liste1) menu_choix_molecule1 = tkinter.Listbox(cadre_liste1) menu_choix_molecule1.insert(1, *menu.menu) scrollbar1.config(command = menu_choix_molecule1.yview) menu_choix_molecule1.config(yscrollcommand = scrollbar1.set, width = 40, cursor = "hand2", activestyle = "dotbox") scrollbar1.grid(row = 3, column = 3, sticky = (tkinter.N, tkinter.S)) menu_choix_molecule1.grid(row = 3, column = 2) menu_choix_molecule1.bind('<>', sel_mol1) cadre_liste2 = tkinter.Frame(fenetre) cadre_liste2.grid(row = 3, column = 4, padx = 20, pady = 10) scrollbar2 = tkinter.Scrollbar(cadre_liste2) menu_choix_molecule2 = tkinter.Listbox(cadre_liste2) menu_choix_molecule2.insert(1, *menu.menu) scrollbar2.config(command = menu_choix_molecule2.yview) menu_choix_molecule2.config(yscrollcommand = scrollbar2.set, width = 40, cursor = "hand2", activestyle = "dotbox") scrollbar2.grid(row = 3, column = 6, sticky = (tkinter.N, tkinter.S)) menu_choix_molecule2.grid(row = 3, column = 5) menu_choix_molecule2.bind('<>', sel_mol2) ## Ligne 4 : les noms des molécules (affichage géré par les fonctions de la ligne 3) et un gros "+" au milieu tkinter.Label(fenetre, text='+', font = ("Arial",25)).grid(row = 4, column = 3) ## Ligne 5 : Le bouton combiner qui va lancer la fonction centrale du programme bouton_combiner = tkinter.Button(fenetre, text = "Combiner", \ command = fonction_principale) bouton_combiner.config(cursor = "hand2") bouton_combiner.grid(row = 5, column = 3) ## Ligne 6 : Liens pour ouvrir des fenêtres explicatives des limites du programme et de la conception lien_limites = tkinter.Label(fenetre, text = "Limites du programme", font = ("Arial", 10, 'underline')) lien_limites.config(fg = 'blue', cursor = 'hand2') lien_limites.grid(row = 6, column = 2, sticky = (tkinter.W)) lien_limites.bind('', limites.principale) lien_apropos = tkinter.Label(fenetre, text = "À propos", font = ("Arial", 10, 'underline')) lien_apropos.config(fg = 'blue', cursor = 'hand2') lien_apropos.grid(row = 6, column = 5) lien_apropos.bind('', apropos.principale) # Très important, la fonction mainloop() permet d'éviter la fermeture de la # fenêtre avant que ne soient exécutées des actions fenetre.mainloop()