Как создать вращающийся курсор командной строки? - PullRequest
53 голосов
/ 14 февраля 2011

Есть ли способ напечатать вращающийся курсор в терминале, используя Python?

Ответы [ 12 ]

63 голосов
/ 14 февраля 2011

Примерно так, при условии, что ваш терминал обрабатывает \ 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')
33 голосов
/ 24 марта 2014

Хороший питонский способ - использовать 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

32 голосов
/ 15 сентября 2016

Простой в использовании 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) 
10 голосов
/ 14 февраля 2011

Решение:

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' и стандартный сброс.

3 голосов
/ 14 февраля 2011

Конечно, это возможно.Это просто вопрос печати символа возврата (\b) между четырьмя символами, чтобы «курсор» выглядел так, как будто он вращается (-, \, |, /).

1 голос
/ 14 февраля 2011

Возьмите удивительный progressbar модуль - http://code.google.com/p/python-progressbar/ используйте RotatingMarker.

1 голос
/ 14 февраля 2011

модуль curses. Я бы взглянул на функции addstr () и addch ().Никогда не использовал это все же.

1 голос
/ 14 февраля 2011

Для более сложных манипуляций с консолью в Unix вы можете использовать модуль Python curses , а в Windows вы можете использовать WConio , который обеспечивает эквивалентную функциональность библиотеки curses.

0 голосов
/ 02 августа 2018

Грубое, но простое решение:

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)

Существуют очевидные ограничения, но опять же, грубые.

0 голосов
/ 06 февраля 2018

Вот, пожалуйста - просто и понятно.

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)
...