I am trying (for testing) to have a little ascii spinner object being printed on the screen during a gtk.main() loop. Currently, I have this code which prints a dot every two seconds.
gobject.timeout_add(2 * 1000,
lambda : (sys.stdout.write('.'), sys.stdout.flush()) )
gtk.main()
However, I would like the traditional ascii spinner instead but cannot get a good lambda for it. Any suggestions?
Edit: Two good answers but is there a way to do this with a lambda? Just 'cause lambda are cool. Nothing more.
Why are you limiting yourself to a lambda
? To do a spinner, it's easiest to maintain state:
class Spinner(object):
def __init__(self):
self._chars = r"-\|/-\|/"
self._pos = 0
def spin(self):
sys.stdout.write(self._chars[self._pos])
sys.stdout.write("\r")
sys.stdout.flush()
self._pos += 1
if self._pos >= len(self._chars):
self._pos = 0
return True
spinner = Spinner()
gobject.timeout_add(2 * 1000, spinner.spin)
Note: the above is untested, but should make the general idea clear enough.
This is something I've just tried in the console without gtk:
import sys
from itertools import cycle
from time import sleep
spinner = r'-\|/'
sys.stdout.write('Please wait... ')
for character in cycle(spinner):
sys.stdout.write(character)
sys.stdout.flush()
sys.stdout.write('\b')
sleep(1)
The two things I like that are slightly different from the previous solution are:
- Use
\b
instead of \r
to preserve any message you have in the same line (like "please wait")
cicle
takes care of what's the next character for you, so you don't need to bother to manage the state yourself.