Вопрос-Ответ

How to detect key presses?

Как определить нажатия клавиш?

Я создаю программу типа секундомера на Python, и я хотел бы знать, как определить, нажата ли клавиша (например, p для паузы и s для остановки), и мне бы не хотелось, чтобы это было что-то вроде raw_input, которое ожидает ввода пользователя перед продолжением выполнения.

Кто-нибудь знает, как это сделать в цикле while?

Я хотел бы сделать это кроссплатформенным, но, если это невозможно, то моей основной целью разработки является Linux.

Переведено автоматически
Ответ 1

В Python есть модуль keyboard со многими функциями. Установите его, возможно, с помощью этой команды:

pip3 install keyboard

Затем используйте это в коде типа:

import keyboard  # using module keyboard
while True: # making a loop
try: # used try so that if user pressed other than the given key error will not be shown
if keyboard.is_pressed('q'): # if key 'q' is pressed
print('You Pressed A Key!')
break # finishing the loop
except:
break # if user pressed a key other than the given key the loop will break
Ответ 2

Для тех, кто работает в Windows и изо всех сил пытался найти рабочий ответ, вот мой: pynput.

Вот pynput официальный пример исходного кода "Мониторинга клавиатуры":

from pynput.keyboard import Key, Listener

def on_press(key):
print('{0} pressed'.format(
key))

def on_release(key):
print('{0} release'.format(
key))
if key == Key.esc:
# Stop listener
return False

# Collect events until released
with Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()

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

Маркус фон Броуди выделил потенциальную проблему, которая заключается в следующем: этот ответ не требует, чтобы вы находились в текущем окне, чтобы этот скрипт был активирован, решением для Windows было бы:

from win32gui import GetWindowText, GetForegroundWindow
current_window = (GetWindowText(GetForegroundWindow()))
desired_window_name = "Stopwatch" #Whatever the name of your window should be

#Infinite loops are dangerous.
while True: #Don't rely on this line of code too much and make sure to adapt this to your project.
if current_window == desired_window_name:

with Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
Ответ 3

More things can be done with keyboard module.
You can install this module using pip install keyboard
Here are some of the methods:


Method #1:

Using the function read_key():

import keyboard

while True:
if keyboard.read_key() == "p":
print("You pressed p")
break

This is gonna break the loop as the key p is pressed.


Method #2:

Using function wait:

import keyboard

keyboard.wait("p")
print("You pressed p")

It will wait for you to press p and continue the code as it is pressed.


Метод # 3:

Использование функции on_press_key:

import keyboard

keyboard.on_press_key("p", lambda _:print("You pressed p"))

Для этого нужна функция обратного вызова. Я использовал _ потому что функция keyboard возвращает событие keyboard этой функции.

После выполнения функция будет запущена при нажатии клавиши. Вы можете остановить все перехваты, выполнив эту строку:

keyboard.unhook_all()

Метод # 4:

На этот метод вроде как уже ответил пользователь8167727, но я не согласен с созданным ими кодом. Он будет использовать функциюis_pressed, но другим способом:

import keyboard

while True:
if keyboard.is_pressed("p"):
print("You pressed p")
break

Это разорвет цикл при нажатии p.


Метод # 5:

Вы также можете использовать keyboard.record. Он записывает все нажатые и отпущенные клавиши до тех пор, пока вы не нажмете escape клавишу или ту, которую вы определили в until аргументе, и возвращает список keyboard.KeyboardEvent элементов.

import keyboard

keyboard.record(until="p")
print("You pressed p")

Примечания:


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

  • keyboard требуется root в Linux

Ответ 4

Как упоминает OP о raw_input - это означает, что ему нужно решение cli. Linux: curses - это то, что вы хотите (Windows PDCurses). Curses - это графический API для программного обеспечения cli, с помощью которого можно добиться большего, чем просто обнаруживать ключевые события.

Этот код будет определять клавиши до тех пор, пока не будет нажата новая строка.

import curses
import os

def main(win):
win.nodelay(True)
key=""
win.clear()
win.addstr("Detected key:")
while 1:
try:
key = win.getkey()
win.clear()
win.addstr("Detected key:")
win.addstr(str(key))
if key == os.linesep:
break
except Exception as e:
# No input
pass

curses.wrapper(main)
python python-2.7