如何 "execute" 在 while 循环中只按下一个键? (PyWin32)

How do I "execute" only one key press inside a while loop? (PyWin32)

我这里有个悖论。我正在使用 GetKeyState 来检索捐赠 vk_code 的状态。我开发了两个功能来帮助我完成任务:

import win32api

def get_key_state(vk_code):
    state = int(win32api.GetKeyState(vk_code))
    if state == 1 or state == -127:
        return 1 # Key is on.
    elif state == 0 or state == -128:
        return 0 # Key is off.

def press_key(vk_code):
    state = int(win32api.GetKeyState(vk_code))
    if state == -127 or state == -128:
        return 1 # Key was pressed.
    else:
        return 0 # Key was released.

state的值从0开始,然后在按住giving键的时候变成-127,然后松开的时候变成1,然后在按住的时候变成-127再次按住,变为-128,最后又回到0。

当我在主循环中使用 press_key 时,像这样:

if __name__ == "__main__":

    while True:
        p_key = 80
        if press_key(p_key):
            print("P key was pressed.")

按下并释放给定键时,我得到以下输出:

如果它在 while 循环中,我怎样才能让按键 只按下一次 ?像这样:

但不会破坏整个循环。

观察:我知道我有点在重新发明轮子(因为我可以使用 PyHook 或其他东西),但我真的很想知道它!我希望 "event" 在主循环中仅被触发一次(即使一直按住该键),但我没有掌握执行此操作的逻辑。

事实证明,解决方案非常明显。我已经使用 time.sleep().

完美解决了这个问题
import win32api
import time

HUMAN_KEYPRESS_TIME = 0.3

def press_key(vk_code):
    state = int(win32api.GetKeyState(vk_code))
    if state == -127 or state == -128:
        return 1 # Key was pressed.
    else:
        return 0 # Key was released.

if __name__ == "__main__":

    while True:
        p_key = 80
        if press_key(p_key):
            print("P key was pressed.")
            time.sleep(HUMAN_KEYPRESS_TIME)

我得出的结论是无法在按住键的同时"execute only once",然后我意识到答案是时间。如果我希望代码块仅通过一次按键执行一次,我只需要在每次物理按键之间的时间间隔内让整个应用程序休眠。

好吧,如果你想确保按键只被注册一次,无论它们保持多久,你可以有一个状态变量来检查这是否是第一次注册特定按键:

import win32api

HUMAN_KEYPRESS_TIME = 0.3

def press_key(vk_code):
    state = int(win32api.GetKeyState(vk_code))
    if state == -127 or state == -128:
        return 1
    else:
        return 0

keyDown = False
if __name__ == "__main__":
    firstPress = True
    while True:
        p_key = 80
        if press_key(p_key):
            if firstPress:
                firstPress = False
                print("P key was pressed.")
        else:
            firstPress = True

这不会阻止循环,它允许您在键盘允许的范围内尽可能快地按下按键;另一种方法只允许您每 300 毫秒按下一次并在那么长的时间内阻止循环。