Bonjour tout le monde,

Voila quelques jours que je bloque sur une solution à mon problème. J'essaie de faire un petit logiciel de contrôle d'appareil photo Canon. pour cela j'ai bien sur une interface série (Arduino) ou plus tard pyserial. Bref, le problème n'est pas là ceci fonctionne à merveille.
Dans mon logiciel j'ai deux modes de prise de photo (les astrophotographes reconnaîtront l'utilité de ce programme ... ) :

- Intervallomètre classique : temps de pose, temps entre les poses et le nombre de pose.
- Mis au point : qui consiste à prendre une seule photo rapide afin d'effectuer la mise au point.

Mon module de mise au point fonctionne nickel, je peux passer l'état des widjets en DISABLED durant la pose et afficher le temps restant ainsi que le mode utilisé.
Voila ou ça se complique...
Pour faire mon intervallomètre j'aimerai pouvoir afficher le nombre de photo restant et le temps total restant de toute les prises, cependant il est très difficile, avec mes petites compétences, de le faire. J'ai tout de même réussi à le faire mais d'une manière différente que le mode mise au point qui m'empêche de prendre la main sur les widgets. Je sais qu'il est impossible de commander des widgets quand une boucle de la lib "time" comme "sleep" est utilisée, car celle-ci est bloquante dans un environnement tkinter qui est , si j'ai bien compris, une boucle en elle-même.

