Пишущая машинка pyautogui не перестанет печатать

Я пишу скрипт так, что когда пользователь нажимает Shift+P, будет введена текстовая строка. Он работает, и когда я нажимаю Shift+P, он вводит текст, но не перестает вводить текст. Я предполагаю, что это то, что я сделал и не вижу. Почему это продолжает зацикливаться и печатать? Как мне заставить его остановиться после того, как он закончит набирать «Hello, World» один раз?

from pynput import keyboard
import pyautogui as pg

COMBINATIONS = [
        {keyboard.Key.shift, keyboard.KeyCode(char="p")},
        {keyboard.Key.shift, keyboard.KeyCode(char="P")}
        ]

current = set()

def execute():
    pg.press("backspace")
    pg.typewrite("Hello, World\n", 0.25)

def on_press(key):
    if any ([key in COMBO for COMBO in COMBINATIONS]):
        current.add(key)
        if any(all(k in current for k in COMBO) for COMBO in COMBINATIONS):
            execute()

def on_release(key):
    if any([key in COMBO for COMBO in COMBINATIONS]):
        current.remove(key)

with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
    listener.join()

person Derek    schedule 11.01.2019    source источник


Ответы (1)


То, что здесь происходит, сложно. py.typewrite вызывает обработчик сигнала on_press. Но он не просто вызывает его... он вызывает on_press с помощью keyboard.Key.Shift из-за заглавной буквы H (shift-h) и восклицательного знака (shift-1) в Hello World!

Во-первых, вы можете увидеть разницу, если вы отправляете hello world, а не Hello World! В версии с строчными буквами пишущая машинка никогда не отправляет клавишу Shift, поэтому мы не запускаем on_press и она не думает, о, у нас есть p и сдвиг вниз , нам нужно снова запустить Hello World, как только мы закончим.

Решение состоит в том, чтобы сделать глобальную переменную process_keystrokes и отключить ее при запуске execute(). Также кажется хорошей идеей очистить набор клавиш, поскольку мы не знаем, что пользователь может/может сделать, когда пишущая машинка отправляет нажатия клавиш.

from pynput import keyboard
import pyautogui as pg

COMBINATIONS = [
        {keyboard.Key.shift, keyboard.KeyCode(char="p")},
        {keyboard.Key.shift, keyboard.KeyCode(char="P")}
        ]

current = set()

pg.FAILSAFE = True # it is by default, but just to note we can go to the very upper left to stop the code

process_keystrokes = True

def execute():
    global process_keystrokes
    process_keystrokes = False # set process_keystrokes to false while saying HELLO WORLD
    pg.press("backspace")
    pg.typewrite("#Hello, World\n", 1)
    process_keystrokes = True

def on_press(key):
    if not process_keystrokes: return
    if any ([key in COMBO for COMBO in COMBINATIONS]):
        current.add(key)
        print("Added", key)
        if any(all(k in current for k in COMBO) for COMBO in COMBINATIONS):
            execute()
            current.clear() # note this may potentially not track if we held the shift key down and hit P again. But unfortunately typewriter can stomp all over the SHIFT, and I don't know what to do. There seems to be no way to tell if the user let go of the shift key, so it seems safest to clear all possible keystrokes.

def on_release(key):
    if not process_keystrokes: return
    if any([key in COMBO for COMBO in COMBINATIONS]):
        print("Removed", key)
        current.remove(key)

with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
    listener.join()
person aschultz    schedule 08.08.2019