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

Python Discussion :

Mise en place d'un thread qui gère le chronomètre


Sujet :

Python

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 29
    Par défaut Mise en place d'un thread qui gère le chronomètre
    Bonjour,

    J'ai mis en place un chronometre qui s'affiche mais ne veut pas s'arrêter stop_chrono appelé dans une fonction et se tuer, pour quelle raison s'il vous plait?

    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
     
    def reset_chrono():
    	isRunningChrono=False
    	my_thread_chrono.current(isRunningChrono,tActualTime,tZero)
    	#my_thread_chrono.stop()
    	chrono_label['text'] ="00:00:00"
    	window.update_idletasks()
     
    def stop_chrono():
    	#global isRunningChrono
    	global tActualTime
    	global tZero
    	global my_thread_chrono
     
    	print("StopChrono")
    	isRunningChrono=False
    	window.update_idletasks()
    	my_thread_chrono.current(isRunningChrono,tActualTime,tZero)
    	for thread in enumerate():
    		if my_thread_chrono.isAlive():
    			try:
    				my_thread_chrono._Thread__stop()
    			except:
    				print(str(my_thread_chrono.getName()) + ' could not be terminated')
    	#time.sleep(5)
    	#window.update_idletasks()
    	#my_thread_chrono.stop()
     
    class Thread_Chrono(threading.Thread):
        def __init__(self, name):
            threading.Thread.__init__(self)
            self.name = name
     
     
        def current(self, test,tActual,tZ):
    		global isRunningChrono
    		#global tActualTime
    		global tZero
    		print(tActual)
    		print(tZ)
    		self.value = test
    		isRunningChrono=self.value
    		tActualTime=tActual
    		print("isRunningCurrent",isRunningChrono)
    		tZero=tZ
    		pass
     
        def run(self):
            global isRunningChrono    #made global here
            #global tActualTime
            global tZero
     
            while True:
                #print("isRunningChrono=%b",isRunningChrono)
     
                while isRunningChrono:
    				print("isRunning enter")
    				tActualTime=time.time()-tZero
    				tiTuple=time.gmtime(tActualTime)
    				reste=tActualTime-tiTuple[3]*3600.0-tiTuple[4]*60.0-tiTuple[5]*1.0
    				resteS=("%.2f" % reste)[-2::]
    				tt=time.strftime("%H:%M:%S",tiTuple)
    				chrono_label['text'] =""+tt
    				window.update_idletasks()
    				print tt
    				time.sleep(1)
    			#conditionThread.release()
     
     
     
    my_thread_chrono=Thread_Chrono("myThread_name_Chrono")
    my_thread_chrono.current(isRunningChrono,tActualTime,tZero)
    my_thread_chrono.start()
     
    def myFonction():
    stop_chrono()
    Ce que je ne comprend pas c'est que le thread doit être démarrer dans le process principal et non dans une fonction def, car je souhaite démarrer le chrono lors de l'appel d'une fonction et s'arrêter après un traitement précis?

    Merci d'avance.

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    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 715
    Par défaut
    Salut,

    Dans le run vous avez écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
             while True:
                   while condition:
                          ....
    lorsque condition passe à False, çà ne sort pas du "while True" englobant.

    Comme vous utilisez un GUI, pas besoin de thread pour réaliser une horloge mise à jour jour toutes les secondes: la plupart des event-loop supportent la déclaration d'un callback déclenché par un timer ou après une durée (et à réarmer).

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

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Février 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 29
    Par défaut
    Lorsque la condition passe à False, la boucle tourne toujours jusqu'à que je resette la valeur condition à True pour executer encore le chrono.

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    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 715
    Par défaut
    Citation Envoyé par lebossejames Voir le message
    Lorsque la condition passe à False, la boucle tourne toujours jusqu'à que je resette la valeur condition à True pour executer encore le chrono.
    Et bien vous remplacez ce True par une condition explicite et vous évitez d'appeler ._Thread_stop() - c'est une méthode privée (et non documentée) qui ne fait pas ce que vous pensez.

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

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Février 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 29
    Par défaut
    Très bien, mais concernant l'appel à la création d'un thread dans une fonction, est-il possible de le faire?

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    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 715
    Par défaut
    Citation Envoyé par lebossejames Voir le message
    Très bien, mais concernant l'appel à la création d'un thread dans une fonction, est-il possible de le faire?
    Un thread est un objet comme un autre... donc à priori, çà ne devrait pas poser de problème. Maintenant, si vous avez un cas de figure où çà ne fonctionne pas, postez le code (un exemple qui fonctionne).
    Ceci dit, thread et GUI coopèrent assez mal. Plutôt que de vous acharner à faire fonctionner votre code, peut être que vous devriez demander comment fabriquer un chrono. sans thread dans le forum qui va bien.

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

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Février 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 29
    Par défaut
    Pourquoi un appel à OS.system cause le blocage du comptage du chrono alors qu'il est lancé dans un thread en parallèle?

  8. #8
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    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 715
    Par défaut
    Citation Envoyé par lebossejames Voir le message
    Pourquoi un appel à OS.system cause le blocage du comptage du chrono alors qu'il est lancé dans un thread en parallèle?
    Si on prend la précaution de lancer os.system (ou time.sleep) dans un thread, c'est pour que les autres threads continuent sans attendre. Et si çà ne se passe pas ainsi chez vous, c'est probablement à cause de votre code.
    note: os.system est à éviter. utilisez subprocess.Popen à la place, c'est déjà asynchrone, pas besoin d'y ajouter un thread "au dessus".
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Février 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 29
    Par défaut
    Si c'est asynchrone, comment faire pour faire 2 appels dont le deuxième doit attendre que le premier est terminé puis après l'éxécution du deuxième exécuter une fonction final() par exemple?

  10. #10
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    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 715
    Par défaut
    Citation Envoyé par lebossejames Voir le message
    Si c'est asynchrone, comment faire pour faire 2 appels dont le deuxième doit attendre que le premier est terminé puis après l'éxécution du deuxième exécuter une fonction final() par exemple?
    Si j'écris un code qui fait "à peu près" ce que vous racontez, cet "à peu près" ne va pas vous aider...
    Donc si vous ne voulez pas prendre le temps de poster du code permettant de reproduire/illustrer votre cas d'utilisation...

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

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Février 2007
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 29
    Par défaut
    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
     
    def launch_report() :
    	try:
    		#os.system(report_cmd)
    		subprocess.Popen(report_cmd,shell=True,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE)
    		reportjs_label.configure(fg="green")
    		subprocess.Popen(archive_report_cmd,shell=True,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE)
    		report_simplified_js_label.configure(fg="green")
    		stop_chrono()
    		#webbrowser.open(localhost_path)
     
     
     
    	except Exception:
    		print('An error occured --- launch report')
    report_cmd doit etre executer en premier lieu puis archive_report_cmd puis la fonction stop_chrono()

  12. #12
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    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 715
    Par défaut
    Citation Envoyé par lebossejames Voir le message
    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
     
    def launch_report() :
    	try:
    		#os.system(report_cmd)
    		subprocess.Popen(report_cmd,shell=True,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE)
    		reportjs_label.configure(fg="green")
    		subprocess.Popen(archive_report_cmd,shell=True,
                            stdin=subprocess.PIPE,
                            stdout=subprocess.PIPE)
    		report_simplified_js_label.configure(fg="green")
    		stop_chrono()
    		#webbrowser.open(localhost_path)
     
     
     
    	except Exception:
    		print('An error occured --- launch report')
    report_cmd doit etre executer en premier lieu puis archive_report_cmd puis la fonction stop_chrono()
    Un bout de code qu'on ne peut pas lancer n'aide pas plus car il manque le contexte...
    note: GUI, chronomètre,... sont des activités asynchrones. On ne peut pas leur confier n'importe quels rôles/responsabilités et puis ramer pour faire tomber çà en marche.

    Tiens une clock et un bouton qui lance des s/process qui démarrent et arrête l'horloge.
    J'ai pris le parti de laisser au GUI le contrôle des opérations (c'est un choix... mais il faut prendre le risque de se tromper et voir comment on arrive à coder çà dans ces conditions)... Et j'ai juste pris le temps de recycler un exemple qui traînait sur mon ordi.

    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
    import tkinter as tk
    import time
    import subprocess as sp
     
     
    class Clock(tk.Label):
        _timer = None
        _start = None
     
        def __init__(self, master=None):
            super().__init__(master, text='00:00:00')
     
        def do_start(self):
            if self._timer is None:
                self._start = time.time()
                self._update()
     
        def do_stop(self):
            if self._timer is not None:
                self.after_cancel(self._timer)
                self._timer = None
     
        def _update(self):
            elapsed = time.time() - self._start
            text = time.strftime('%H:%M:%S', time.gmtime(elapsed))
            self.configure(text=text)
            self._timer = self.after(200, self._update)
     
     
    def do_run():
     
     
        def watch_terminate():
            if p.poll() is not None:
                data, error = p.communicate()
                data = data.splitlines()
                text.insert('end', b'\n'.join(data))
                clock.do_stop()
     
            else:
                root.after(200, watch_terminate)
        clock.do_start()
        p = sp.Popen('sleep 2 & ls', stdout=sp.PIPE, shell=True)
     
        watch_terminate()
     
     
    if __name__ == '__main__':
        root = tk.Tk()
        clock = Clock(root)
     
        menu = tk.Menu(root)
     
    #     menu.add_command(label='start', command=clock.do_start)
    #     menu.add_command(label='stop', command=clock.do_stop)
    #     menu.add_command(label='quit', command=root.quit)
     
        menu.add_command(label='run', command=do_run)
     
     
        root['menu'] = menu
     
        clock.pack()
        text = tk.Text(root)
        text.pack()
        tk.mainloop()

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

Discussions similaires

  1. Mise en place de div qui ne correspond pas aux pourcentages de width
    Par francky74 dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 06/03/2015, 11h10
  2. Problème de mise en place de thread
    Par Alex-L dans le forum SDL
    Réponses: 2
    Dernier message: 30/05/2012, 10h00
  3. Probleme avec la mise en place de thread
    Par jcloupgarou dans le forum MFC
    Réponses: 11
    Dernier message: 29/02/2012, 15h29
  4. Fermer proprement un thread qui gère les sockets
    Par theclem35 dans le forum Réseau
    Réponses: 1
    Dernier message: 08/04/2011, 10h59
  5. Réponses: 12
    Dernier message: 15/11/2010, 14h26

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