tkinter 在使用 after_cancel() 之后再执行一次函数

tkinter executes one more time the function after using after_cancel()

所以我有一个按钮,只要按下按钮,它就会以循环方式执行一个功能。一旦释放,函数就会停止执行。

现在,由于某种原因,一旦我松开按钮,该功能就会再次执行。

您可以在下面找到我用来创建按钮的代码

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)

button_hold_callback 是管理按下按钮后必须循环的函数的函数

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 而不是在释放按钮后立即阻止循环

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)

不知为什么,连button_stop_callback函数都执行正确了,好像button_hold_callback又执行了一次

我在日志中发现了这种奇怪的行为,因为一旦我松开按钮,我就会有另一个日志告诉我另一个数据包已经发送到串行

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)

我在调试模式下输入代码,出于某种原因,如果我在代码的每一步都设置断点,一切都会顺利进行。在生产中它有下面所述的问题

有什么想法吗?

所以,我找到了一种变通方法,一旦调用释放按钮回调并再次打开 try except 一旦函数 button_hold_callback最后一次打电话

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()