Pour créer un timer qui va décompter le temps on va utiliser les threads de Python dans une classe séparée.
On va importer les classes nécessaires et surtout initialiser les threads.
gobject.threads_init()
La classe qui va gérer le thread comporte 3 paramètres : la barre de progression, le temps, la fonction à apeller quand le timer expire
def __init__(self, barre, tempstotal,callback):
super(MaBarre, self).__init__()
self.barre = barre
self.tempstotal=tempstotal
self.callback=callback
self.quitter=False
self.on = False
self.compteur = 0.0
def update_barre(self, frac):
if self.on:
self.barre.set_fraction(frac)
return False
def run(self):
print "run"
#tant que le thread est actif
while not self.quitter:
if self.on: #si le compteur est allumé et non expiré alors
self.compteur += 0.1
frac=self.compteur/self.tempstotal
if frac<=1.0:
gobject.idle_add(self.update_barre, frac)
else:
self.lancer_callback()
time.sleep(0.1)
def stop(self):
self.quitter=True
def setOn(self):
self.on=True
self.compteur = 0.0
def setOff(self):
self.on=False
def lancer_callback(self):
self.setOff()
self.callback()
TODO : pour faire plus propre il faudrait enlever le set_fraction pour regrouper tout ce qui est GUI dans le main thread.
Ensuite, dans la classe principale, il faut :
- instancier le timer
- détruire le timer si on quitte
on rajoute donc
self.threadpbar.start()
dans la fonction main() et
dans la fonction destroy
Le code complet :
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 | #!/usr/bin/env python # -*- coding: utf-8 -*- import pygtk pygtk.require('2.0') import string,random import threading,time,gobject import gtk gobject.threads_init() class MaBarre(threading.Thread): def __init__(self, barre, tempstotal,callback): super(MaBarre, self).__init__() self.barre = barre self.tempstotal=tempstotal self.callback=callback self.quitter=False self.on = False self.compteur = 0.0 def update_barre(self, frac): if self.on: self.barre.set_fraction(frac) return False def run(self): print "run" #tant que le thread est actif print self.quitter while not self.quitter: if self.on: #si le compteur est allumé et non expiré alors self.compteur += 0.1 frac=self.compteur/self.tempstotal if frac<=1.0: gobject.idle_add(self.update_barre, frac) else: self.lancer_callback() time.sleep(0.1) def stop(self): self.quitter=True def setOn(self): print "timer=on" self.on=True self.compteur = 0.0 def setOff(self): self.on=False def lancer_callback(self): self.setOff() self.callback() class ChiffresEtLettres: def delete_event(self, widget, event, data=None): print "delete event occurred" return False def destroy(self, widget, data=None): print "destroy signal occurred" self.threadpbar.stop() gtk.main_quit() def __init__(self): print "_init_" # création de la fenêtre self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.set_title("Des Chiffres et des Lettres") self.window.connect("delete_event", self.delete_event) self.window.connect("destroy", self.destroy) self.window.set_border_width(100) table=gtk.Table(11,3,False) self.window.add(table) #labels tirages self.lettre=[] for i in range(10): self.lettre.append(gtk.Label("")) table.attach(self.lettre[i], i+1, i+2, 0, 1) # bouton nouveau tirage button = gtk.Button("Nouveau tirage") button.connect("clicked", self.tiragelettres, None) table.attach(button, 0, 1, 0, 1) #progress bar self.pbar = gtk.ProgressBar() table.attach(self.pbar, 1, 11, 1, 2) #tout montrer self.window.show_all() self.window.show() def main(self): self.threadpbar=MaBarre(self.pbar,5.0,self.timeup) self.threadpbar.start() gtk.main() def tiragelettres(self, widget, data=None): print "Nouveau tirage de lettres" for i in range(10): self.lettre[i].set_text(string.ascii_uppercase[random.randint(0,25)]) self.demarrertimer() def demarrertimer(self): print "Demarrage du timer" self.threadpbar.setOn() def timeup(self): print "times up" if __name__ == "__main__": cl = ChiffresEtLettres() cl.main() |
Ce qui donne ceci :
Le timer se déclenche sur le nouveau tirage, le callback est apellé quand le temps est écoulé.
Prochaine étape : améliorer la qualité des tirages