On Sun, 2003-11-02 at 09:04, Liquid wrote:
> Hi all,
> I have a little question about textbuffer.
> The following code works good, the buffer will go straight to the textview,
> but if the process is quite long the window will freeze (also for a minute)
> until the command have finish, and the output will be shoot into the window
> in one time.
> My question is if for you is possible to stream the output to the textview
> fluently and not all in one time.
>
> configure = ("./configure --with-pthread")
> makeinstall = (configure + ' && make && make install')
> command = makeinstall
> child_e, child_o = os.popen4(command)
> data_o = child_o.read()
> textbuffer.set_text(data_o)
>
> textview = gtk.TextView()
> textview.set_wrap_mode(gtk.TRUE)
> textview.set_editable(False)
> textview.modify_font(pango.FontDescription("Monospace"))
>
> sw = gtk.ScrolledWindow()
> sw.show()
> sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
> sw.add(textview)
>
> frame = gtk.Frame();
> frame.set_shadow_type(gtk.SHADOW_IN)
> frame.add(sw)
> frame.set_border_width(6)
>
> textbuffer = textview.get_buffer()
> textview.set_size_request(gtk.gdk.screen_width()/3, gtk.gdk.screen_height()/5)
> table.attach(frame, 0, 8, 3, 12)
> frame.show()
> window.show_all()
> window.show()
OK, this requires using what should be called "Secret Technique #1 For
Making Your Application Look Responsive"(tm):
If you want to avoid freezes in your application while you are
doing large amounts of work in the background, remember to call
gtk.mainiteration() from time to time.
To apply this to your specific situation, set up your window and show it
before starting to read the data. Now read the data in chunks and append
it to the textbuffer.
You will not want to use textbuffer.set_text() to do this (since that
replace any existing text). Instead use
textbuffer.insert(textbuffer.get_end_iter(), "Text goes here")
After appending some text (a reasonably short amount, since you want
things to appear interactive), let GTK+ catch up on any pending events
-- which will include the events to trigger a redraw (update) of your
window. So you would append a couple of lines and then run the loop
while gtk.events_pending():
gtk.mainiteration(gtk.FALSE)
to update the display. Repeat until all your data has finished being
displayed.
Now, after getting this to work initially, you may want to tweak things
to avoid the incrementally updated display from jumping around. A couple
of things that immediately spring to mind:
(1) Push out the data in line-based chunks. This will tend to look nicer
in an incrementally updated display, rather than seeing part of a line
display and then suddenly have some more text whacked onto the end of
that line. This is particularly relevant since you have turned on wrap
mode, so you might get some strange re-wrapping effects if you inserted
arbitrary chunks which could terminate mid-word.
(2) Think about what should be displayed on the screen after each
update. Do you want to have the beginning of the text displayed and let
the user scroll down in their leisure (the web browser style of
behaviour), or do you want to always display the last piece of text you
inserted (the terminal window style)? Either is possible, you just need
to set the correct portion to be displayed.
Hope this helps a bit. Secret Technique #1 is the solution to so many of
these questions. :-)
Cheers,
Malcolm
_______________________________________________
pygtk mailing list [EMAIL PROTECTED]
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/