Donc me voila dans un dilem j'ai essayé plusieurs chose mais ça "bloque" à chaque fois .... bref quelqu'un pourrait m’aiguiller sur la manière de faire pour avoir une solution qui pourrait décompter (photo restantes à prendre) des boucles (temps d'exposition et temps entre pose) dans un environnement tkinter afin de pouvoir garder le contrôle sur l'affichage des labels et l’état des widgets(combobox, button, etc...).
Je vous mets le code complet en espérant qu'ils soient assez clair :
Merci d'avance pour votre aide.
Fred

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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
from tkinter import *
from tkinter import messagebox, ttk
from time import sleep
 
"""upload StandardFirmata.ino"""
import pyfirmata
 
counter_id = None
counter_time_between_id = None
exposure_time = [1, 2, 3, 4, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90]
 
"""connection à la carte Arduino"""
# pin = 10
# strComPort = '/dev/ttyACM0'
# strComBaud = 9600
# brdUno = pyfirmata.Arduino(strComPort)
 
 
def intervalometer(c, texp, tbet):
    for i in range(c):
        if i != 0:
            c = c - 1
            print("reste :", c, "photos.")
 
            """Envoi signal externe on"""
            # brdUno.digital[pin].write(1)
            print("Photo en pose On")
            sleep(texp)
            """Envoi signal externe off"""
            # brdUno.digital[pin].write(0)
            print("Photo en pose Off")
 
            print("temps entre la pose")
            sleep(tbet)
    return c
 
 
def run_intervalometer():
    c = int(nbr_picture_entry.get()) + 1
    texp = int(exposure_intervalometer_value_combobox.get())
    tbet = int(time_between_combobox.get())
    intervalometer(c, texp, tbet)
 
 
def run_map():
    mode_value['text'] = "Mise au point"
    remain_pic_label['state'] = DISABLED
    button_stop['state'] = NORMAL
    t = int(exposure_intervalometer_value_combobox_map.get())
    run(t)
 
 
def run(t):
    expo_time_map(t)
    """Envoi signal externe on"""
    # brdUno.digital[pin].write(1)
 
 
def expo_time_map(exp_time_map):
    """blocage des widgets durant la photo"""
    # Mise au point
    button_run_map['state'] = DISABLED
    exposure_intervalometer_value_combobox_map['state'] = DISABLED
 
    # Intervalomètre
    button_run_intervalometer['state'] = DISABLED
    exposure_intervalometer_value_combobox['state'] = DISABLED
    time_between_combobox['state'] = DISABLED
    nbr_picture_entry['state'] = DISABLED
 
    global counter_id
 
    """convertisseur seconde en h:m:s"""
    days = divmod(exp_time_map, 86400)
    hours = divmod(days[1], 3600)
    minutes = divmod(hours[1], 60)
    remain_time_value['text'] = "%i h %i min %i sec." % (hours[0], minutes[0], minutes[1])
 
    if exp_time_map > 0:
        counter_id = root.after(1000, expo_time_map, exp_time_map - 1)
    else:
        fin()
 
 
def fin():
    if counter_id:
        root.after_cancel(counter_id)
        remain_time_value['text'] = "Terminé"
 
        """Envoi signal externe off"""
        # brdUno.digital[pin].write(0)
 
        messagebox.showinfo("", "Prise terminée !")
        """Déblocage des widgets une fois la ou les photo(s) terminée(s)"""
 
    # Mise au point
    button_run_map['state'] = NORMAL
    exposure_intervalometer_value_combobox_map['state'] = NORMAL
    button_stop['state'] = DISABLED
 
    # Intervalomètre
    button_run_intervalometer['state'] = NORMAL
    exposure_intervalometer_value_combobox['state'] = NORMAL
    time_between_combobox['state'] = NORMAL
    nbr_picture_entry['state'] = NORMAL
 
    # Status
    remain_pic_label['state'] = NORMAL
    mode_value['text'] = ""
    remain_pic_value['text'] = ""
    remain_time_value['text'] = ""
 
 
def stop():
    if counter_id:
        root.after_cancel(counter_id)
        remain_time_value['text'] = "Terminé"
 
        """Envoi signal externe off"""
        # brdUno.digital[pin].write(0)
 
        messagebox.showinfo("", "Prise annulée")
 
    """Déblocage des widgets une fois la ou les photo(s) terminée(s)"""
    # Mise au point
    button_run_map['state'] = NORMAL
    exposure_intervalometer_value_combobox_map['state'] = NORMAL
    button_stop['state'] = DISABLED
 
    # Intervalomètre
    button_run_intervalometer['state'] = NORMAL
    exposure_intervalometer_value_combobox['state'] = NORMAL
    time_between_combobox['state'] = NORMAL
    nbr_picture_entry['state'] = NORMAL
 
    # Status
    remain_pic_label['state'] = NORMAL
    mode_value['text'] = ""
    remain_pic_value['text'] = ""
    remain_time_value['text'] = ""
 
 
def quitter():
    root.destroy()
    root.quit()
 
 
root = Tk()
root.minsize(455, 310)
root.title("Intervallomètre")
 
""" LabelFrames & Labels ---------------------------------------------------------------------------"""
intervalometer_frame = LabelFrame(root, text="Intervallomètre")
intervalometer_label_frame = Frame(intervalometer_frame)
intervalometer_entries_frame = Frame(intervalometer_frame)
 
status_frame = LabelFrame(root, text="status")
status_frame_label = Frame(status_frame)
status_frame_value = Frame(status_frame)
 
map_frame = LabelFrame(root, text="Mise au point")
 
intervalometer_frame.place(width=240, height=200, x=5, y=5)
intervalometer_label_frame.place(width=145, height=170, x=5)
intervalometer_entries_frame.place(width=80, height=170, x=150)
 
status_frame.place(width=325, height=100, x=5, y=205)
status_frame_label.place(width=110, height=75, x=5)
status_frame_value.place(width=200, height=75, x=115)
 
map_frame.place(width=200, height=200, x=250, y=5)
"""-------------------------------------------------------------------------------------------------"""
 
""" Intervalometer Frame ---------------------------------------------------------------------------"""
# Label frames
exposure_intervalometer_label = Label(intervalometer_label_frame, text="Temps d'exposition :")
time_between_label = Label(intervalometer_label_frame, text="Temps entre prise :")
time_nbr_picture_label = Label(intervalometer_label_frame, text="Nombre de photos :")
 
exposure_intervalometer_label.grid(row=0, sticky=E, ipady=10)
time_between_label.grid(row=1, sticky=E, ipady=10)
time_nbr_picture_label.grid(row=2, sticky=E, ipady=10)
 
# Entry frames
exposure_intervalometer_value_combobox = ttk.Combobox(intervalometer_entries_frame, values=exposure_time)
exposure_intervalometer_value_combobox.current(0)
time_between_combobox = ttk.Combobox(intervalometer_entries_frame, values=[1, 2, 3, 4, 5])
time_between_combobox.current(0)
nbr_picture_entry = Entry(intervalometer_entries_frame)
 
exposure_intervalometer_value_combobox.place(width=50, height=20, y=10)
time_between_combobox.place(width=50, height=20, y=50)
nbr_picture_entry.place(width=50, height=22, y=92)
 
# Bouton
button_run_intervalometer = Button(intervalometer_frame, text="Run", command=run_intervalometer)
button_run_intervalometer.place(width=80, height=30, x=85, y=140)
"""-------------------------------------------------------------------------------------------------"""
 
""" Status Frame -----------------------------------------------------------------------------------"""
# Label frame
mode_label = Label(status_frame_label, text="Mode :")
remain_pic_label = Label(status_frame_label, text="Reste :")
remain_time_label = Label(status_frame_label, text="Temps restant :")
 
mode_label.grid(row=0, sticky=E, ipady=2)
remain_pic_label.grid(row=1, sticky=E, ipady=2)
remain_time_label.grid(row=2, sticky=E, ipady=2)
 
# Value frame
mode_value = Label(status_frame_value)
remain_pic_value = Label(status_frame_value)
remain_time_value = Label(status_frame_value)
 
mode_value.grid(row=0, sticky=W, ipady=2)
remain_pic_value.grid(row=1, sticky=W, ipady=2)
remain_time_value.grid(row=2, sticky=W, ipady=2)
"""-------------------------------------------------------------------------------------------------"""
 
""" map Frame --------------------------------------------------------------------------------------"""
exposure_intervalometer_map = Label(map_frame, text="Temps d'exposition :")
exposure_intervalometer_value_combobox_map = ttk.Combobox(map_frame, values=exposure_time)
exposure_intervalometer_value_combobox_map.current(0)
button_run_map = Button(map_frame, text="Run", command=run_map)
 
exposure_intervalometer_map.place(width=150, height=20, y=20, x=25)
exposure_intervalometer_value_combobox_map.place(width=50, height=20, y=60, x=75)
button_run_map.place(width=80, height=30, x=60, y=105)
"""-------------------------------------------------------------------------------------------------"""
 
""" Bouton root -----------------------------------------------------------------------------------"""
button_stop = Button(root, text="Stop", state=DISABLED, command=stop)
button_stop.place(width=80, height=30, x=350, y=220)
 
button_quit = Button(root, text="Quitter", command=quitter)
button_quit.place(width=80, height=30, x=350, y=270)
"""-------------------------------------------------------------------------------------------------"""
 
root.protocol('WM_DELETE_WINDOW', quitter)
root.mainloop()
J'ai commenté toutes les commandes extérieures (Arduino) afin que vous puissiez faire fonctionner le programme.