Mailing List Archive

More Problems With Curses
Hello,

I'm trying to write an IRC client in Python using the curses and
threading modules. Basically one thread will read user input while the
other threads print the messages received from the servers the user is
connected to. This works fine if I use print() and input() instead of
curses, but it's annoying because the other threads will print stuff to
the screen in the middle of what you are typing. However, when I try to
use curses instead, only the user-input thread seems to have control of
the screen; the other threads will hang and not print anything until you
press return.

I wrote the following to try to figure out what's going on:


import time
import threading
import curses

def repd():
x=0
while 1:
time.sleep(1)
print 'x=%d' % x
x=x+1

thr=threading.Thread(target=repd)
thr.start()
while 1:
time.sleep(1)
str=raw_input()
print 'got %s' % str


This prints out 'x=0', 'x=1' etc. at one second intervals, and in
addition prints whatever you type as soon as you press return. However,
if I add the following two lines:

stdscr=curses.initscr()
curses.endwin()

right before I start the thread, then what happens is that 'x=0' gets
printed, and then nothing will get printed again until you type
something and press return, at which point all the 'x=n' messages which
you should have seen get printed all at once. So, just the act of
initializing curses causes this annoying blocking behavior which I don't
want.

So, what am I doing wrong? How can I get curses and threading to play
nice with each other?

now-I-know-why-it's-called-"curses"-ly yrs, Cliff
More Problems With Curses [ In reply to ]
ATS Public Labs <xcvx@sdofi.com> wrote:
: Hello,

: I'm trying to write an IRC client in Python using the curses and
: threading modules. Basically one thread will read user input while the
: other threads print the messages received from the servers the user is
: connected to. This works fine if I use print() and input() instead of
: curses, but it's annoying because the other threads will print stuff to
: the screen in the middle of what you are typing. However, when I try to
: use curses instead, only the user-input thread seems to have control of
: the screen; the other threads will hang and not print anything until you
: press return.

: I wrote the following to try to figure out what's going on:


: import time
: import threading
: import curses

: def repd():
: x=0
: while 1:
: time.sleep(1)
: print 'x=%d' % x
: x=x+1

: thr=threading.Thread(target=repd)
: thr.start()
: while 1:
: time.sleep(1)
: str=raw_input()
: print 'got %s' % str


: This prints out 'x=0', 'x=1' etc. at one second intervals, and in
: addition prints whatever you type as soon as you press return. However,
: if I add the following two lines:

: stdscr=curses.initscr()
: curses.endwin()

: right before I start the thread, then what happens is that 'x=0' gets
: printed, and then nothing will get printed again until you type
: something and press return, at which point all the 'x=n' messages which
: you should have seen get printed all at once. So, just the act of
: initializing curses causes this annoying blocking behavior which I don't
: want.

: So, what am I doing wrong? How can I get curses and threading to play
: nice with each other?

Curses was designed before threading (and before the "modern thought"
of event loops). Curses is based on reading and writing from the same
file descriptor. So it is better to "block" on a poll to see if there
is data there before calling the curses routines (with select).

You might want to look at how I did it in my own alpha version of an
IRC client:
ftp://starship.python.net/pub/crew/arcege/Pyirc-1.5.1.tar.gz

-Arcege