IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Tkinter Python Discussion :

Exécuter une fonction à la fin de l'exécution d'un thread


Sujet :

Tkinter Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Technicien audiovisuel
    Inscrit en
    Juillet 2023
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Technicien audiovisuel
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2023
    Messages : 11
    Par défaut Exécuter une fonction à la fin de l'exécution d'un thread
    Bonjour, j'ai écrit un code dont voici une fonction j'aimerais attendre la fin de l'envois du fichier pour vérifier que celui-ci soit bien présent sur le bucket S3.

    j'ai essayé en utilisant .join() a la fin de mon thread mais cela fait planter mon code ...

    Merci d'avance pour vos retours

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
     
     
    def rename (filename,new_file_name,label,progress_lock,progress_bar,label_progress_lock,label_percent):
     
        if retour_fonction['chemin'] != 'chemin' and retour_fonction['Jour'] != 'Jour' and retour_fonction['Hote'] != 'Hote' and retour_fonction['Visiteur'] != 'Visiteur' and retour_fonction['Plan'] != 'Plan' and retour_fonction['Hote'] != retour_fonction['Visiteur']:
     
            chemin = os.path.dirname(filename)
            os.chdir(chemin)
            os.rename(f'{filename}', f'{new_file_name}') 
     
            def progress_callback(bytes_amount):
                with progress_lock:
                    progress_bar["value"] += bytes_amount
                label_progress_callback()
     
            def label_progress_callback():
                with label_progress_lock:
                    global send_finished
                    progress_bar_value = round(progress_bar["value"]/(1024*1000),2)
                    file_size = round(progress_bar["maximum"]/(1024*1000), 2)
                    percentage = (progress_bar_value / file_size) * 100
                    label_percent.configure(text = f"{progress_bar_value} Mo / {file_size} Mo  ({percentage:.2f}%)")
     
     
            s3 = boto3.client(
            service_name='s3',
            aws_access_key_id=f'{key_id_bucket}',
            aws_secret_access_key=f'{key_secret_bucket}',
            )
     
            new_filename = os.path.basename(new_file_name)
            file_size = os.path.getsize(new_file_name)
     
            progress_bar["value"] = 0
            progress_bar["maximum"] = file_size
     
            thread1 = threading.Thread(target=lambda: s3.upload_file(
                new_file_name, 'testbein', f'video/{new_filename}',
                Callback=progress_callback))
     
            thread1.start()
            thread1.join()
     
            def check (bucket,file_key,label):
                s3_client = boto3.client('s3',
                                          aws_access_key_id=f'{key_id_bucket}',
                                          aws_secret_access_key=f'{key_secret_bucket}')
     
                result = s3_client.list_objects_v2(Bucket= bucket, Prefix= file_key)
                if 'Contents' in result:
                    label.configure(text='Fichier présent sur le serveur')
                else:
                    label.configure(text="Erreur lors de l'envois sur le serveur : Fichier introuvable")
     
     
     
            check('testbein',f"video/{new_file_name}",label)
     
     
     
            jour = retour_fonction['Jour']
            nom_court_hote = retour_fonction['Hote']
            nom_court_visiteur = retour_fonction['Visiteur']
            plan = retour_fonction['Plan']
            new_file_name = f'lfp_{compet}_{saison}_{jour}_{nom_court_hote}_{nom_court_visiteur}_si_{plan}.mp4'
     
     
     
        else : 
     
            def open_up():
                global popup
                if popup is None or not popup.win_2.winfo_exists():
                    popup = new_window()
                else:
                    popup.win_2.lift(root)
     
            class new_window:
     
                def __init__(self):
                    self.win_2 = Toplevel()
                    self.win_2.geometry("700x100")
                    self.win_2.title('Popup')
                    self.win_2.resizable(False, False)
                    self.win_2.label_msg = Label(self.win_2 , text='Merci de choisir des valeurs dans chaque catégories et de choisir un fichier à envoyer', font=('Verdana',10))
                    self.win_2.label_msg.pack()
     
                    self.win_2.bout2 = Button(self.win_2, text='OK',width=10, command=self.win_2.destroy )
                    self.win_2.bout2.pack(pady=20)
     
            open_up()

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Salut,

    Attendre avec tkinter se programme (par exemple) via .after. Il peut aussi permettre au thread qui se termine de poster une action qui...
    note: after dans le thread principal (qui exécute tkinter) fera du polling (on peut tester l'état du thread toutes les x secondes...). after comme dernière instruction du thread poste une fonction de rappel qui sera exécutée dans le contexte du thread principal.

    .join, attend aussi mais gèle l'interface graphique.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre habitué
    Homme Profil pro
    Technicien audiovisuel
    Inscrit en
    Juillet 2023
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Technicien audiovisuel
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2023
    Messages : 11
    Par défaut
    J'ai essayé comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
       if retour_fonction['chemin'] != 'chemin' and retour_fonction['Jour'] != 'Jour' and retour_fonction['Hote'] != 'Hote' and retour_fonction['Visiteur'] != 'Visiteur' and retour_fonction['Plan'] != 'Plan' and retour_fonction['Hote'] != retour_fonction['Visiteur']:
     
            chemin = os.path.dirname(filename)
            os.chdir(chemin)
            os.rename(f'{filename}', f'{new_file_name}') 
     
            def progress_callback(bytes_amount):
                with progress_lock:
                    progress_bar["value"] += bytes_amount
                label_progress_callback()
     
            def label_progress_callback():
                with label_progress_lock:
                    progress_bar_value = round(progress_bar["value"]/(1024*1000),2)
                    file_size = round(progress_bar["maximum"]/(1024*1000), 2)
                    percentage = (progress_bar_value / file_size) * 100
                    label_percent.configure(text = f"{progress_bar_value} Mo / {file_size} Mo  ({percentage:.2f}%)")
                parent.after(check,('testbein',f"video/{new_file_name}",label)) ########################## -> Modification
     
            s3 = boto3.client(
            service_name='s3',
            aws_access_key_id=f'{key_id_bucket}',
            aws_secret_access_key=f'{key_secret_bucket}',
            )
     
            new_filename = os.path.basename(new_file_name)
            file_size = os.path.getsize(new_file_name)
     
            progress_bar["value"] = 0
            progress_bar["maximum"] = file_size
     
            thread1 = threading.Thread(target=lambda: s3.upload_file(
                new_file_name, 'testbein', f'video/{new_filename}',
                Callback=progress_callback))
     
            thread1.start()
    mais j'ai l'erreur suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      File "C:\Users\caudo\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 851, in after
        return self.tk.call('after', ms, name)
    _tkinter.TclError: bad argument "<function rename.<locals>.check at 0x000001C9D2844040>": must be cancel, idle, info, or an integer

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Citation Envoyé par elbobito Voir le message
    J'ai essayé comme ceci :
    On essaie pas un truc. On ouvre une documentation, on récupère des exemples sur Internet et on essaie de comprendre comment ça marche. Puis on écrit un petit exemple proche de ce qu'on veut faire pour s'assurer qu'on a compris.

    Si ça plante avec un message d'erreur qui dit "bad argument"... la moindre des choses est de revoir quels sont les paramètres à passer à after pour s'assurer qu'ils sont du type attendu.

    Si a ce stade on ne s'en sort toujours pas, alors on peut demander de l'aide avec un code à poster qui montre qu'on a essayé de comprendre avant de se jeter à l'eau.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre habitué
    Homme Profil pro
    Technicien audiovisuel
    Inscrit en
    Juillet 2023
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Technicien audiovisuel
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2023
    Messages : 11
    Par défaut
    Après d'autres recherches j'ai réussis à trouver une autre méthode pour régler mon problème.

    Merci de votre aide

    Ci-joint la méthode utilisée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    def rename (filename,new_file_name,label,progress_lock,progress_bar,label_progress_lock,label_percent,parent):  
     
        if retour_fonction['chemin'] != 'chemin' and retour_fonction['Jour'] != 'Jour' and retour_fonction['Hote'] != 'Hote' and retour_fonction['Visiteur'] != 'Visiteur' and retour_fonction['Plan'] != 'Plan' and retour_fonction['Hote'] != retour_fonction['Visiteur']:
     
            chemin = os.path.dirname(filename)
            os.chdir(chemin)
            os.rename(f'{filename}', f'{new_file_name}') 
     
            def progress_callback(bytes_amount):
                with progress_lock:
                    progress_bar["value"] += bytes_amount
                label_progress_callback()
     
     
            def label_progress_callback():
                with label_progress_lock:
                    progress_bar_value = round(progress_bar["value"]/(1024*1000),2)
                    file_size = round(progress_bar["maximum"]/(1024*1000), 2)
                    percentage = (progress_bar_value / file_size) * 100
                    label_percent.configure(text = f"{progress_bar_value} Mo / {file_size} Mo  ({percentage:.2f}%)")
     
     
            s3 = boto3.client(
            service_name='s3',
            aws_access_key_id=f'{key_id_bucket}',
            aws_secret_access_key=f'{key_secret_bucket}',
            )
     
            new_filename = os.path.basename(new_file_name)
            file_size = os.path.getsize(new_file_name)
     
            progress_bar["value"] = 0
            progress_bar["maximum"] = file_size
     
            thread1 = threading.Thread(target=lambda: s3.upload_file(
                new_file_name, 'testbein', f'video/{new_filename}',
                Callback=progress_callback))
     
            thread1.start()
     
            def monitor ():
                if thread1.is_alive():
                    parent.after(100, lambda:monitor())
                else :
                    check('testbein',f'video/{new_filename}',label)
     
            monitor()
     
     
            def check (bucket,file_key,label):
                s3_client = boto3.client('s3',
                                          aws_access_key_id=f'{key_id_bucket}',
                                          aws_secret_access_key=f'{key_secret_bucket}')
     
                result = s3_client.list_objects_v2(Bucket= bucket, Prefix= file_key)
                if 'Contents' in result:
                    label.configure(text='Fichier présent sur le serveur')
                else:
                    label.configure(text="Erreur lors de l'envois sur le serveur : Fichier introuvable")
    J'ai rajouté la fonction "monitor" qui vérifie toutes les 100 millisecondes si mon thread est actif

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    définir des fonctions un peu n'importe où à l'intérieur d'autres fonctions n'aide pas côté lisibilité.
    Si monitor est une fonction sans paramètre, le déclarer via juste monitor suffit écrire lambda:monitor() c'est juste plus lourd.

    Je ne sais pas combien de temps dure la copie, mais progress_callback doit savoir quand on est arrivé à 100%. Qu'on attende un peu pour s'assurer que... via monitor pourquoi pas.

    note: le prix de l'électricité va augmenter significativement... Python est certes interprété mais ce n'est pas une raison pour en ajouter.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

+ Répondre à la discussion
Cette discussion est résolue.

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo