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 bug et 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:

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()
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
# -*- 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
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++"



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