Отследить отпускание клавиши python

Вопрос простой. Я пишу свою функцию отлова события с клавишами. Решил написать функцию, которая срабатывает ОДИН РАЗ после нажатия и отпускания. Т.е. она возвращает False, пока клавиша отпущена, пока она нажата. Но вернет True, как только клавишу отпустили после нажатия. Но лишь 1 раз. Потом снова False.

Сделал набросок функции:

import win32api as wapi
from random import randint as rd

RC_KEY_STATE = False

def isKeyPressed(key):

        state = wapi.GetKeyState(key)
        if state == -127 or state == -128:
            return True
        else:
            return False

def wasKeyPressed(key):
        
        if isKeyPressed(key):

            RC_KEY_STATE = True
            return False

        else:

            if RC_KEY_STATE:
                    
                RC_KEY_STATE = False
                return True
                
            return False
while True:
    print(wasKeyPressed(0x01))

Я запускаю эту функцию в бесконечном цикле. В принципе, эта функция очень даже работает. Но лишь для одной кнопки. Если я попытаюсь так прослушивать несколько кнопок, то работа будет некорректной по вполне понятным причинам - переключатель RC_KEY_STATE один.

Вопрос: как мне отследить ОТПУСКАНИЕ клавиши после нажатия? Не так, чтобы функция выполнялась все время, пока клавиша нажата/отжата, а только в момент отпускания. Правильный ли путь я выбрал или все гораздо сложнее? Есть ли какой-либо модуль, позволяющий это сделать? Может в win api есть такое? (не нашел)

Заранее спасибо


Ответы (2 шт):

Автор решения: Kers

Попробуйте через keybord:

import keyboard


def press_key(key):
    k = key.event_type
    if k == "down":
        print("ВНИЗ!", key.name)
    if k == "up":
        print("ВВЕРХ!", key.name)


keyboard.hook(press_key)
keyboard.wait()
→ Ссылка
Автор решения: CSharpLooser

Относительное решение все таки нашел. Изначально моя ошибка была в том, что я делил ситуацию на черное и белое. Ошибка изначально была в мышлении, что кнопка может быть либо нажата, либо отжата (False/True), а другого не дано. Нужно было использовать не False/True, а ID кнопок для сравнения, что дает куда больше возможностей.

Код:

import win32api as wapi
from random import randint as rd

RC_LAST_KEY = -1

def isKeyPressed(key):

    state = wapi.GetKeyState(key)
    if state == -127 or state == -128:
        return True
    else:
        return False

def wasKeyReleased(key):

    global RC_LAST_KEY
        
    if isKeyPressed(key) and RC_LAST_KEY == -1:

        RC_LAST_KEY = key

    elif not isKeyPressed(key) and RC_LAST_KEY == key:

        RC_LAST_KEY = -1
        return True

    return False

Не обращайте внимания на global - эти функции у меня в модуле. По-другому доступ к переменной уровня модуля получить нельзя - причуда Python, о которой я узнал не так давно, когда мой скрипт умирал по неадекватным причинам.

У данного способа есть свои недостатки, вроде не совсем корректной работы, когда нажимаются и отжимаются две проверяемые клавиши поочередно, но, в целом, результат меня устраивает.

Если есть более корректные способы и более удобные - я с радостью посмотрел бы.

→ Ссылка