1

我正在编写一个脚本,当用户按下 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()
4

1 回答 1

1

这里发生的事情很棘手。py.typewrite 调用 on_press 信号处理程序。但它不只是调用它......它使用keyboard.Key.Shift调用on_press,因为Hello World中的大写H(shift-h)和感叹号(shift-1)!

首先,如果你发送hello world和不发送,你可以看到区别Hello World!在小写版本中,打字机从不发送 shift 键,所以我们不运行 on_press 并且它不会认为,哦,我们有 p 和 shift down,我们完成后需要再次运行 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()
于 2019-08-08T02:26:31.507 回答