Bonjour. J'essaye de faire la synthèse de ce que j'ai glané sur la toile à propos de pygtk et les threads. J'essaye donc un programme très simple d'expérimentation. J'ai une classe principale, une qui gère 2 threads et un classe thread proprement dite.

Mon problème : lorsque les threads 1 et 2 sont lancés simultanément, j'ai toujours un seul des deux labels qui est mis à jour. D'une façon générale, j'ai repéré les fonctions "critiques" avec des flèches, sont-elles aux bons endroits ? Je pense qu'il y a un problème.

D'avance merci.

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
 
#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import threading
import time
from threads_manager import ThreadsManager
import gobject
import gtk
gobject.threads_init() # <-----
 
class Main:
 
    def __init__(self):    
        self.window = gtk.Window()
        self.button1 = gtk.Button('Start/stop thread 1')
        self.button2 = gtk.Button('Start/stop thread 2')
        self.label = []
        self.label.append(gtk.Label(str(time.time())))
        self.label.append(gtk.Label(str(time.time())))
        self.table = gtk.Table()
        self.table.attach(self.label[0], 0, 1, 0, 1, xpadding=10)
        self.table.attach(self.button1, 1, 2, 0, 1)
        self.table.attach(self.label[1], 0, 1, 1, 2, xpadding=10)
        self.table.attach(self.button2, 1, 2, 1, 2)
        self.window.add(self.table)
        self.threads_manager = ThreadsManager(self)
        self.button1.connect('clicked', self.threads_manager.switch_thread_state, 1)
        self.button2.connect('clicked', self.threads_manager.switch_thread_state, 2)
        self.window.connect('destroy', self.quit)
        self.window.set_position(gtk.WIN_POS_CENTER)
        self.window.show_all()
 
    def main(self):
        gtk.main()
        return 0
 
    def quit(self, widget_window):
        # À finir. Informer les threads qu'ils doivent stopper afin de quitter proprement ?
        gtk.main_quit()
 
if __name__ == '__main__':
    main = Main()
    main.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
 
#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import threading, time
from my_thread import MyThread
import gtk
 
class ThreadsManager:
 
    def __init__(self, main):
        self.main = main
        self.th1 = MyThread(self.main, 1)
        self.th2 = MyThread(self.main, 2)
 
    def switch_thread_state(self, widget_button, nb):
        if nb == 1:
           if self.th1.is_running == True:
               self.th1.stop()
           else:
               self.th1.start()
        else: # Therefore nb == 2
            if self.th2.is_running == True:
               self.th2.stop()      
            else:
               self.th2.start()
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
 
#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import threading, time
import gtk
 
class MyThread(threading.Thread):
 
    def __init__(self, main, nb):
        threading.Thread.__init__(self)
        self.main = main
        self.nb = nb
        self.is_running = False
 
    def start(self):
        print 'start thread', self.nb
        self.is_running = True
        while self.is_running == True:
            self.update_label()
            time.sleep(0.1) 
 
    def stop(self):
        print 'stop thread', self.nb
        self.is_running = False
 
    def update_label(self):
        # Le but de cette fonction est de montrer comment modifier
        # un objet gtk dans la boucle principale depuis un thread.
        gtk.gdk.threads_enter()  # <-----
        self.main.label[self.nb-1].set_text(str(time.time()))
        gtk.gdk.threads_leave() # <-----
        gtk.main_iteration() # <-----