【tkinter-tk.after-tk.after_cancel】多个按键事件冲突 同时进行 无法正常中止

项目场景:

使用tkinter和pyinstaller 摄像头进行手势识别数字识别等功能封装为一个可执行程序


问题描述

使用tkinter 中Button中转换不同画面功能时 因为使用了tk.after这样的功能,且无法使用tk.after_cancel正常退出循环,会导致两个按键对应的事件同时进行,导致程序卡顿,甚至崩溃。

问题代码:

self.fingerCount_Button = tk.Button(self, text="fingerCount", command=self.fingerCount)
self.fingerCount_Button.pack (side='left')

self.start_Button = tk.Button(self, text="start", command=self.update)
self.fingerCount_Button.pack (side='left')

def fingerCount(self):
        # 读取当前帧
        ret, frame = self.video.read()
        
        if ret:
            # 检测手势
            img = self.detector.find_hands(frame, draw=True)
            
            # 中间的代码略了 写的屎山 就不让大家笑话了
            
                cv2.rectangle(img, (200, 0), (300, 100), (0, 255, 0), cv2.FILLED)
                cv2.putText(img, str(cnt), (200, 100), cv2.FONT_HERSHEY_DUPLEX, 5, (0, 0, 255))
            # 将 OpenCV 图像转换为 PIL 图像
            self.image = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
            
            # 在 Canvas 上显示图像
            self.canvas.image = ImageTk.PhotoImage(self.image)
            self.canvas.create_image(0, 0, anchor=tk.NW, image=self.canvas.image)
          self.after(self.delay, self.fingerCount)
 

 def update(self):
        # 读取当前帧
        ret, frame = self.video.read()
        
        if ret:
            # 将 OpenCV 图像转换为 PIL 图像
            self.image = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
            
            # 在 Canvas 上显示图像
            self.canvas.image = ImageTk.PhotoImage(self.image)
            self.canvas.create_image(0, 0, anchor=tk.NW, image=self.canvas.image)
        self.after(self.delay, self.update)


原因分析:

提示:这里填写问题的分析:我发现虽然点击了另一个按钮 但是没法停止前一个按钮带来的事件 试了普通的tk.after_cancel 无果


解决方案:

提示:这里填写该问题的具体解决方案:要实现同一时间只执行最新点击的按钮对应的事件,可以使用一个变量记录最后一次点击的按钮,并在每次点击按钮时更新这个变量,同时在每个事件执行时判断这个变量是否与当前按钮相同。

import tkinter as tk

class App:
    def __init__(self, master):
        self.master = master
        self.last_btn = None

        self.btn1 = tk.Button(self.master, text="Button 1", command=self.on_btn1_click)
        self.btn1.pack()

        self.btn2 = tk.Button(self.master, text="Button 2", command=self.on_btn2_click)
        self.btn2.pack()

    def on_btn1_click(self):
        self.last_btn = self.btn1
        self.do_something()

    def on_btn2_click(self):
        self.last_btn = self.btn2
        self.do_something()

    def do_something(self):
        if self.last_btn == self.btn1:
            print("Button 1 is clicked")
            # do something for Button 1

        elif self.last_btn == self.btn2:
            print("Button 2 is clicked")
            # do something for Button 2

        else:
            print("No button is clicked")

root = tk.Tk()
app = App(root)
root.mainloop()


创建了一个last_btn变量,它用于记录最后一次点击的按钮。在每个按钮的回调函数中,我们更新了last_btn变量,然后调用do_something()方法。在do_something()方法中,我们检查last_btn变量,并根据最后一次点击的按钮执行相应的操作。

这样实现的好处是可以避免同时执行多个事件,保证只有最新点击的按钮对应的事件在执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值