I have a paradox here. I'm using GetKeyState in order to retrieve the state of a giving vk_code. I've developed two functions to aid me in my task:
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.
The value of state
starts with 0, and then while the giving key is held down, it changes to -127, and then when I release, it changes to 1, and then while the key is held down again, it changes to -128, and then finally it gets back to 0.
When I use press_key inside a main loop, like this:
if __name__ == "__main__":
while True:
p_key = 80
if press_key(p_key):
print("P key was pressed.")
I get the following output when the giving key is pressed and released:
How can I get the key press only once if its inside a while loop? Like this:
But without breaking the whole loop.
Observation: I know I'm kinda of reinventing the wheel here (Since I could use PyHook or something), but I really want to know it! I want the "event" to be triggered only once inside the main-loop (Even if the key is kept held down), and I'm failing to grasp the logic to do it.
Well if you want to ensure that the press will only be registered once no matter how long they hold you can have a state variable to check if this is the first time that particular keypress is registered:
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
This won't hold up the loop, and it allows you the press the key as rapidly as your keyboard will allow; the other method only allows you to press every 300 ms and blocks the loop for that long.