회전하는 명령 줄 커서를 만드는 방법은 무엇입니까?
Python을 사용하여 터미널에서 회전하는 커서를 인쇄하는 방법이 있습니까?
이와 같이 터미널이 \ b를 처리한다고 가정합니다.
import sys
import time
def spinning_cursor():
while True:
for cursor in '|/-\\':
yield cursor
spinner = spinning_cursor()
for _ in range(50):
sys.stdout.write(next(spinner))
sys.stdout.flush()
time.sleep(0.1)
sys.stdout.write('\b')
사용하기 쉬운 API (별도의 스레드에서 스피너를 실행합니다) :
import sys
import time
import threading
class Spinner:
busy = False
delay = 0.1
@staticmethod
def spinning_cursor():
while 1:
for cursor in '|/-\\': yield cursor
def __init__(self, delay=None):
self.spinner_generator = self.spinning_cursor()
if delay and float(delay): self.delay = delay
def spinner_task(self):
while self.busy:
sys.stdout.write(next(self.spinner_generator))
sys.stdout.flush()
time.sleep(self.delay)
sys.stdout.write('\b')
sys.stdout.flush()
def __enter__(self):
self.busy = True
threading.Thread(target=self.spinner_task).start()
def __exit__(self, exception, value, tb):
self.busy = False
time.sleep(self.delay)
if exception is not None:
return False
이제 with
코드의 어느 곳에서나 블록 에서 사용하십시오 .
with Spinner():
# ... some long-running operations
# time.sleep(3)
좋은 파이썬적인 방법은 itertools.cycle을 사용하는 것입니다.
import itertools, sys
spinner = itertools.cycle(['-', '/', '|', '\\'])
while True:
sys.stdout.write(spinner.next()) # write the next character
sys.stdout.flush() # flush stdout buffer (actual character display)
sys.stdout.write('\b') # erase the last written char
또한 http://www.interclasse.com/scripts/spin.php 와 같이 긴 함수 호출 중에 스레딩을 사용하여 스피너를 표시 할 수 있습니다 .
해결책 :
import sys
import time
print "processing...\\",
syms = ['\\', '|', '/', '-']
bs = '\b'
for _ in range(10):
for sym in syms:
sys.stdout.write("\b%s" % sym)
sys.stdout.flush()
time.sleep(.5)
핵심은 백 스페이스 문자 '\ b'를 사용하고 stdout을 플러시하는 것입니다.
물론 가능합니다. 그것은 백 스페이스 문자 (인쇄 단지 질문 \b
그것의 회전과 같은 "커서"모양을 만드는 것이 네 문자 사이) ( -
, \
, |
, /
).
curses 모듈. addstr () 및 addch () 함수를 살펴 보겠습니다. 그래도 사용하지 않았습니다.
고급 콘솔 조작을 위해 유닉스에서는 curses python module 을 사용할 수 있으며 Windows에서는 curses 라이브러리와 동등한 기능을 제공하는 WConio 를 사용할 수 있습니다 .
멋진 progressbar
모듈 -http : //code.google.com/p/python-progressbar/ 사용 RotatingMarker
.
#!/usr/bin/env python
import sys
chars = '|/-\\'
for i in xrange(1,1000):
for c in chars:
sys.stdout.write(c)
sys.stdout.write('\b')
sys.stdout.flush()
주의 사항 : 내 경험상 이것은 모든 터미널에서 작동하지 않습니다. Unix / Linux에서이 작업을 수행하는 더 강력한 방법은 Windows에서는 작동하지 않는 curses 모듈 을 사용하는 것 입니다. 백그라운드에서 진행되는 실제 처리로 속도를 늦추고 싶을 것입니다.
import sys
def DrowWaitCursor(self, counter):
if counter % 4 == 0:
print("/",end = "")
elif counter % 4 == 1:
print("-",end = "")
elif counter % 4 == 2:
print("\\",end = "")
elif counter % 4 == 3:
print("|",end = "")
sys.stdout.flush()
sys.stdout.write('\b')
매개 변수가있는 함수를 사용하는 또 다른 솔루션이 될 수도 있습니다.
여기 있습니다-간단하고 명확합니다.
import sys
import time
idx = 0
cursor = ['|','/','-','\\'] #frames of an animated cursor
while True:
sys.stdout.write(cursor[idx])
sys.stdout.write('\b')
idx = idx + 1
if idx > 3:
idx = 0
time.sleep(.1)
조잡하지만 간단한 솔루션 :
import sys
import time
cursor = ['|','/','-','\\']
for count in range(0,1000):
sys.stdout.write('\b{}'.format(cursor[count%4]))
sys.stdout.flush()
# replace time.sleep() with some logic
time.sleep(.1)
명백한 한계가 있지만 다시 말하지만, 조잡합니다.
전체 응용 프로그램에서 공유하는 일반 Singleton을 만들었습니다.
from itertools import cycle
import threading
import time
class Spinner:
__default_spinner_symbols_list = ['|-----|', '|#----|', '|-#---|', '|--#--|', '|---#-|', '|----#|']
def __init__(self, spinner_symbols_list: [str] = None):
spinner_symbols_list = spinner_symbols_list if spinner_symbols_list else Spinner.__default_spinner_symbols_list
self.__screen_lock = threading.Event()
self.__spinner = cycle(spinner_symbols_list)
self.__stop_event = False
self.__thread = None
def get_spin(self):
return self.__spinner
def start(self, spinner_message: str):
self.__stop_event = False
time.sleep(0.3)
def run_spinner(message):
while not self.__stop_event:
print("\r{message} {spinner}".format(message=message, spinner=next(self.__spinner)), end="")
time.sleep(0.3)
self.__screen_lock.set()
self.__thread = threading.Thread(target=run_spinner, args=(spinner_message,), daemon=True)
self.__thread.start()
def stop(self):
self.__stop_event = True
if self.__screen_lock.is_set():
self.__screen_lock.wait()
self.__screen_lock.clear()
print("\r", end="")
print("\r", end="")
if __name__ == '__main__':
import time
# Testing
spinner = Spinner()
spinner.start("Downloading")
# Make actions
time.sleep(5) # Simulate a process
#
spinner.stop()
원래 버전에는 문제가 거의 없었기 때문에 @Victor Moyseenko에서 개선 된 버전
- 회전이 완료된 후 스피너의 캐릭터를 떠났습니다.
- 때로는 다음 출력의 첫 번째 문자도 제거됩니다.
- 출력에 threading.Lock ()을 추가하여 드문 경쟁 조건을 피합니다.
- tty를 사용할 수 없을 때 더 간단한 출력으로 돌아갑니다 (회전 없음).
import sys
import threading
import itertools
import time
class Spinner:
def __init__(self, message, delay=0.1):
self.spinner = itertools.cycle(['-', '/', '|', '\\'])
self.delay = delay
self.busy = False
self.spinner_visible = False
sys.stdout.write(message)
def write_next(self):
with self._screen_lock:
if not self.spinner_visible:
sys.stdout.write(next(self.spinner))
self.spinner_visible = True
sys.stdout.flush()
def remove_spinner(self, cleanup=False):
with self._screen_lock:
if self.spinner_visible:
sys.stdout.write('\b')
self.spinner_visible = False
if cleanup:
sys.stdout.write(' ') # overwrite spinner with blank
sys.stdout.write('\r') # move to next line
sys.stdout.flush()
def spinner_task(self):
while self.busy:
self.write_next()
time.sleep(self.delay)
self.remove_spinner()
def __enter__(self):
if sys.stdout.isatty():
self._screen_lock = threading.Lock()
self.busy = True
self.thread = threading.Thread(target=self.spinner_task)
self.thread.start()
def __exit__(self, exception, value, tb):
if sys.stdout.isatty():
self.busy = False
self.remove_spinner(cleanup=True)
else:
sys.stdout.write('\r')
위의 Spinner 클래스 사용 예 :
with Spinner("just waiting a bit.. "):
time.sleep(3)
https://github.com/Tagar/stuff/blob/master/spinner.py에 코드를 업로드했습니다.
참고 URL : https://stackoverflow.com/questions/4995733/how-to-create-a-spinning-command-line-cursor
'developer tip' 카테고리의 다른 글
BibTex를 사용하는 경우 IEEE 종이에서 열을 수동으로 균일화하는 방법은 무엇입니까? (0) | 2020.12.10 |
---|---|
이름이있는 브라우저에서 ASP.NET MVC FileContentResult를 사용하여 파일을 스트리밍 하시겠습니까? (0) | 2020.12.10 |
ViewGroup에서 최대 너비 설정 (0) | 2020.12.10 |
Ruby에서 <<는 무엇을 의미합니까? (0) | 2020.12.10 |
int를 Android에서 문자열로 (0) | 2020.12.10 |