Tcl_AsyncDelete 使用 pynput 和 pyautogui

Tcl_AsyncDelete with pynput and pyautogui

在简化版的代码中:

from pynput import keyboard
import time
import pyautogui


class Test:
    def __init__(self):
        self.paused = False

    def on_activate(self):
        if self.paused:
            pyautogui.alert(text='was paused', title='title', button='button')
            self.paused = False
        elif self.paused is False:
            pyautogui.alert(text='was not paused', title='title', button='button')
            self.paused = True


test = Test()
pyautogui.alert(text='test', title='title', button='button')
hotkey = keyboard.GlobalHotKeys({
    '<ctrl>+a': test.on_activate
})
hotkey.start()

while True:
    time.sleep(1)

我会得到错误 Tcl_AsyncDelete: async handler deleted by the wrong thread

现在我明白这是由于处理线程的问题,或者更确切地说是缺乏上述处理。我注意到如果代码在 class 声明下方没有 alert() 的情况下运行;从来没有任何这样的错误。

我相信我知道这是来自 pynput 在另一个线程上工作,而不是第一次调用 pyautogui;但是,由于我不再使用 for 警告框,有没有办法在该线程中 "properly close" 它并在另一个线程中操作它?

我有点不知所措,如有任何意见或帮助,我们将不胜感激。

我似乎找到了解决方法。 'solution' 代表它只是不对这些提示使用 pyautogui,并在每次调用时为这些侦听器调用构建一个独特的 tkinter 框。我得到的结束代码是:

from pynput import keyboard
import time
import pyautogui
import tkinter as tk
import tkinter.messagebox as messagebox


def send_alert(text, title):
    root = tk.Tk()
    root.withdraw()
    messagebox.showinfo(title, text)
    root.destroy()


class Test:
    def __init__(self):
        self.paused = False

    def on_activate(self):
        if self.paused:
            send_alert('paused', 'title')
            self.paused = False
        elif self.paused is False:
            send_alert('not paused', 'title')
            self.paused = True


test = Test()
pyautogui.alert(text='test', title='title', button='button')

hotkey = keyboard.GlobalHotKeys({
    '<ctrl>+a': test.on_activate
})
hotkey.start()

while True:
    time.sleep(1)