'tkinter executes one more time the function after using after_cancel()
So I have a button that in a cyle way execute a function as soon as the buttom is pressed down. Once released the function stops its execution.
Now, for some reason, once I released the button, the function is executed one more time.
Below you can find the code I'm uing to create the button
self.sch_minus_button = tk.Button(self, text="S-", command=lambda: self.button_hold_callback('sch_minus'))
self.sch_minus_button.bind('<Button-1>', lambda event: self.button_hold_callback('sch_minus', event))
self.sch_minus_button.bind('<ButtonRelease-1>', self.button_stop_callback)
The button_hold_callback
is the function that manages the function that must cycle as soon as I've the button pressed
def button_hold_callback(self, *args):
global repeat
global last_call
try:
repeat = self.after(250, self.button_hold_callback, args[0], args[1])
except IndexError:
pass
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
if not last_call:
self.ser.write(self.message_to_send(args[0]))
logging.info('Sent message ' + str(self.message_to_send(args[0])))
# logging.info("write on serial")
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
button_stop_callback
instead block the cycle as soon as the button is released
def button_stop_callback(self, event):
last_call = True
for x in range(0,10):
self.ser.write(b'\x02\x56\xff\xff\xff\xff\xff\xff\x32\x35\x04')
time.sleep(0.01)
logging.debug("Written stop on the serial")
self.after_cancel(repeat)
For some reason, even the button_stop_callback
function is executed correctly, it seems that button_hold_callback
is executed one more time.
I found out this strange behavior with the logging as, as soon as I release the button I have another log that tells me anothe packet has been sent on the serial
2022-05-13 11:19:23,956 - root - INFO - created serial port (GUI.py:43)
2022-05-13 11:19:25,107 - root - INFO - Sent message b'\x02V\x81\x80\x80\x80\x80\x8095\x04' (GUI.py:84)
2022-05-13 11:19:25,373 - root - INFO - Sent message b'\x02V\x81\x80\x80\x80\x80\x8095\x04' (GUI.py:84)
2022-05-13 11:19:25,623 - root - INFO - Sent message b'\x02V\x81\x80\x80\x80\x80\x8095\x04' (GUI.py:84)
2022-05-13 11:19:25,888 - root - INFO - Sent message b'\x02V\x81\x80\x80\x80\x80\x8095\x04' (GUI.py:84)
2022-05-13 11:19:26,136 - root - DEBUG - Written stop on the serial (GUI.py:67)
2022-05-13 11:19:26,136 - root - INFO - Sent message b'\x02V\x81\x80\x80\x80\x80\x8095\x04' (GUI.py:84)
I've entered the code in debug mode and for some reason, everything works smooth if I breakpoint every step of my code. In production it has the issue stated below
Any idea?
Solution 1:[1]
So, I've found out a sort of workaround killing the serial once the release button callback is called and opening again with a try
except
once the function button_hold_callback
is called for the last time
def button_stop_callback(self, event):
self.ser.reset_output_buffer()
self.ser.write(b'\x02\x56\xff\xff\xff\xff\xff\xff\x32\x35\x04')
logging.debug("Written stop on the serial")
self.ser.close()
self.after_cancel(repeat)
# ---- CALLBACK MANTIENE L'ESECUZIONE DELLA FUNZIONE CON TASTO PREMUTO
def button_hold_callback(self, *args):
global repeat
try:
repeat = self.after(250, self.button_hold_callback, args[0], args[1])
except IndexError:
pass
try:
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
self.ser.write(self.message_to_send(args[0]))
logging.info('Sent message ' + str(self.message_to_send(args[0])))
# logging.info("write on serial")
self.ser.reset_input_buffer()
self.ser.reset_output_buffer()
# ---- SE FALLISCE PORTA SERIALE CHIUSA
except:
self.ser.open()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | NicoCaldo |