파이썬에서 키보드 폴링 (키 누르기 감지)
콘솔 Python 앱에서 키보드를 어떻게 폴링 할 수 있습니까? 특히, 다른 많은 I / O 활동 (소켓 선택, 직렬 포트 액세스 등) 중에 이와 유사한 작업을하고 싶습니다.
while 1:
# doing amazing pythonic embedded stuff
# ...
# periodically do a non-blocking check to see if
# we are being told to do something else
x = keyboard.read(1000, timeout = 0)
if len(x):
# ok, some key got pressed
# do something
Windows에서 이것을 수행하는 올바른 파이썬 방법은 무엇입니까? 또한 필수는 아니지만 Linux 로의 이식성은 나쁘지 않습니다.
표준 접근 방식은 선택 모듈 을 사용하는 것 입니다.
그러나 이것은 Windows에서는 작동하지 않습니다. 이를 위해 msvcrt 모듈의 키보드 폴링을 사용할 수 있습니다 .
종종이 작업은 여러 스레드 ( "감시"되는 장치 당 하나씩)와 장치에 의해 중단되어야하는 백그라운드 프로세스로 수행됩니다.
import sys
import select
def heardEnter():
i,o,e = select.select([sys.stdin],[],[],0.0001)
for s in i:
if s == sys.stdin:
input = sys.stdin.readline()
return True
return False
curses 모듈을 사용하는 솔루션입니다. 누른 각 키에 해당하는 숫자 값 인쇄 :
import curses
def main(stdscr):
# do not wait for input when calling getch
stdscr.nodelay(1)
while True:
# get keyboard input, returns -1 if none available
c = stdscr.getch()
if c != -1:
# print numeric value
stdscr.addstr(str(c) + ' ')
stdscr.refresh()
# return curser to start position
stdscr.move(0, 0)
if __name__ == '__main__':
curses.wrapper(main)
좋아요, 댓글에 내 솔루션을 게시하려는 시도가 실패했기 때문에 여기에 제가 말하려는 내용이 있습니다. 다음 코드를 사용하여 네이티브 Python에서 원하는 것을 정확하게 수행 할 수 있습니다 (다른 곳은 아니지만 Windows에서).
import msvcrt
def kbfunc():
x = msvcrt.kbhit()
if x:
ret = ord(msvcrt.getch())
else:
ret = 0
return ret
이 답변 중 어느 것도 나를 위해 잘 작동하지 않았습니다. 이 패키지 pynput은 내가 필요한 것을 정확히 수행합니다.
https://pypi.python.org/pypi/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()
파이 게임 이 아이디어를 훔치기 위해 이것을 어떻게 처리 하는지 볼 수 있습니다 .
댓글에서 :
import msvcrt # built-in module
def kbfunc():
return ord(msvcrt.getch()) if msvcrt.kbhit() else 0
도와 주셔서 감사합니다. 결국 PyKeyboardAccess.dll이라는 C DLL을 작성하고 crt conio 함수에 액세스하여이 루틴을 내보냈습니다.
#include <conio.h>
int kb_inkey () {
int rc;
int key;
key = _kbhit();
if (key == 0) {
rc = 0;
} else {
rc = _getch();
}
return rc;
}
그리고 ctypes 모듈 (python 2.5에 내장 됨)을 사용하여 파이썬에서 액세스합니다.
import ctypes
import time
#
# first, load the DLL
#
try:
kblib = ctypes.CDLL("PyKeyboardAccess.dll")
except:
raise ("Error Loading PyKeyboardAccess.dll")
#
# now, find our function
#
try:
kbfunc = kblib.kb_inkey
except:
raise ("Could not find the kb_inkey function in the dll!")
#
# Ok, now let's demo the capability
#
while 1:
x = kbfunc()
if x != 0:
print "Got key: %d" % x
else:
time.sleep(.01)
나는 키 누름을 확인하기 위해 이것을 사용하고 있으며 훨씬 더 간단해질 수 없습니다.
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
import curses, time
def main(stdscr):
"""checking for keypress"""
stdscr.nodelay(True) # do not wait for input when calling getch
return stdscr.getch()
while True:
print("key:", curses.wrapper(main)) # prints: 'key: 97' for 'a' pressed
# '-1' on no presses
time.sleep(1)
While curses is not working on windows, there is a 'unicurses' version, supposedly working on Linux, Windows, Mac but I could not get this to work
I've come across a cross-platform implementation of kbhit
at http://home.wlu.edu/~levys/software/kbhit.py (made edits to remove irrelevant code):
import os
if os.name == 'nt':
import msvcrt
else:
import sys, select
def kbhit():
''' Returns True if a keypress is waiting to be read in stdin, False otherwise.
'''
if os.name == 'nt':
return msvcrt.kbhit()
else:
dr,dw,de = select.select([sys.stdin], [], [], 0)
return dr != []
Make sure to read()
the waiting character(s) -- the function will keep returning True
until you do!
If you combine time.sleep, threading.Thread, and sys.stdin.read you can easily wait for a specified amount of time for input and then continue, also this should be cross-platform compatible.
t = threading.Thread(target=sys.stdin.read(1) args=(1,))
t.start()
time.sleep(5)
t.join()
You could also place this into a function like so
def timed_getch(self, bytes=1, timeout=1):
t = threading.Thread(target=sys.stdin.read, args=(bytes,))
t.start()
time.sleep(timeout)
t.join()
del t
Although this will not return anything so instead you should use the multiprocessing pool module you can find that here: how to get the return value from a thread in python?
참고URL : https://stackoverflow.com/questions/292095/polling-the-keyboard-detect-a-keypress-in-python
'IT Share you' 카테고리의 다른 글
터미널 프롬프트없이 IPython 세션에서 복사하는 방법 (0) | 2020.12.04 |
---|---|
IE11-CSS 변수에 대한 polyfill / 스크립트가 있습니까? (0) | 2020.12.04 |
svn : 로컬 커밋 (0) | 2020.12.04 |
WPF에서 컨트롤이 사용자에게 표시되는지 여부를 어떻게 확인할 수 있습니까? (0) | 2020.12.04 |
Control.Applicative를 사용하여 더 깨끗한 Haskell을 작성하는 방법은 무엇입니까? (0) | 2020.12.04 |