Tcl_AsyncDelete с помощью pynput и pyautogui - PullRequest
1 голос
/ 30 мая 2020

В упрощенной версии кода:

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.

Теперь я понимаю, что это происходит из-за проблем с обработкой потоков, а точнее из-за отсутствия указанной обработки. Я заметил, что если код работает без предупреждения () под объявлением класса; такой ошибки никогда не бывает.

Я полагаю, что понимаю, что это происходит из-за того, что pynput работает в другом потоке, чем был сделан первый вызов pyauto gui; однако, поскольку я больше не использую окна предупреждений, есть ли способ «должным образом закрыть» его в этом потоке и использовать его в другом? был бы очень признателен.

1 Ответ

0 голосов
/ 30 мая 2020

Кажется, мне удалось найти обходное решение. «Решение» в его нынешнем виде состоит в том, чтобы просто не использовать pyauto gui для этих запросов и создать уникальный ящик 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)
...