Casse-tête Python : lecture d'1 fichier txt bug mais débug avec un problème tkin
Résolu
Lecodeurhtmlcss
Messages postés
79
Statut
Membre
-
yg_be Messages postés 24281 Statut Contributeur -
yg_be Messages postés 24281 Statut Contributeur -
Bonjour, et merci beaucoup de vous pencher sur ce problème. C'est un casse-tête j'ai l'impression !
Circonstances :
- Je crée un moteur 3D avec python Tkinter depuis pas mal de temps, avec enregistrement de fichiers
- J'ai un niveau assez moyen en python (mais pas débutant)
Problème en gros : la lecture d'un fichier ne fonctionne pas du premier coup, mais fonctionne avec la suite du script, dès qu'on ferme la fenêtre
Explication du script :
1) On crée une fenetre Tkinter, et on lance une fonction ("Activation")
2) Cette fonction "Activation" essaie de voir si il y a déjà un monde ouvert sauvegardé :
..............->Si oui : juste définir le chemin ("pathmonde")
..............->Si non : On regarde si quelqu'un a créé un monde temporaire, non sauvegardé :
.........................-> Si non : on le crée (en attendant de sauvegarder...), et on met les options(contenues dans un fichier txt)
.........................-> Si oui : on demande si on continue ou on supprime ce pauvre fichier
........................................-(on ne s'intéresse pas au cas continuer pour l'instant ;)
........................................-Si on supprime, ça appelle une fonction "ecraserfichiertemporaire"
Puis elle appelle la fonction "suiteActivation"
fonction "ecraser..." :
- On supprime l'ancien fichier
- on en crée un nouveau avec les options
- on continue l'activation ("suiteactivation")
fonction "suiteactivation" :
- On retrouve le chemin des options
- on les lis et on les print.
Et là est le problème !
Dès qu'on utilise la fonction "écraser...." les options ne s'impriment pas (elles sont bien écrites dans le fichier txt).
2e problème : La suite de la fonction activation ne se fait que quand on ferme la fenetre principale... Je suppose qu'elle attend la fin du "mainloop" de la fenetre popup, alors qu'on la détruite !
Et, surprise, dès qu'on ferme la fenêtre principale... "Suiteactivation" fonctionne et imprimme les options !
A mon avis, c'est une histoire de fonction et de fenêtre à la fois...
Code : (assez long)
Quel est le poblème ? Et comment régler ça (pourquoi pas une fonction avant le mainloop de la fenetre popup ?)?
Merci beaucoup pour votre attention !!!
Cordialement,
N. B.
Circonstances :
- Je crée un moteur 3D avec python Tkinter depuis pas mal de temps, avec enregistrement de fichiers
- J'ai un niveau assez moyen en python (mais pas débutant)
Problème en gros : la lecture d'un fichier ne fonctionne pas du premier coup, mais fonctionne avec la suite du script, dès qu'on ferme la fenêtre
Explication du script :
1) On crée une fenetre Tkinter, et on lance une fonction ("Activation")
2) Cette fonction "Activation" essaie de voir si il y a déjà un monde ouvert sauvegardé :
..............->Si oui : juste définir le chemin ("pathmonde")
..............->Si non : On regarde si quelqu'un a créé un monde temporaire, non sauvegardé :
.........................-> Si non : on le crée (en attendant de sauvegarder...), et on met les options(contenues dans un fichier txt)
.........................-> Si oui : on demande si on continue ou on supprime ce pauvre fichier
........................................-(on ne s'intéresse pas au cas continuer pour l'instant ;)
........................................-Si on supprime, ça appelle une fonction "ecraserfichiertemporaire"
Puis elle appelle la fonction "suiteActivation"
fonction "ecraser..." :
- On supprime l'ancien fichier
- on en crée un nouveau avec les options
- on continue l'activation ("suiteactivation")
fonction "suiteactivation" :
- On retrouve le chemin des options
- on les lis et on les print.
Et là est le problème !
Dès qu'on utilise la fonction "écraser...." les options ne s'impriment pas (elles sont bien écrites dans le fichier txt).
2e problème : La suite de la fonction activation ne se fait que quand on ferme la fenetre principale... Je suppose qu'elle attend la fin du "mainloop" de la fenetre popup, alors qu'on la détruite !
Et, surprise, dès qu'on ferme la fenêtre principale... "Suiteactivation" fonctionne et imprimme les options !
A mon avis, c'est une histoire de fonction et de fenêtre à la fois...
Code : (assez long)
from tkinter import * from tkinter import ttk import os as o import shutil DirectoryPath=(o.path.abspath(__file__))[0:-27] # On regarde où seront les fichiers... def SuiteActivation(): #Suite lienoptions=o.path.normpath(o.path.join(pathmonde,"options.txt")) print("lien option normalisé : ",lienoptions) options=open(lienoptions,"r") pos=(options.readlines()) print("position : ",pos) #Et là ça marche une fois sur deux ! #Normalement, c'est activé le première fois quand on clique sur le bouton et la 2e fois après (fin de def activation) def ecraserfichiertemporaire(): #Si on détruit le fichier temporaire (pour plus de clarté voir ci-après) print("fichier temporaire supprimé") asupprimer=o.path.join(DirectoryPath, "fichier_temporaire") shutil.rmtree(asupprimer) #supprimer tout le fichier global textelabelfichiertemporairesupprime textelabelfichiertemporairesupprime="Le fichier " + asupprimer + " a été supprimé" fenetrefichiertrouve.destroy() # Je détruis l'ancienne fenetre o.mkdir("fichier_temporaire") #On crée à nouveau un fichier temporaire print("fichier temporaire créé") global pathmonde pathmonde=o.path.join(DirectoryPath,"fichier_temporaire") #On ajoute les options à ce fichier pathmonde=o.path.normpath(pathmonde) options=open(o.path.join(pathmonde,"options.txt"),"w+") #écrire les options options.write("pos=1,1,1\nRgd=2,356\nRhb=-0,7854") options.close suite=SuiteActivation() #passer à la suite def Activation(): fichiermondecourant=open("mondeactuel.txt","r") mondecourant=fichiermondecourant.read() print(mondecourant) if mondecourant=='': print("pas de monde courant sauvegardé") fileexist=0 try: #On essaie de créer un fichier temporaire en attendant de sauvegarder o.mkdir("fichier_temporaire") except FileExistsError: #Il y a déjà un fichier temporaire de la dernière fois ! fileexist=1 global fenetrefichiertrouve fenetrefichiertrouve = Toplevel() #On veut une fenetre popup fenetrefichiertrouve.attributes("-topmost", True) textefichiertrouve = Text(fenetrefichiertrouve, height=4, width=40) textefichiertrouve.pack() textefichiertrouve.insert(END, "Fichier non-sauvegardé trouvé.") boutonsupprimerfichiertrouve = Button(fenetrefichiertrouve, text="supprimer", command=lambda : ecraserfichiertemporaire()) boutonsupprimerfichiertrouve.pack() boutoncontinuerfichiertrouve = Button(fenetrefichiertrouve, text="le continuer") # ce n'est pas ce qui nous intéresse boutoncontinuerfichiertrouve.pack() fenetrefichiertrouve.title("Fichier non sauvergardé trouvé") fenetrefichiertrouve.mainloop() if fileexist==0: print("Aucun fichier temporaire n'a existé") #Pour la première fois qu'on utilise ou quand on supprime le fichier manuelement global pathmonde pathmonde=o.path.join(DirectoryPath,"fichier_temporaire") #Je crée un nouveau monde avec les options pathmonde=o.path.normpath(pathmonde) options=open(o.path.join(pathmonde,"options.txt"),"w+") options.write("pos=1,1,1\nRgd=2,356\nRhb=-0,7854") options.close else: print("il y a un monde courant ! son nom est : ",mondecourant) pathmonde=o.path.join(DirectoryPath,mondecourant) suite=SuiteActivation() #On passe à la suite ! ################################## # /\ C'est ici que ça se joue ! # /||\ En gros, la première fois en supprimant le fichier, SuiteActivation ne fonctionne pas # / '' \ Mais dès que on le fait ici (au dessus) la position marche ! # /______\ ################################### ################################### Juste du tkinter... fenetre = Tk() fenetre.geometry("600x600") label=Label(fenetre,text="Cette fenetre a été grandement simplifiée...") label.pack() Lancement=Activation() ################## On lance avant le mainloop... fenetre.mainloop()
Quel est le poblème ? Et comment régler ça (pourquoi pas une fonction avant le mainloop de la fenetre popup ?)?
Merci beaucoup pour votre attention !!!
Cordialement,
N. B.
A voir également:
- Casse-tête Python : lecture d'1 fichier txt bug mais débug avec un problème tkin
- Citizen code python avis - Accueil - Outils
- Tête de parabole défectueuse - Forum TV & Vidéo
- Réparation écran tv samsung cassé ✓ - Forum Téléviseurs
- Écran ordinateur cassé sans choc - Forum Ecran
- Ecran telephone cassé de l'interieur - Forum Wiko
6 réponses
bonjour,
il serait préférable que tu simplifies ton programme pour n'y garder que le minimum qui pose problème.
tu n'expliques pas comment utiliser le programme (en partant de rien) afin d'obtenir le comportement inattendu.
il serait préférable que tu simplifies ton programme pour n'y garder que le minimum qui pose problème.
tu n'expliques pas comment utiliser le programme (en partant de rien) afin d'obtenir le comportement inattendu.
Ton problème vient de l'incompréhension du déroulement de ton code, le code qui suit l'ouverture de ta toplevel ne va pas attendre que celle-ci soit fermée pour être exécuté, il le sera directement.
Il y a tellement de choses à rectifier dans ton code.
Déjà la 1ère ligne, comme dit par le voisin du dessus.
Déjà pourquoi mettre un alias à une lettre d'un module ayant un nom de 2 lettres ?
De plus DirectoryPath étant une constante, on l'écrit en majuscule.
Soit quelque chose comme
Il y a tellement de choses à rectifier dans ton code.
Déjà la 1ère ligne, comme dit par le voisin du dessus.
DirectoryPath=(o.path.abspath(__file__))[0:-27]est erroné et soumis à de futurs bugs.
Déjà pourquoi mettre un alias à une lettre d'un module ayant un nom de 2 lettres ?
De plus DirectoryPath étant une constante, on l'écrit en majuscule.
Soit quelque chose comme
DIRECTORY_PATH = os.path.abspath(os.path.dirname(__file__))qui est déjà plus limpide, ne trouves-tu pas ?
Le soucis principal, c'est ton approche: construire un truc simple et ensuite le complexifier au fur et à mesure.
Comme si tu construisais un abri de jardin pour ensuite le transformer en immeuble à appartement. Al lieu de commencer par les fondations et la structure.
Avant de commencer, tu dois déterminer où tu veux arriver, et commencer en conséquence.
Quel que soit la source de ton soucis, il faudra immanquablement réécrire ton code en le structurant différemment.
Une des preuves de cela, c'est que, au lieu d'expliquer ce que tu attends de ton code (que nous ne pouvons pas deviner), tu nous expliques la logique de ton script, alors que nous pouvons lire le programme, malgré qu'il soit mal commenté.
Comme si tu construisais un abri de jardin pour ensuite le transformer en immeuble à appartement. Al lieu de commencer par les fondations et la structure.
Avant de commencer, tu dois déterminer où tu veux arriver, et commencer en conséquence.
Quel que soit la source de ton soucis, il faudra immanquablement réécrire ton code en le structurant différemment.
Une des preuves de cela, c'est que, au lieu d'expliquer ce que tu attends de ton code (que nous ne pouvons pas deviner), tu nous expliques la logique de ton script, alors que nous pouvons lire le programme, malgré qu'il soit mal commenté.
Allez, d'autres petites choses.
Utiliser des exceptions, c'est très bien, mais il y a aussi un else et finally dans la gestion des exceptions en python, donc plutôt que faire
Fais simplement
Faire
Essaie aussi de respecter les conventions en python (et bien souvent en programmation), soit le snake_case, soit le camelCase, car écrire des noms comme
Comme tu ne fermes pas tes fichiers, utilise à bon escient le context manager with
Essaie aussi de dissocier dans des fonctions distinctes ce qui concerne l'interface garphique et les autres choses, logique, etc.
Utiliser des exceptions, c'est très bien, mais il y a aussi un else et finally dans la gestion des exceptions en python, donc plutôt que faire
fileexist=0 try: o.mkdir("fichier_temporaire") except FileExistsError: fileexist=1 if fileexist==0: # code
Fais simplement
try: o.mkdir("fichier_temporaire") except FileExistsError: # code else: # code
Faire
command=lambda : ecraserfichiertemporaire())est inutile, puisque ta fonction anonyme fait exactement la même chose que la fonction d'origine, donc autant passer la référence à la fonction
ecraserfichiertemporaire(sans parenthèses donc).
Essaie aussi de respecter les conventions en python (et bien souvent en programmation), soit le snake_case, soit le camelCase, car écrire des noms comme
textelabelfichiertemporairesupprimen'aide pas à la lecture du code, c'est vraiment très bien de donner des noms de variables, fonctions descriptives, mais là c'est un peu trop ^^
Comme tu ne fermes pas tes fichiers, utilise à bon escient le context manager with
with open('fichier_a_lire') as f: content = f.read()
Essaie aussi de dissocier dans des fonctions distinctes ce qui concerne l'interface garphique et les autres choses, logique, etc.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
A vrai dire, le problème ressort plus si on enlève les lignes 85->89
De fait là la seule fonction qui appele "Suiteactivation" est bien celle du bouton "supprimer" de la fenetre popup. On clique, mais malheureusement a position est illisible.
else: print("il y a un monde courant ! son nom est : ",mondecourant) pathmonde=o.path.join(DirectoryPath,mondecourant) suite=SuiteActivation() !
De fait là la seule fonction qui appele "Suiteactivation" est bien celle du bouton "supprimer" de la fenetre popup. On clique, mais malheureusement a position est illisible.
Vidéo explicative ici : https://drive.google.com/file/d/1WnY_2ib-23qzICMeTb1N0-GJRNiT2fO5/view?usp=sharing
C'est mieux ! Et merci de votre aide et implication !
C'est mieux ! Et merci de votre aide et implication !
Désolé pour la non-explication ! Oui il faut juste lancer le programme 2 fois. La première il n'y aura aucun monde temporaire et normalement il ne se passera rien. C'est une fois qu'il y en a un que ça marche.
ton programme est visiblement prévu pour un scenario bien précis, et se termine en erreur si on ne suit pas ce scenario.
n'hésite pas non plus à expliquer ce que le programme affiche dans ce scénario.
J'eplicite mal mon but : j'essaie de supprimer les infos pour en remettre de nouvelles, et ensuite réussir à lire ces infos depuis le fichier texte "options.txt"
Ce processus se traduit par cliquer sur "supprimer" sur la fenêtre popup - mais on voit que dans la console on n'arrive pas à récupérer les informations (juste une liste vide). En fait ce n'est que supprimer la fenêtre principale qui fait fonctionner le script après ces différentes manips.
Et j'essaie de comprendre pourquoi (et surtout de trouver un moyen de récupérer les options du fichier texte correctement sans fermer la fenetre principale.