2016-10-11 2 views
2

스레드가 실행되어 회전하는 커서를 표시하는 다양한 시간 동안 실행되는 코드가 있습니다. 코드가 끝나면 출력으로 출력하고 이벤트를 설정하면 커서가 멈 춥니 다. 그러나 이것은 화면에 인쇄 된 마지막 문자를 남겨 둡니다. 나는 이것을 제거하고 싶습니다.화면에서 인쇄 된 행을 삭제합니다.

def spinning_cursor(event):              
    for j in itertools.cycle('/-\|'):           
     if not event.is_set():             
      sys.stdout.write(j)             
      sys.stdout.flush()          
      time.sleep(0.1)              
      sys.stdout.write('\b')            
     else: 
      #sys.stdout.write('\b')                             
      return 

은 내가 화면에 표시되는 것은 다음과 같습니다

paul# 
Writing file... 
/
info: file has been written 
paul# 

내가 이벤트가 설정되어있을 때 / 사라지게하고 싶습니다. 위의 줄을 주석 처리하지 않고 반환하기 전에 sys.stdout.write('\b') 시도했지만이 코드는 주 스레드의 후속 인쇄 후 실행할 것으로 보이며 아무것도 삭제합니다. 왜 이런거야? else으로 돌아 오기 전에 sys.stdout.write('TEST')을 사용하는 좀 더 분명한 예입니다.

paul# 
Writing file... 
/
info: file has been written 
TESTpaul# 

나는 메인 스레드에 인쇄하기 전에 한 줄 위로 이동을 통해 해결책을 발견하지만, 많은 코드 경로를 있기 때문에이 지저분 :

여기
CURSOR_UP_ONE = '\x1b[1A'                       
sys.stdout.write(CURSOR_UP_ONE) 

는 회전 커서를 호출하는 방법입니다. 어떤 아이디어?

def copy():                                                             
    processing_flag = Event()                                                               
    Thread(target = spinning_cursor, kwargs = {'event': processing_flag}).start()                                                                                                                
    try:                                                                   
     ...                                                             
    except: 
     ...                                                                
    finally:                                                                  
     processing_flag.set()                                                              
+0

은 역시'\의 b'를 작성 후'sys.stdout.flush()'ING보십시오. – alexpeits

+0

@ Alex.P 이걸 시험해 보았지만 행운은 없었어, 고마워. – Paul

+0

'sys.stdout' 대신에 스피너에'sys.stderr'을 사용하면 어떻게 될까요? 아마'sys.stderr.write ('\ b')'는 다른 스트림에 쓰여졌 기 때문에 작동 할 것입니다. – nauer

답변

1

문제는 메인 쓰레드가 spinning_cursor 한 대기하지 않습니다. 그래서 여기에 무슨이다 (나는 그것을 재현 할 수) :

main          | spinning 
--------------------------------------------------------------------------- 
starts spinning thread     | starts 
works         | displays a *spinning* cursor 
ends working        | == 
sets event        | waits for running time 
continues and writes to stdout (*)  | may be still waiting ... 
...          | writes its last backspace and exits (*) 

(*) I도 회전하는 스레드가 쓸 수 전에 finaly 블록 write 발생하는과 표준 출력에 쓰는 메인 스레드가 시작 것을 증명할 수 thread의 마지막에 인쇄 가능한 문자를 기입하는 것으로 써 마지막 백 스페이스. 그 성격은 너무 늦게 인쇄되었습니다.

어떻게 해결하는 방법 : 단순히 joinspinning_cursor 스레드 :

def copy(): 
    processing_flag = Event() 
    t = Thread(target = spinning_cursor, kwargs = {'event': processing_flag}) 
    t.start() 
    try: 
     ... 
    except: 
     ... 
    finally: 
     processing_flag.set() 
     t.join() # waits for the thread to output its last backspace 
+0

위대한 답변과 제가 대신 해킹을 구현할 것입니다. 고마워요! – Paul

관련 문제