Des Chiffres et des Lettres – Timer et ProgressBar

08 062011

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.

import threading,time,gobject
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

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
        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=MaBarre(self.pbar,5.0,self.timeup)
self.threadpbar.start()

dans la fonction main() et

self.threadpbar.stop()

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

Cette entrée a été publiée dans Des Chiffres et des Lettres. Vous pouvez la mettre en favoris avec ce permalien.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>