Bonjour,
Depuis plusieurs jours, je suis confronté au crash aléatoire d'un thread dans une application qui comporte:
1- une fenêtre de saisie et affichage
2- un thread de calcul.
Fort heureusement (ou malheureusement!) ces crashs se produisent très rarement; mais cela révèle l'existence d'un buget j'aimerais bien corriger la situation.
J'ai reproduit le problème sur un bout de code minimum.
Le programme principal ouvre une fenêtre Tkinter dans laquelle il y a un curseur (Scale) et un label.
Ce programme lance un thread de calcul qui tourne continuellement dans une boucle et qui:
1- récupère la valeur affichée au curseur
2- calcul une variable, dans le cas présent la variable rejoint progressivement la valeur affichée au curseur
3- modifie la valeur de la variable dans le "main", ce qui provoque son affichage
Voici le code du main:
Et voici le code du thread de calcul:
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 # -*- coding: ISO8859-1 -*- # from Tkinter import * import threading from calcul import * import time from sys import modules progmain = modules['__main__'] def afficher(varName, index, mode): # déclenchée lors d'un changement de my_var label_my_var.configure ( text = 'ma variable : ' + '%6.1f' %my_var.get()) def set_var(my_var): # activée lors du mouvement du curseur my_cursor.event_generate('<Control-Z>') def stop_calcul(): calcul_running.set(False) # stop calcul when mainloop is terminated time.sleep (1.) # attendre 1 seconde l'arrêt du calcul root.destroy() # main prog ################################### root = Tk() # creation du curseur my_cursor = Scale(root, length=450, orient=HORIZONTAL, sliderlength =15, label ='ma consigne', from_=0, to=200, tickinterval =20, resolution =0.1,showvalue =1, command = set_var) my_cursor.pack() # creation de l'afficheur avec variable traçable label_my_var = Label (root, font=("Arial",14)) label_my_var.pack() my_var = DoubleVar() my_var.trace_variable("w", afficher) # tout changement de my_var déclenche son affichage # lancement du thread de calcul calcul_running=BooleanVar() # le booléen permet d'arrêter le thread calcul_running.set(True) t1=threading.Thread(target=calcul) t1.start() # execute mainloop root.protocol ("WM_DELETE_WINDOW",stop_calcul) root.mainloop()
Voici le genre de bug aléatoire qui est déclenché, notez qu'il est surprenant que la fenêtre soit intitulée "Visual C++"
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 # -*- coding: cp1252 -*- from math import * import time from sys import modules progmain = modules['__main__'] def calcul(): # initialisation step = 0.1 ; temps = 0. ; var = 0. while progmain.calcul_running.get()== True: progmain.my_var.set(var) # on renvoie var dans progmain.my_var, cette action déclenche # l'affichage par changement de sa valeur # calcul d'une seconde fictive par pas de 0,1 seconde ################ for i in range(0,10): var0 = progmain.my_cursor.get() # récupérer la valeur du curseur toutes les 0.1 seconde temps = temps + step # calcul du temps fictif dvar = var0 - var # adjuster progressivement var à la valeur du curseur if (abs(dvar) <= (5. * step) ) : var = var0 else : var = var + 5.* step * dvar / abs (dvar) time.sleep(0.1) # les calculs sont remplacés par time.sleep
suivi du message suivant dans lequel la fenêtre est bien intitulée "pythonw.exe - erreur d'application"
Il n'y a aucun message sur la fenêtre Python !!
J'ajoute un point important :
le crash se produit uniquement (quand il se produit!) lors d'un déplacement du curseur
Merci d'avance à ceux qui me liront et surtout à ceux qui pourront me donner un coup de main pour résoudre ce problème.
Bonne journée
Partager