Bonjour à tous,

Il y a quelques années dans le cadre d'un projet j'ai écrit un petit chronomètre
en python2/pygtk qui marche très bien. Maintenant je veux porter ce projet en
python3/Gtk3 et la mon chronomètre ne marche plus du tout. Il fonctionne de
manière classique avec le signal SIGALRM arrêté par un handler toutes les secondes.
Curieusement en python3/Gtk3 le signal n'est pas transmis comme on s'y attendrait.
Pour donner plus de détails sur ce problème voici la version simplifiée du programme
en python2/pygtk qui marche parfaitement suivi du même programme en python3/Gtk3
qui ne fonctionne pas. Comment adapter cette gestion du signal en python3 ?

Je précise que je travaille sous Linux Debian 9 Stretch 64 bits. On voit mieux
le fonctionnement du signal si on lance les programmes dans un terminal.

La version qui marche en python2/pygtk
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
 
#!/usr/bin/env python2
# -*- coding: UTF-8
import pygtk
pygtk.require('2.0')
import gtk, gobject
import signal
 
class MainWindow(gtk.Window):
    def __init__(self):
        gtk.Window.__init__(self)
        self.set_border_width(6)
        self.set_title("Petit Chronomètre")
        self.stop = 0
        self.seconde = 0
 
        self.vbox = gtk.VBox(homogeneous=False,spacing=5)
        self.add(self.vbox)
 
        self.button1 = gtk.Button("Lancer le chrono")
        self.button1.connect("clicked", self.Button_Chrono)
        self.vbox.pack_start(self.button1, False, True, 1)
 
        self.button2 = gtk.Button("Mettre à zéro le chronomètre")
        self.button2.connect("clicked", self.init)
        self.vbox.pack_start(self.button2, False, True, 1)
 
        self.button3 = gtk.Button("Fermer")
        self.button3.connect("clicked", self.fermer)
        self.vbox.pack_start(self.button3, False, True, 1)
 
    def Button_Chrono(self,button):
        if(self.stop == 1):
            signal.alarm(1)
            button.set_label("Arrêter le chronomètre  ( "+str(self.seconde)+" secondes )")
            self.stop = 0
        else:
            signal.alarm(0)
            button.set_label("Relancer le chronomètre ( "+str(self.seconde)+" secondes )")
            self.stop = 1
 
    def init(self,button):
        self.seconde = 0
        if(self.stop == 1):
            self.button1.set_label("Relancer le chronomètre ( "+str(self.seconde)+" secondes )")
        else:
            self.button1.set_label("Arrêter le chronomètre  ( "+str(self.seconde)+" secondes )")
 
    def fermer(self,button):
        gtk.main_quit()
 
def gerechrono():
    def handler(signum, frame):
        print "DANS HANDLER: ",signum
        signal.signal(signal.SIGALRM, handler)
        win.button1.set_label("Arrêter le chronomètre  ( "+str(win.seconde)+" secondes )")
        win.seconde = win.seconde + 1
        signal.alarm(1)
    handler(0,0)
 
win = MainWindow()
win.connect("delete-event", gtk.main_quit)
win.show_all()
gerechrono()
gtk.main()
La version en python3/Gtk3
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
 
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import signal
 
class MainWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Petit Chronomètre")
        self.set_border_width(6)
        self.stop = 0
        self.seconde = 0
 
        self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL,homogeneous=False,spacing=5)
        self.add(self.vbox)
 
        self.button1 = Gtk.Button("Lancer le chronomètre")
        self.button1.connect("clicked", self.Button_Chrono)
        self.vbox.pack_start(self.button1, False, True, 1)
 
        self.button2 = Gtk.Button("Mettre à zéro le chronomètre")
        self.button2.connect("clicked", self.init)
        self.vbox.pack_start(self.button2, False, True, 1)
 
        self.button3 = Gtk.Button("Fermer")
        self.button3.connect("clicked", self.fermer)
        self.vbox.pack_start(self.button3, False, True, 1)
 
    def Button_Chrono(self,button):
        if(self.stop == 1):
            signal.alarm(1)
            button.set_label("Arrêter le chronomètre ( "+str(self.seconde)+" secondes )")
            self.stop = 0
        else:
            signal.alarm(0)
            button.set_label("Relancer le chronomètre ( "+str(self.seconde)+" secondes )")
            self.stop = 1
 
    def init(self,button):
        self.seconde = 0
        if(self.stop == 1):
            self.button1.set_label("Relancer le chronomètre ( "+str(self.seconde)+" secondes )")
        else:
            self.button1.set_label("Arrêter le chronomètre  ( "+str(self.seconde)+" secondes )")
 
    def fermer(self,button):
        Gtk.main_quit()
 
def gerechrono():
    def handler(signum, frame):
        print("DANS HANDLER: ",signum)
        signal.signal(signal.SIGALRM, handler)
        win.button1.set_label("Arrêter le chronomètre  ( "+str(win.seconde)+" secondes )")
        win.seconde = win.seconde + 1
        signal.alarm(1)
    handler(0,0)
 
win = MainWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
gerechrono()
Gtk.main()
Avec mes remerciements pour vos conseils