Filedialog tkinter modifier mot.

Résolu
Bonjour,

j'ai crée un programme de texte sauvegarder, ouvrir, fermer etc...

mais je veut crée une commande qui permet de lire le texte et remplacer par exemple maman par papa (un txt) avec filedialog mais cela me crée des erreurs.

voici une partie de mon programme si vous souhaiter des informations complémentaire dite le moi.

def cherche():
   cherche_file = filedialog.askopenfilename(initialdir="/Users/", title="Ouvrir txt", filetypes=(("Text Files,", "*.txt"),))
   cherche_file = open(cherche_file, 'r')
   ia = cherche_file.read()
   my_text.insert(END, ia)


def sauvegarder():
    cherche_file = filedialog.askopenfilename(initialdir="/Users/", title="Ouvrir txt",filetypes=(("Text Files,", "*.txt"),))
    cherche_file = open(cherche_file, 'w')
    cherche_file.write(my_text. get(1.0, END))

def ZRC():
    Directory = filedialog.askopenfilename(initialdir=r"C:\Desktop", title="Ouvrir",
                                filetypes=(("Text Files", "*.txt"),
                                           ("Python Files", "*.py"),
                                           ("all files", "*.*")))
    name = PureWindowsPath(Directory).name
    file = open(name, "r")
    print(name)
    lignes = file.readlines()
    lignes[2] = "test \n"
    name = name.replace("maman", "papa")
    file = open(name, "w")
    file.writelines(lignes)
    file.close()


Configuration: Windows / Firefox 82.0

23 réponses

Résumé de la discussion

Plusieurs échanges portent sur l'implémentation d'une commande Python Tkinter qui lit un fichier texte via filedialog et remplace un mot (par exemple 'maman' par 'papa'). Des extraits de code montrent l'usage de filedialog pour ouvrir et sauvegarder, des chemins et des messages d'erreur comme FileNotFoundError lorsque le nom de fichier n'est pas trouvé. Des propositions évoquent des corrections d indentation, la gestion d'un fichier temporaire et la vérification du chemin affiché par la boîte de dialogue pour éviter les erreurs d'ouverture. Enfin, un point utile est de tester le chemin retourné et d'employer des contextes 'with' pour ouvrir les fichiers, afin de garantir la fermeture même en cas d'exception.

