Curses programming, threads?

  • Thread starter Bartlomiej Rymarski
  • Start date
B

Bartlomiej Rymarski

Hello,

I'm writing this little program, and I've came across a function
that I need to call. Since the execution of the function takes a
real long time I want to put a timer, or an animated 'loading'
screen (it would be best if it was a progressbar). The questions is
how to make two commands to run at the same time.

I'm talking about a function which (for example) is connecting to
the database, and while it's connecting I would like to display a
nice loading animation. It could be a ascii sequence like this:
[/] [-] [\] [|] [/] [-] [\] [|]

I could write a function like this:

#v+
def function:
print "[/]"
command
print "[-]"
command
print "[\]"
command
...
#v-

But is this really the way other programs work? I don't think so.
And they don't use threads AFAIK. How can I accomplish something
like this?

It would be best if I could operate with like this:

#v+
def function:
do loader() while
connect_db()
#v-

And the loader() function would run in a loop until connect_db() is
is finished. Is that possible in python? Or are there any other,
better ways to do it?

Thanks a lot.

Regards,
 
B

Bartlomiej Rymarski

Bartlomiej Rymarski said:
[...]
And the loader() function would run in a loop until connect_db() is
is finished. Is that possible in python? Or are there any other,
better ways to do it?
[...]

Oh, I forgot - I'm using Linux, and curses module in Python 2.3.
 
M

Michele Simionato

Bartlomiej Rymarski said:
Bartlomiej Rymarski said:
[...]
And the loader() function would run in a loop until connect_db() is
is finished. Is that possible in python? Or are there any other,
better ways to do it?
[...]

Oh, I forgot - I'm using Linux, and curses module in Python 2.3.

You don't need curses. Some time ago somebody (I forgot the name)
posted this spinner class:

class Spinner( threading.Thread ): # a google search should find the author

DELAY = 0.1
DISPLAY = [ '|', '/', '-', '\\' ]

def __init__( self, before='', after='' ):
threading.Thread.__init__( self )
self.before = before
self.after = after

def run( self ):
write, flush = sys.stdout.write, sys.stdout.flush
self.running = 1
pos = -1
while self.running:
pos = (pos + 1) % len(self.DISPLAY)
msg = self.before + self.DISPLAY[pos] + self.after
write( msg )
flush()
write( '\x08' * len(msg) )
time.sleep( self.DELAY )
write( ' ' * len(msg) + '\x08' * len(msg) )
flush()

def stop( self ):
self.running = 0
self.join()

if __name__=="__main__":
spinner = Spinner('Be patient please ...')
spinner.start()
time.sleep(5) # doing a long operation
spinner.stop()



Michele Simionato
 
C

Carl Banks

Bartlomiej Rymarski said:
Hello,

I'm writing this little program, and I've came across a function
that I need to call. Since the execution of the function takes a
real long time I want to put a timer, or an animated 'loading'
screen (it would be best if it was a progressbar). The questions is
how to make two commands to run at the same time.
[snip]

It would be best if I could operate with like this:

#v+
def function:
do loader() while
connect_db()
#v-

And the loader() function would run in a loop until connect_db() is
is finished. Is that possible in python?

Generally speaking, to do this in C, on Unix, without threads, one
would use the setitimer system call, along with SIGALARM. (Doubtful
available on all Unices, and there are probably other ways, but I'd
guess this is the most common way to do it. It is available on Linux;
I've used it before.) AFAIK, Python does not expose the setitimer
call, so you can't do it that way in Python without writing a C
extension. (It would be a pretty simple extension to write, though.)

In Python, you could use the signal.alarm() call in much the same way.
The downside is that you can only update the little animation once
per second. Something like this could do what you want (untested):

def alarm_handler(*args):
if loaded:
return
update_animation()
signal.alarm(1)

signal.signal(signal.SIGALARM,alarm_handler)
signal.alarm(1)
loaded = False
connect_db()
loaded = True

But I recommend threads for this. It's one of the easiest possible
uses of threads. There's no complex communication involved; locks and
semaphores and stuff aren't required. Just connect to the database in
a subthread, and have it set a global flag just before it exits.
Animate in a loop in the main thread, checking the flag every
iteration, and when it's true, you're done.
 
B

Bartlomiej Rymarski

Michele Simionato said:
You don't need curses. Some time ago somebody (I forgot the name)
posted this spinner class:

class Spinner( threading.Thread ): # a google search should find the author
[...]

Great, thanks a lot.
 
B

Bartlomiej Rymarski

Carl Banks said:
(...)
But I recommend threads for this. It's one of the easiest possible
uses of threads. There's no complex communication involved; locks and
semaphores and stuff aren't required. Just connect to the database in
a subthread, and have it set a global flag just before it exits.
Animate in a loop in the main thread, checking the flag every
iteration, and when it's true, you're done.
(...)

I'll try to do this with threads then. Thanks for the answer.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top