[pygtk] Hi, all! I'm new to the list. How can I create please a frontend for a TUI command?
A.T.Hofkamp
a.t.hofkamp at tue.nl
Wed Oct 29 21:12:01 WST 2008
Néstor Amigo Cairo wrote:
> Ok, now I have some more comments. I have tried it, and it works fine
> when the application sends output as newlines, but sometimes, it
> prints a line and then waits to put some more output before the
> newline, and then, the application locks up.
> For example:
>
> # /sbin/badblocks --vw /dev/testdevice
> Checking for bad blocks in read-write mode
>>From block 0 to 1007496
> Testing with pattern 0xaa:
>
> and then, Done is put on the end of the last line, and a newline is
> added. But a new IO_IN event is triggered just as the line starts to
> arrive, and readline() has to wait for the newline to arrive, while
> the application is locked.
Basically, the solution is: don't use 'readline()'.
A safe solution is to use source.read(1), which reads 1 character strings
(which are garanteed to exist, otherwise gobject would not have triggered the
event). In this way you will never block in the read() call.
(note that you may still get a 0 length string, indicating that you have read
all data from the stream.)
Since you are reading partial lines in this way, you'll also have to handle
partial lines in your event handler. You can collect the read 1 character
strings into a longer string until you receive a \n, and then forward the read
line into the widget, ie
data = source.read(1)
# check for len(data) == 0 and act on it
collected = collected + data
if collected[-1] == '\n':
# collected is a complete line, do something with it
collected = ""
Alternatively, you may be able to push the read bytes directly in the widget
(I have no experience with TextView, so I cannot help you here).
The disadvantage of the above is that you read 1 character strings, which may
be highly inefficient if you get large volumes of output to read.
An other solution is to use os.read(source.fileno(), 1024). os.read() reads as
much data as available, upto (in this case) 1024 characters. That upper limit
is kind of arbitrary, if you expect large amounts of output, you should
increase it.
Here you'll read chunks of data (upto 1024 chars at a time), broken at
arbitrary points in the output stream. It may be less than a line, it may be a
line, it may be 5 lines and 10 characters, etc.
If you want to work line-based, the simplest solution is something like
chunk = os.read( ... )
# check for len(chunk) == 0 and act on it
collected = collected + chunk
i = collected.find('\n')
while i >= 0:
line = collected[:i]
collected = collected[i+1:]
# do something with 'line'
i = collected.find('\n')
Like above, if you don't care about lines, it may be easier (I never tried that).
Good luck,
Albert
More information about the pygtk
mailing list