Bobot (l’IA à votre service)
  1. Il faut absolument que tu fasse comme je te l'indique, ca marche à coup sur, je l'ai testé

    abandonne tes ligness[2] = " .\n"
    et tes doubles lectures

    moi, j'ai fait une fonction remplacer(), puis une fonction supprimer(), je les appelle l'une apres l'autre

    et ca marche bien
    1. Bonjour,

      "nan la ligne ne contient pas [2]" : c'est pas nan, c'est non...
      ben alors si elle ne contient pas [2], pourquoi testes-tu son contenu :
      if ([2] in lignes):


      for lignes in fi:

      ici, la variable s'appelle lignes

      ligness = fi.readlines()

      ici, la variable s'appelle ligness (avec 2 s) ?

      de plus tu n'as pas vraiment compris la mécanique:
      avec la boucle for, on lit ligne par ligne
      avec readlines, on lit tout le contenu du fichier
      et en plus, tu mets ça dans la boucle for qui est déjà en train de lire : quel cirque !

      Et ça, ca fait quoi : ??????
      ligness[2] = " .\n"


      Moi, pour faire simple, je laisserais la fonction ZRC comme elle est (remplacement de texte)
      ensuite, j'appellerais une autre fonction pour supprimer les lignes

      Admettons que l'on veuille supprimer les lignes 2 et 3
      même mécanique que ZRC:
      on ouvre les fichiers tempo et mon_fichier
      on lit avec une boucle for
      dans la boucle on met un compteur pour compter les lignes
      et si le compteur=2 ou compteur = 3, on ne l'écrit pas dans tempo
      1. Bonjour, de base :

        ligness[2] = " .\n"


        devait supprimer ma ligne numéro 3 mais malheureusement elle supprime tout sauf TI sans aucune explication mais sans cette commande tout fonctionne.

        enfaite des fois j'ai l'impression aussi vous ne comprenez pas se que je recherche
        avec ZRC je veut remplacer des mot et supprimer une ligne qui met sert pas.

        exemple :

        ENTETE
        Livraison = domicile
        fjsdgfnig@gmail.com
        toto = 13
        argent : 13euro

        la entete devient TI etc...

        mais par exemple je veut que @gmail disparait car elle apparait tout le temps a la même ligne du texte mais je peut pas faire .replace sa serait tricher il faut que je la supprime et laisser le reste. voila
      2. Bon merci de votre aide je vais conclure se post car il a été résolu en partie je vais refaire un post merci pour votre aide
    2. if ([2] in lignes)


      tu es sur que la ligne contient [2] ????

      Et je t'ai dis dans mon message précédent que supprimer une ligne, c'est tout simplement ne pas la recopier dans tempo, donc ne pas faire
      fo.write(lignes)


      j'ai fait ce cis -> j'ai fait ceci
      1. Je vois se que tu veut dire ^^ mais vraiment je ne vois pas du tout comment faire desoler ^^"
        es ce que tu peut donner un exemple ?
      2. nan la ligne ne contient pas [2] je veut juste supprimer la numéro 3 (car la ligne 1 = 0 2= 1 etc...)
      3. je viens de comprend j'ai ceci :

        cela supprime bien ma ligne numéro deux mais le problème cela me supprime aussi tout le reste

        exemple :

        ENTETE
        fraise
        papa
        mama

        sa devient :

        TI
        (le reste supprimer)

        def ZRC():
            mon_fichier = askopenfilename(initialdir ="C:/Phil/dev/python",filetypes =(("Text File", "*.txt"),("All Files","*.*")),title = "Selectionner fichier txt")
        
            fi = open(mon_fichier, 'r')
            fo = open('tempo.txt','w')
        
            for lignes in fi:
                if ('[ENTETE]' in lignes):  lignes = lignes.replace('[ENTETE]', 'TI')
                if ("TYPE = LIVRAISON" in lignes): lignes = lignes.replace("TYPE = LIVRAISON", "Reception")
                if ("NO BDL =" in lignes): lignes = lignes.replace("NO BDL =", "Z")
                if ("DAT BDL" in lignes): lignes = lignes.replace("DAT BDL" , "ZRC")
                if("DAT LIV ="in lignes): lignes = lignes.replace("DAT LIV =", " ")
                if("[LIGNES]"in lignes): lignes = lignes.replace("[LIGNES]", "LI;ARTICLE")
                if("REF FOU"in lignes): lignes = lignes.replace("REF FOU", "BRA")
                if("QTE ="in lignes): lignes = lignes.replace("QTE =", " ")
                if("PA BRUT"in lignes): lignes = lignes.replace("PA BRUT", " ")
                if("REMISE"in lignes): lignes = lignes.replace("REMISE", " ")
                if("PV TTC"in lignes): lignes = lignes.replace("PV TTC", " ")
                if("TVA"in lignes): lignes = lignes.replace("TVA", " ")
                if("LIBELLE ="in lignes): lignes = lignes.replace("LIBELLE =", "A01D;")
                if("GENCOD = "in lignes): lignes = lignes.replace("GENCOD = ", "FAUX")
                ligness = fi.readlines()
                ligness[2] = " .\n"
        
    3. je te laisse y réfléchir un peu

      rappelle toi qu'on lit une ligne dans le fichier initial, on la modifie (ou pas) et on la copie
      dans tempo

      donc, supprimer une ligne, c'est tout simplement ne pas la recopier dans tempo
      donc une fois identifiée la ligne, sauter le code
      fo.write(lignes)

      avec un if
      1. j'ai fait ce cis mais malheureusement je comprend pas pourquoi cela supprime tout ^^

            for lignes in fi:
                if ('[ENTETE]' in lignes):  lignes = lignes.replace('[ENTETE]', 'TI')
                if ("TYPE = LIVRAISON" in lignes): lignes = lignes.replace("TYPE = LIVRAISON", "Reception")
                if ("NO BDL =" in lignes): lignes = lignes.replace("NO BDL =", "Z")
                if ("DAT BDL" in lignes): lignes = lignes.replace("DAT BDL" , "ZRC")
                if("DAT LIV ="in lignes): lignes = lignes.replace("DAT LIV =", " ")
                if("[LIGNES]"in lignes): lignes = lignes.replace("[LIGNES]", "LI;ARTICLE")
                if("REF FOU"in lignes): lignes = lignes.replace("REF FOU", "BRA")
                if("QTE ="in lignes): lignes = lignes.replace("QTE =", " ")
                if("PA BRUT"in lignes): lignes = lignes.replace("PA BRUT", " ")
                if("REMISE"in lignes): lignes = lignes.replace("REMISE", " ")
                if("PV TTC"in lignes): lignes = lignes.replace("PV TTC", " ")
                if("TVA"in lignes): lignes = lignes.replace("TVA", " ")
                if("LIBELLE ="in lignes): lignes = lignes.replace("LIBELLE =", "A01D;")
                if("GENCOD = "in lignes): lignes = lignes.replace("GENCOD = ", "FAUX")
        
            for lignes in fi :
                if ([2] in lignes): lignes.replace('.\n')
    4. il manque les replace()

      et tu décales les if, donc ils dépendent tous les uns des autres !

      fais donc comme ça:
      if('[ENTETE]' in lignes):  lignes = lignes.replace('[ENTETE]', 'TI')


      et tu répètes le test au même niveau mais pour les autres chaines
      1. Parfait maintenant mon code marche il me manque plus que la dernière étape c'est de supprimer les lignes en question
        imaginons la ligne 4 5 9 ^^
    5. Réfléchis a ce que tu écris:

      if('[ENTETE]' in lignes):
                  lignes = lignes.replace('[ENTETE]', 'TI')
                  lignes = lignes.replace("TYPE = LIVRAISON", "Réception")
      


      tu ne fait les remplacements que si la ligne lue dans le fichier contient [ENTETE]
      donc forcement, ca ne marche que si il y a [ENTETE] dans la ligne !

      Je te rappelle que la boucle for sert a lire ligne par ligne
      et donc ta variable lignes contient une seule ligne à chaque tour de boucle ...
      1. oui je viens de remarquer cette erreur donc j'ai ce cis actuellement :

        je ne sais pas si c'est juste mais je pense qu'il me manque des chose

        def ZRC():
            mon_fichier = askopenfilename(initialdir ="C:/Phil/dev/python",filetypes =(("Text File", "*.txt"),("All Files","*.*")),title = "Selectionner fichier txt")
        
            fi = open(mon_fichier, 'r')
            fo = open('tempo.txt','w')
        
            for lignes in fi:
                if('[ENTETE]' in lignes):
                  if ("TYPE = LIVRAISON" in "Réception"):
                   if ("NO BDL ="in "Z"):
                    if lignes.replace("DAT BDL" in "ZRC"):
                     if("DAT LIV ="in " "):
                      if("[LIGNES]"in "LI;ARTICLE"):
                       if("REF FOU"in "BRA"):
                        if("QTE ="in " "):
                         if("PA BRUT"in " "):
                          if("REMISE"in " "):
                           if("PV TTC"in " "):
                             if("TVA"in " "):
                               if("LIBELLE ="in "A01D;"):
                                if("GENCOD = "in "FAUX"):
                                     print(lignes)
                fo.write(lignes)
        
            fi.close()
            fo.close()
        
            os.remove(mon_fichier)
            os.rename('tempo.txt', mon_fichier)
        
        ZRC()
        input('appuyer sur entrée ...')
    6. il faut commencer petit puis compliquer ensuite

      déjà, dis-moi si mon dernier code avec un fichier de test comme je l'ai fait fonctionne ...
      1. Oui il fonctionne mais ensuite j'ai rajouter la suite :

         from tkinter.filedialog import askopenfilename
        import os
        
        def ZRC():
            mon_fichier = askopenfilename(initialdir ="C:/Phil/dev/python",filetypes =(("Text File", "*.txt"),("All Files","*.*")),title = "Selectionner fichier txt")
        
            fi = open(mon_fichier, 'r')
            fo = open('tempo.txt','w')
        
            for lignes in fi:
                if('[ENTETE]' in lignes):
                    lignes = lignes.replace('[ENTETE]', 'TI')
                    lignes = lignes.replace("TYPE = LIVRAISON", "Réception")
                    lignes = lignes.replace("NO BDL =", "Z")
                    lignes = lignes.replace("DAT BDL", "ZRC")
                    lignes = lignes.replace("DAT LIV =", " ")
                    lignes = lignes.replace("[LIGNES]", "LI;ARTICLE")
                    lignes = lignes.replace("REF FOU", "BRA")
                    lignes = lignes.replace("QTE =", " ")
                    lignes = lignes.replace("PA BRUT", " ")
                    lignes = lignes.replace("REMISE", " ")
                    lignes = lignes.replace("PV TTC", " ")
                    lignes = lignes.replace("TVA", " ")
                    lignes = lignes.replace("LIBELLE =", "A01D;")
                    lignes = lignes.replace("GENCOD = ", "FAUX")
                    print(lignes)
                fo.write(lignes)
        
            fi.close()
            fo.close()
        
            os.remove(mon_fichier)
            os.rename('tempo.txt', mon_fichier)
        
        ZRC()
        input('appuyer sur entrée ...')


        mais bizarrement il fait le TI mais refuse de faire la suite il ignore les autres lignes.
    7. je te redonnes ce qui marche chez moi:

      le fichier test.txt contient ceci:

      toto
      [ENTETE]
      tagada

      le code:
      from tkinter.filedialog import askopenfilename
      import os
      
      def ZRC():
          mon_fichier = askopenfilename(initialdir ="C:/Phil/dev/python",filetypes =(("Text File", "*.txt"),("All Files","*.*")),title = "Selectionner fichier txt")
      
          fi = open(mon_fichier, 'r')
          fo = open('tempo.txt','w')
      
          for ligne in fi:
              if('[ENTETE]' in ligne):
                  print(ligne)
                  ligne = ligne.replace('[ENTETE]', 'TI')
              fo.write(ligne)
      
          fi.close()
          fo.close()
      
          os.remove(mon_fichier)
          os.rename('tempo.txt', mon_fichier)
      
      ZRC()
      input('appuyer sur entrée ...')


      le fichier test.txt après exécution:

      toto
      TI
      tagada

      essaie juste ça pour voir ...
      1. Merci beaucoup ^^ mais maintenant il faut que fasse supprimer lignes en même temps que sa

        exemple
        toto
        ENTETE
        tagada
        erreur
        erreur
        ENTETE

        sans que sa supprime tout l'interrieur ^^ si tu pouvais m'aider ^^
    8. ben oui, tu as surement écrit fi = askopenfilename

      c'est fichier = askopenfilename

      fi = open(fichier, 'r')
      fi.close()
      1. Je vois mais es ce que tu pourrais m'aider a supprimer les ligne et même faire le remplacement je continuerais ton code intéressant après ^^
    9. normal, le chemin codé en dur, c'est comme ça:

      C:\\Phil

      ou bien

      alors C:/Phil
      1. Nan je confirme que c'est comme sa mais bon je vais utilise mes file dialog
      2. Avec file dialog cela conftionne mais dans le dossier tempo seulement mon chemin est écrit dedans et une erreur apparait

         14, in <module>
            fi.close()
        AttributeError: 'str' object has no attribute 'close'
      3. En tout cas ton code ne m'aide pas ^^" mon code entre guillement fonctionne :
        car si je supprime pas les lignes les mot son remplacer...
        et si seulement je supprime les ligne elles ont supprimer.

        mais si je fait replace + supprimer les lignes tout le dossier se supprime
    10. tu n'as pas mis les balises de code...

      mon code ne marche pas ?

      chez moi, si

      tu as un message d'erreur ? et lequel ?

      fi = open("13915 (5).txt", 'r') : tu n'as pas oublié le chemin devant le nom de fichier ?

      genre 'C:\\phil\\dev\\13915(5).txt' ???
      1. Je l'est mi dans le meme dossier que mon code donc il le détecte automatiquement du temps que je le met le meme dossier et le nom(j'utilise pychram comme support)
        je n'est aucune erreur juste il ne se passe rien et si je met le chemin

        ", line 3
        fi = open("C:\Users\Paul\PycharmProjects\FREDproject\Nouveau dossier\test.txt", 'r')
        ^
        SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape
    11. Je fais comme ça:

      import os
      
      fi = open(mon_fichier, 'r')
      fo = open('tempo.txt','w')
      
      for ligne in fi:
          if('[ENTETE]' in ligne): ligne.replace('[ENTETE]', 'TI')
          fo.write(ligne)
      
      fi.close()
      fo.close()
      
      os.remove(mon_fichier)
      os.rename('tempo.txt', mon_fichier)
      1. Merci pour ta réponse rapide mais je sais pas pourquoi personnellement ton code ne marche pas mais je reste bloquer faut que en une seul def:() je dois supprimer les lignes et modifier les mot

        import os
        
        fi = open("13915 (5).txt", 'r')
        fo = open('tempo.txt','w')
        
        for ligne in fi:
            if('[ENTETE]' in ligne): ligne.replace('[ENTETE]', 'TI')
            fo.write(ligne)
        
        fi.close()
        fo.close()
        
        os.remove("13915 (5).txt")
        os.rename('tempo.txt', "13915 (5).txt")
    12. Pas de problème, mais la méthode pour ne pas vider ton fichier, c'est celle que je te décris à la fin de mon message ....
      1. A Vrai dire je ne comprend pas comment tu a fait Phil es ce que tu peut me faire un exemple s'il vous plait ?
    13. Ah, ce n'est pas clair dans ta tête ces notions de dossiers et de fichiers !!

      Un dossier, c'est un répertoire, comme 'c:\Phil\dev\'
      C'est le fichier qui se vide !

      Déjà, ca ne change pas grand chose, mais remplace donc le nom Directory par nom_fichier, car directory, en anglais, = dossier ou répertoire, c'est un fichier que l'on sélectionne

      Ensuite, voila ce que fait ton code actuellement:

      ouvrir le fichier en lecture
      lire tout le fichier d'un coup avec file.readlines
      modifier des lignes
      lire une seule ligne avec file.read()
      remplacer des trucs
      ouvrir à nouveau le fichier mais en écriture, sans l'avoir fermé
      y écrire le contenu de lignes
      fermer le fichier

      C'est un peu le bazar, non ?

      Finalement, que veux tu faire exactement ?
      Lire le fichier, remplacer des trucs et le sauvegarder comme ça avec le meme nom ?

      Je te donne une méthode plus sure:

      ouvrir temporaire.txt en écriture
      ouvrir ton fichier en lecture

      lire les lignes de ton fichier et y remplacer les textes
      écrire les lignes modifiées dans temporaire.txt

      fermer temporaire et ton fichier
      détruire ton fichier
      renommer temporaire .txt avec le nom de ton fichier

      et là, il ne reste plus que ton fichier modifié...
      1. Mon objectif est un exercice que je dois faire pour ma formation.

        Je dois supprimer la ligne 3 et 4 puis 7 à 13 puis encore ensuite je dois remplacer tout ses mot dans le Fichier exemple :
        [ENTETE] (il doit devenir TI)
        blabla
        tu dois supprimer cette ligne ( je dois supprimer)
        tu dois supprimer cette ligne (je dois supprimer)
        TYPE = LIVRAISON (doit devenir Réception)
        ETC...

        puis sauvegarder le fichier
    14. Je pense avoir encore avoir un petit problème j'ai maintenant fait ce si comme codage et je ne comprend pas pourquoi tout mon dossser devient vide je ne sais pas comment regler se problème.

      def ZRC():
          Directory = filedialog.askopenfilename(initialdir=r"C:\Desktop", title="Ouvrir",
                                      filetypes=(("Text Files", "*.txt"),
                                                 ("Python Files", "*.py"),
                                                 ("all files", "*.*")))
          file = open(Directory, "r")
          lignes = file.readlines()
          lignes[2] = " \n"
          lignes[3] = " \n"
          lignes[6] = " \n"
          lignes[7] = " \n"
          lignes[8] = " \n"
          lignes[9] = " \n"
          lignes[10] = " \n"
          lignes[11] = " \n"
          lignes[12] = " \n"
          lignes = file.read()
          lignes = lignes.replace("[ENTETE]", "TI")
          lignes = lignes.replace("TYPE = LIVRAISON", "Réception")
          lignes = lignes.replace("NO BDL =", "Z")
          lignes = lignes.replace("DAT BDL", "ZRC")
          lignes = lignes.replace("DAT LIV =", " ")
          lignes = lignes.replace("[LIGNES]", "LI;ARTICLE")
          lignes = lignes.replace("REF FOU", "BRA")
          lignes = lignes.replace("QTE =", " ")
          lignes = lignes.replace("PA BRUT", " ")
          lignes = lignes.replace("REMISE", " ")
          lignes = lignes.replace("PV TTC", " ")
          lignes = lignes.replace("TVA", " ")
          lignes = lignes.replace("LIBELLE =", "A01D;")
          lignes = lignes.replace("GENCOD = ", "FAUX")
          file = open(Directory, "w")
          file.writelines(lignes)
          file.close()
      1. dis moi si ca va mieux comme ça ...

        juste askopenfilename et tout de suite après file = open(
        1. Oui oui sa fonctionner et j'ai réussir a supprimer la ligne 3 de mon dossier ^^
        2. J'ai compris d'ou viens le problème sa viens du codage lignes=[2] etc... mais je comprend pas pourquoi sa supprime tout le contenue de mon fichier... mais je dois vraiment tout supprimer ses lignes d'un coup et ensuite que mon programme fasse des remplacement peut tu m'aider a régler se problème ?
      2. "dossier s'appelle bien comme sa "13915 (5) - Copie.txt"

        Ce n'est pas le dossier en fait, c'est le fichier qui s'appelle "13915 (5) - Copie.txt"

        Moi, quand je vais chercher un fichier à ouvrir dans un dossier, je fais comme ça:

        file_name = askopenfilename(initialdir ="/Users/",filetypes =(("Text File", "*.txt"),("All Files","*.*")),title = "Selectionner fichier txt")


        et dans file_name, j'ai bien le chemin et le nom: 'C:\Phil\dev\python\copie.txt'

        donc
        file = open(file_name, "r")
        ouvre mon fichier

        Je pense que tu n'as pas besoin de PureWindowsPath(Directory).name, c'est ça qui met le bazar....
        en fait, il te te manque pas de lignes, il y en a plutot en trop
        1. Merci beaucoup
      3. on ouvre un fichier dont le nom et le chemin sont dans la variable name:
        file = open(name, "r")


        Apparemment, name est égal à : '13915 (5) - Copie.txt' :
        FileNotFoundError: [Errno 2] No such file or directory: '13915 (5) - Copie.txt'

        (fichier non trouvé pas de fichier ou de répertoire '13915 (5) - Copie.txt')

        Ca m'étonnerais que tu aie un nom de chemin+fichier nommé comme ça comme ça sur ton pc ....
        Chez moi ca ressemble plutot à ça:
        'C:\Phil\dev\python\copie.txt'
        1. Merci pour ta réponse mais si mon dossier s'appelle bien comme sa "13915 (5) - Copie.txt" surtout que je l'es sélectionner avec filedialog.askopenfilename donc je ne peut pas me tromper ^^ mais j'ai remarquer aussi que cela ne crée pas le chemin et j'essaie de le regler mais je n'y arrive pas je crois qu'il me manque une ligne de code mais je n'arrive pas a la trouver sur internet.
      4. Merci beaucoup ^^ et voici le message d'érreur :

        Exception in Tkinter callback
        Traceback (most recent call last):
          File "C:\Users\****\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", [https://www.commentcamarche.net/download/telecharger-34098305-line line] 1885, in __call__
            return self.func(*args)
          File "C:\Users\****\PycharmProjects\FREDproject\fenetre.py", line 38, in ZRC
            file = open(name, "r")
        FileNotFoundError: [Errno 2] No such file or directory: '13915 (5) - Copie.txt'
        1. Aaaah, c'est mieux

          Par contre il manque des indentations:

          def sauvegarder():
          cherche_file = filedialog.askopenfilename(initialdir="/Users/", title="Ouvrir txt",filetypes=(("Text Files,", "*.txt"),))
          cherche_file = open(cherche_file, 'w')
          cherche_file.write(my_text. get(1.0, END))
          


          c'est plutot comme ça :

          def sauvegarder():
              cherche_file = filedialog.askopenfilename(initialdir="/Users/", title="Ouvrir txt",filetypes= 
             (("Text Files,", "*.txt"),))
              cherche_file = open(cherche_file, 'w')
              cherche_file.write(my_text. get(1.0, END))


          Et c'est quoi le message d'erreur, exactement ?
          • 1
          • 2