Bonjour,
Je souhaiterais pouvoir éxécuter une action en boucle pendant un temps donné (2' par exemple).
J'ai essayé en utilisant le module time et les threads mais ça ne fait pas ce que je veux.
Merci pour vos idées à venir
Greg
Bonjour,
Je souhaiterais pouvoir éxécuter une action en boucle pendant un temps donné (2' par exemple).
J'ai essayé en utilisant le module time et les threads mais ça ne fait pas ce que je veux.
Merci pour vos idées à venir
Greg
Bonjour,
Voilà un exemple tout simple qui utilise threading.Timer (arrêt ici au bout de 5 secondes):
Tyrtamos
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 import threading def findeboucle(): global encore encore = False encore = True timer = threading.Timer(5, findeboucle) timer.start() while encore: pass print u"fini!"
bonjour ,
J ai un probleme avec Thread.start sous Tkinter je peux uniquement lancer le Thread via Thread.run et donc mes apis ne sont pas "multitaches" y a t il quelque chose que j aurais oublie?
bonjour,
tu lances un thread depuis Tkinter ou tu lances un Tkinter depuis un thread ?
Bonsoir,
voici le code dans lequel j'aimerais l'utiliser.
Les instances Keys doivent en fait dériver de Threads mais comme ça posait problème j'ai du adopter une autre méthode.
salut
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223 #coding:latin1 #################### Fichier Tk_key.py v(1.0 mono-Thread)#################### from time import sleep from threading import Thread class core(Thread): def __init__(self): Thread.__init__(self) self.alive = True self.db = [] def pause(self,event=None): self.alive = False def unpause(self,event=None): self.alive = True for key in self.db: key.pressed = False self.run() def add(self,key): self.db.append(key) def kill(self,key): if key in self.db: self.db.remove(key) def run(self): while self.alive: l = len(self.db) for key in self.db: key.run_() sleep(0.001) sleep(0.002) class Key: motor = core() def __init__(self,boss,key,func,slp=0.01): """Constructeur de classe Key pour des bindings multiples""" self.boss = boss self.func = func self.slp = slp self.alive = True self.pressed = False #self.boss.bind("<FocusIn>",self.unpause) #Pour les versions multi-Thread #self.boss.bind("<FocusOut>",self.pause) #Pour les versions multi-Thread self.k_p = "<KeyPress "+key+">" #sauvegarde le nom de l'evenement pour Press self.k_r = "<KeyRelease "+key+">" #sauvegarde le nom de l'evenement pour Release self.f_p = boss.bind(self.k_p,self.press) #fait un binding(attend un appui de touche) self.motor.add(self) #La jour la cle au moteur des Keys if len(self.motor.db)==1: #Si c'est la premiere instance alors on demarre le moteur self.boss.after(250,self.motor.run) self.boss.bind("<FocusIn>",self.motor.unpause) self.boss.bind("<FocusOut>",self.motor.pause) def set(self,slp=0.005): """Definit le temps de repos de la Key (Non implemente)""" if slp>0.001: self.slp = slp def press(self,event=None): """Est appele lorsque la touche est presse""" self.boss.unbind(self.k_p,self.f_p) self.f_r = self.boss.bind(self.k_r,self.release) self.pressed = True self.func() self.run_() def release(self,event=None): """Est appele lorsque la touche est relache""" self.boss.unbind(self.k_r) self.f_p = self.boss.bind(self.k_p,self.press) self.pressed = False def run_(self,arg=None): """Effectue les tache necessaire ...""" #Dans les versions ulterieures chaque instance de Key sera #un Thread et a la place de if on aura un while if self.alive: try: self.boss.update() if self.pressed: self.func() except: self.alive = False self.motor.kill(self) sleep(self.slp) #Le sleep(self.slp) sera donc independant de processus #en cours. def pause(self,event=None): """met la touche en pause""" self.alive = False self.motor.kill(self) def unpause(self,event=None): """reactive la touche""" self.alive = True self.motor.add(self) #self.run() # zone de test # """ if __name__ == "__main__": from Tkinter import Tk def f(): root.title("spy_anf") print "spy_anf" def g(): root.title("nano is me") print "nano is me" def h(): root.title("salut les potes") print ("salut les potes") root = Tk() k = Key(root,"q",f) g = Key(root,"s",g) h = Key(root,"d",h) root.mainloop() """ #################### Fin du fichier Tk_key.py ############ #################### Fichier ???car_schum?????.py ######## from Tkinter import * #from Tk_key import Key,sleep ##Ligne à decommenter def round( x ): if x > 0: return int( x+0.5 ) else: return -int( -x+0.5 ) class Vector : sin45 = 0.70710678 def __init__(self,x = 0,y = 0): self.x,self.y = x,y def rot45left(self) : self.x,self.y = round( self.x*self.sin45 + self.y*self.sin45 ), round( self.y*self.sin45 - self.x*self.sin45 ) def rot45right(self) : self.x,self.y = round( self.x*self.sin45 - self.y*self.sin45 ), round( self.y*self.sin45 + self.x*self.sin45 ) def __iadd__ (self,vect): self.x += vect.x self.y += vect.y return self def __add__ (self,vect): return Vector( self.x+vect.x,self.y+vect.y ) def __isub__ (self,vect): self.x -= vect.x self.y -= vect.y return self def __sub__ (self,vect): return Vector( self.x-vect.x,self.y-vect.y ) class Auto : def __init__(self,canvas): self.A = Vector( 5,0 ) self.B = Vector( -5,0 ) self.C = Vector( 0,5 ) self.dir = Vector( 0,2 ) self.pos = Vector( 25,100 ) self.canvas = canvas self.poly = self.canvas.create_polygon( *self._poly()) self.canvas.itemconfigure(self.poly,fill="red") def left (self): self.A.rot45left() self.B.rot45left() self.C.rot45left() self.dir.rot45left() self.canvas.coords( self.poly,*self._poly() ) def right (self): self.A.rot45right() self.B.rot45right() self.C.rot45right() self.dir.rot45right() self.canvas.coords( self.poly,*self._poly() ) def forward (self): self.pos += self.dir self.canvas.coords( self.poly,*self._poly() ) def backward (self): self.pos -= self.dir self.canvas.coords( self.poly,*self._poly() ) def _poly (self): a = self.A + self.pos b = self.B + self.pos c = self.C + self.pos return ( a.x,a.y,b.x,b.y,c.x,c.y ) def test_Auto (): fenster = Tk() canvas = Canvas(fenster, height=200, width=200, bg='black') bahn = canvas.create_polygon(20, 20, 30,10, 170,10, 180,20, 180,170, 170,180, 30,180, 20,170, 20,20, 30,30, 40,20, 160,20, 170,30, 170,160, 160,170, 40,170, 30,160, 30,30, fill='white') car = Auto( canvas ) canvas.focus_set() Key(canvas,"Up",car.forward) Key(canvas,"Down",car.backward) Key(canvas,"Right",car.right) Key(canvas,"Left",car.left) #canvas.bind("<Up>" , lambda e : car.forward ()) #canvas.bind("<Down>" , lambda e : car.backward()) #canvas.bind("<Right>", lambda e : car.right ()) #canvas.bind("<Left>" , lambda e : car.left ()) canvas.pack() mainloop()
Salut,
Dans le post, j'avais donné des solutions avec et sans threads pour faire cela.
- W
Bonsoir,
@wiztricks:
Merci pour le lien mais Je n'y pas compris grand chose
Donc pour tout ce que j'ai c'est
pour résoudre mes problèmes.récursivité + sleep
@greg_78ou alors tu veux killer une boucle infinie? genre un watchdog ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 T = maintenant + 2 secondes temps que maintenant < T: action()
Hmm
En gros çà dit que:
1 - Tk n'est pas thread-safe. Ce qui signifie que modifier l'état de Widget Tk dans un thread autre que celle dans laquelle a été lancée root.mainloop() plantera +/- vite et de façon +/- aléatoire,
2 - Les threads sont indiquées pour y faire des traitement de type calculs mais comme Python ne sait pas les ordonnancer sur plusieurs CPU, il faudra plutôt utiliser multiprocessing - sinon IHM et calculs partagent le même CPU et les calculs impacteront la réactivité de l'IHM.
3 - Si le but est de modifier l'état de Widgets TK pour créer une illusion de mouvement, "il suffit" de les faire tourner un peu de temps en temps,
4 - Avec TK, "de temps en temps" peut être une fonction poller_routine qui se ressoumet à chaque fois via un appel a root.after(delay, routine).
Lorsque la routine se déclenche, on parcours la liste des Widgets "en mouvement" pour qu'ils changent leur état.
Reste à aligner ton code avec cela... et je conviens que ce ne soit pas "simple" mais il faudra s'y résoudre un jour ou l'autre
- W
[quote=wiztricks;
root.after(delay, routine)[/QUOTE]
Effectivement c'est ce que j'entends par
récursivité + sleep
Bonjour,
Le Forum regorge de cas dans ce sens. Les cas les plus presents sont la différence entre l'état de l'objet tk et les informations de tkinter (vous avez un post récent sur Frame à ce sujet) ou l'utilisation des class variables tkinter.
La solution est peut être de passer par le callback d'un objet python.
tkinter est dans l'attente du callback.
le thread modifie l'objet.
De ce fait le thread et tkinter sont indépendants.
Cela donne un truc comme :
Bon code
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 #!/usr/bin/env python # -*- coding: UTF-8 -*- # # class myvar for jlg_47 # http://www.developpez.net/forums/d915461/autres-langages/python-zope/general-python/crash-aleatoire-thread/ # Based on Tkinter variable class class myvar: _default = "" def __init__(self, master=None, value=None, name=None, trace=None, mode=None): if not master: master = self self._master = master if name: self._name = name else: self._name = None if value is not None: self._value=value else: self._value=self._default if trace: self._trace=trace else: self._trace=None if mode: self._mode=mode else: self._mode=None self._oldmode=None self._oldtrace=None def __str__(self): return str(self._name) def set(self, value): self._value=value if self._trace is not None and (self._mode == 'u' or self._mode == 'w'): self.savetrace() self._oldtrace() elif self._oldtrace is not None: self.restauretrace() def get(self): if self._trace is not None and (self._mode == 'u' or self._mode == 'r'): self.savetrace() self._oldtrace() elif self._oldtrace is not None: self.restauretrace() return self._value def trace_variable(self, mode, callback): self._mode=mode self._trace=callback trace = trace_variable def trace_vdelete(self): self._mode=None self._trace=None def trace_vinfo(self): return self._mode, self._trace def varinfo(self): return "Master", self._master, "Name", self._name, "Value", str(self._value), "Trace callback", self._trace, "Trace mode", self._mode # TODO For callback recursion def restauretrace(self): self._trace=self._oldtrace self._mode=self._oldmode self._oldtrace=None self._oldmode=None def savetrace(self): self._oldtrace=self._trace self._oldmode=self._mode self._trace=None self._mode=None if __name__ == "__main__": a=myvar() # Default value = "" print a.get() # Set a value a.set(10) # Get the value print a.get() # trace value def callback(): # Please, don't use multiples get()/set() whith callback print 'a in callback', a.get() # a.set(30) a.trace('u', callback) a.set(20) print 'a after callback' print a.get() # Callback informations print 'Callback informations', a.trace_vinfo() # Name b=myvar(name='b') print 'b name', b # Variable informations print 'Variable informations' dir(b) print b.varinfo() # Delete callback a.trace_vdelete() print a.trace_vinfo()
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager