2015-02-02 3 views
2

나는 내 Raspberry Pi에서 실행되는 프로그램을 Python으로 작성하고 있습니다. 많은 사람들이 알고 있듯이, 라스베리는 다양한 입력 방법을받을 수 있습니다. 키보드와 다른 외부 입력 소스를 사용하고 있습니다. 이는 문맥 화에만 해당되며 문제 자체에 대해서는 중요하지 않습니다.키보드 입력 시간 초과 및 누르기없이 입력

내 프로그램에서 키보드 입력을 기다리고 잠시 동안 아무 것도없는 경우 건너 뛰고 다른 입력에서 입력을 찾습니다. 이를 위해 나는 다음과 같은 코드를 사용하고 있습니다 : I 전체 키보드없이 라즈베리 파이를 실행하기 위하여려고하고있다

import sys 
import time 
from select import select 

timeout = 4 
prompt = "Type any number from 0 up to 9" 
default = 99 

def input_with(prompt, timeout, default): 
    """Read an input from the user or timeout""" 
    print prompt, 
    sys.stdout.flush() 
    rlist, _, _ = select([sys.stdin], [], [], timeout) 
    if rlist: 
     s = int(sys.stdin.read().replace('\n','')) 
    else: 
     s = default 
     print s 
    return s 

을, 이것은 내가 리턴 키가없는 것을 의미합니다. 이 방법으로 키보드 입력의 유효성을 검사하는 것은 불가능합니다.

입력을 누르지 않고 입력 시간 제한을 유지하지 않고도 사용자 입력을받을 수 있는지 의문입니다.

나는 두 가지 이슈 (타임 아웃과 입력을 기다리지 않고 입력)에 대해 많은 주제를 보았지만 두 가지를 함께 사용하지 않았습니다.

미리 도움을 청하십시오!

+0

. 'stdin'은 이런 식으로 작동하지 않습니다. 어떻게 든 직접 tty를 캡처해야합니다. 로그인시 비밀번호를 입력 할 때 표준 입력을 무시하는 방법을 생각하십시오. – robert

+0

['timeout' 매개 변수를 받아들이 기 위해'readchar'을 적용하는 것이 간단해야합니다.] (https://github.com/magmax/python-readchar/blob/e020e152f1787074ef915e50f46c407ca8ac355b/readchar/readchar_linux.py). [대답] (http://stackoverflow.com/a/25342814/4279)에서 [파이썬은 사용자로부터 한 글자를 읽습니다.] (http://stackoverflow.com/q/510357/4279) – jfs

답변

0

필자가 원하는대로 (즉, 입력이 눌러지지 않았더라도) 대기중인 내용을 읽는 것은 간단하지 않다고 생각합니다.

제가 제안 할 수있는 최선의 제안은 눌렀을 때 각 캐릭터를 캡처하고 시간이 경과하면 호출하는 것입니다. 당신은 CBREAK에게 모드를 설정하여 문자 단위로 입력을 캡처 할 수 있습니다 : 흥미로운 질문이다 tty.setcbreak()

import sys 
from select import select 
import tty 
import termios 

try: 
    # more correct to use monotonic time where available ... 
    from time33 import clock_gettime 
    def time(): return clock_gettime(0) 
except ImportError: 
    # ... but plain old 'time' may be good enough if not. 
    from time import time 

timeout = 4 
prompt = "Type any number from 0 up to 9" 
default = 99 

def input_with(prompt, timeout, default): 
    """Read an input from the user or timeout""" 
    print prompt, 
    sys.stdout.flush() 

    # store terminal settings 
    old_settings = termios.tcgetattr(sys.stdin) 

    buff = '' 
    try:  
     tty.setcbreak(sys.stdin) # flush per-character 

     break_time = time() + timeout 

     while True: 

      rlist, _, _ = select([sys.stdin], [], [], break_time - time()) 
      if rlist: 
       c = sys.stdin.read(1) 

       # swallow CR (in case running on Windows) 
       if c == '\r': 
        continue 
       # newline EOL or EOF are also end of input 
       if c in ('\n', None, '\x04'): 
        break # newline is also end of input 
       buff += c 

       sys.stdout.write(c) # echo back 
       sys.stdout.flush() 

      else: # must have timed out 
       break 

    finally: 
     # put terminal back the way it was 
     termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_settings) 

    if buff: 
     return int(buff.replace('\n','').strip()) 
    else: 
     sys.stdout.write('%d' % default) 
     return default 
+0

'time.time()'을 다시 설정할 수 있습니다. Ubuntu에서 Python 2.7에 대한'time.monotonic()'구현 (https://gist.github.com/zed/5073409) – jfs

+1

당신은'eof'와'eol' 문자가 입력을 끝내도록 허용해야합니다 ('b '\ n''외에도)'stty -a'를보십시오. – jfs

+0

고마움, 나는 당신이'time.time '에 대해 무슨 뜻인지 모르겠다. 이런 이유로 믿을 수 없다는 암시인가? 나는 EOL이 라즈베리 파이에 대한 우려라고 생각하지 않습니다. 비 * nix 플랫폼에서는 지원할 수도 있지만 무시해야합니다. – robert