2009-08-11 6 views
2

os.system ("clear")을 사용하여 화면을 지속적으로 업데이트하고 몇 초마다 다른 텍스트 메시지를 인쇄하는 while 루프를 작성하려고합니다. 루프 중에 사용자 입력을 얻으려면 어떻게해야합니까? raw_input()은 잠깐 멈추고 기다리는데, 이는 내가 원하는 기능이 아닙니다.차단하지 않고 while 루프에서 사용자 입력을 얻는 방법

import os 
import time 

string = "the fox jumped over the lazy dog" 
words = string.split(" ") 
i = 0 

while 1: 
    os.system("clear") 
    print words[i] 
    time.sleep(1) 
    i += 1 
    i = i%len(words) 

중간에 'q'또는 'p'를 눌러 종료하고 일시 중지 할 수 있습니다.

+0

관련없는에서 큐의 이름을 변경합니다. – EOL

+1

@EOL :'string.split()'과'string.split ("")'은 같은 것이 아닙니다. – SilentGhost

+0

멋지다, 1 명의 담당자가오고, asling하고, 그 다음가는 것을 가지고있는 사람. 그거 사랑해. –

답변

9

Python의 표준 라이브러리에있는 select 모듈은 표준 입력이 FD 0인데, 터미널을 "raw"("cooked"모드와 반대) 모드로 두어야 할 수도 있지만, unix-y 시스템에서는 줄 끝으로 끝나는 전체 줄과 반대로 단일 키 누르기를 얻을 수 있습니다. Windows의 경우 msvcrt도 Python 표준 라이브러리에서 필요한 모든 기능을 제공합니다. msvcrt.kbhit()은 어떤 키 스트로크가 보류 중인지 알려주고, 그렇다면 msvcrt.getch()이 어떤 문자인지 알려줍니다.

3

유닉스와 윈도우 모두에서 찾고있는 기능을 제공하는 one of the recipes을 확인할 수도 있습니다.

1

당신은 스레드, 여기에 기본 예제이라고 할 수 있습니다 : 평소처럼

import threading, os, time, itertools, Queue 

# setting a cross platform getch like function 
# thks to the Python Cookbook 
# why isn't standard on this battery included language ? 
try : # on windows 
    from msvcrt import getch 
except ImportError : # on unix like systems 
    import sys, tty, termios 
    def getch() : 
     fd = sys.stdin.fileno() 
     old_settings = termios.tcgetattr(fd) 
     try : 
      tty.setraw(fd) 
      ch = sys.stdin.read(1) 
     finally : 
      termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) 
     return ch 

# this will allow us to communicate between the two threads 
# Queue is a FIFO list, the param is the size limit, 0 for infinite 
commands = Queue.Queue(0) 

# the thread reading the command from the user input  
def control(commands) : 

    while 1 : 

     command = getch() 
     commands.put(command) # put the command in the queue so the other thread can read it 

     # don't forget to quit here as well, or you will have memory leaks 
     if command == "q" : 
      break 


# your function displaying the words in an infinite loop 
def display(commands): 

    string = "the fox jumped over the lazy dog" 
    words = string.split(" ") 
    pause = False 
    command = "" 

    # we create an infinite generator from you list 
    # much better than using indices 
    word_list = itertools.cycle(words) 

    # BTW, in Python itertools is your best friend 

    while 1 : 

     # parsing the command queue 
     try: 
      # false means "do not block the thread if the queue is empty" 
      # a second parameter can set a millisecond time out 
      command = commands.get(False) 
     except Queue.Empty, e: 
      command = "" 

     # behave according to the command 
     if command == "q" : 
      break 

     if command == "p" : 
      pause = True 

     if command == "r" : 
      pause = False 

     # if pause is set to off, then print the word 
     # your initial code, rewritten with a generator 
     if not pause : 
      os.system("clear") 
      print word_list.next() # getting the next item from the infinite generator 

     # wait anyway for a second, you can tweak that 
     time.sleep(1) 



# then start the two threads 
displayer = threading.Thread(None, # always to None since the ThreadGroup class is not implemented yet 
          display, # the function the thread will run 
          None, # doo, don't remember and too lazy to look in the doc 
          (commands,), # *args to pass to the function 
          {}) # **kwargs to pass to the function 

controler = threading.Thread(None, control, None, (commands,), {}) 

if __name__ == "__main__" : 
    displayer.start() 
    controler.start() 

, 스레드를 사용하는 것이 까다 롭다, 그래서 당신은 당신이 코딩하기 전에 무엇을 이해해야합니다.

경고 :) (해당 사항 String.split주의 더 간단하게 ("") 사항 String.split를 대체 할 수 대기열이 질문에 파이썬 3

관련 문제