On Wed, 2005-03-30 at 19:54 -0800, John Finlay wrote: > L�szl� Monda wrote: > > >On Sat, 2005-03-26 at 08:04 -0500, John (J5) Palmieri wrote: > > > > > >>On Sat, 2005-03-26 at 06:46 -0600, Skip Montanaro wrote: > >> > >> > >>> L�szl�> I want to make my application very responsive under high load. > >>> ... > >>> L�szl�> As you can see, I want to pulse a progress bar while a long > >>> L�szl�> (computationally or I/O intensive) operation is running. I > >>> L�szl�> started a separate thread for it. > >>> > >>>I could be wrong (never used threads with gtk), but don't you have some > >>>sort > >>>of gtk thread initialization function(s) to call? See if something in > >>>section 20 of the PyGTK FAQ leads to a solution: > >>> > >>> http://www.async.com.br/faq/pygtk/index.py?req=index > >>> > >>> > >>gtk.gdk.threads_init() > >> > >>also you can update the progress bar from you thread by calling these > >>two methods to lock the main thread: > >> > >>gtk.gdk.threads_enter() > >><gui update code here> > >>gtk.gdk.threads_leave() > >> > >> > >> > > > >Thanks everyone for the help. In this particular example, it was enough > >to call gtk.threads_init() before gtk.main() to work properly. > > > >However according to the PyGTK documentation, timeout handlers are > >outside the GDK global lock and therefore every GTK functions should be > >wrapped in gtk.threads_enter() and gtk.threads_leave() inside them. > > > >Is it possible that gtk.threads_init() was enough in this example > >because the other thread didn't do any GUI manipulation? > > > > > >Beyond that there are some things I cannot completely understand from > >the documentation: > > > >1) Why should I use gtk.threads_enter() and gtk.threads_leave() around > >gtk.main()? I would suppose that this locks the main thread and doesn't > >let other threads running. I tried it and know that it doesn't, but > >it's still illogical to me. > > > >2) Are the gtk.threads_*() functions the same as the gtk.gdk.threads_*() > >functions? In my experience they are, but I couldn't find any related > >documentations. > > > > > >Unfortunately my real world application still doesn't work because it > >manipulates the GUI in more thread, so I've written a second test > >application to demonstrate the problem in a more deep but (hopefully) > >still clear way (also attached in pygtk-threading-example-2-wrong.py): > > > >#!/usr/bin/env python > > > >import threading > >import signal > >import gtk > > > >def timerfunc(): > > if not thread_finished: > > gtk.threads_enter() > > pbar.pulse() > > print 'Plusing ProgressBar, since '+ \ > > 'thread_finished is'+`thread_finished` > > gtk.threads_leave() > > return not thread_finished > > > >def threadfunc(): > > for i in range(25): > > k = 0 > > for j in range(1000000): > > k += 1 > > > > string = 'foo '+`i` > > print 'Appending to TreeView "'+string+'"' > > gtk.threads_enter() > > store.append([string]) > > gtk.threads_leave() > > thread_finished = True > > print 'thread_finished is True' > > > >def on_window_map_event(event, param): > > print 'Window mapped' > > while gtk.events_pending(): > > gtk.main_iteration(False) > > thread_finished = False > > gtk.timeout_add(50, timerfunc) > > thread = threading.Thread(target=threadfunc) > > thread.run() > > > > > Try thread.start() instead of thread.run()
Ouch! I'm banging my head against the wall. Thanks John!
> >store = gtk.ListStore(str)
> >renderer = gtk.CellRendererText()
> >column = gtk.TreeViewColumn('Foos', renderer, text=0)
> >view = gtk.TreeView(store)
> >view.append_column(column)
> >sw = gtk.ScrolledWindow()
> >sw.add(view)
> >pbar = gtk.ProgressBar()
> >vbox = gtk.VBox()
> >vbox.pack_start(sw)
> >vbox.pack_start(pbar, False)
> >window = gtk.Window()
> >window.set_default_size(100, 600)
> >window.add(vbox)
> >window.show_all()
> >window.connect('map_event', on_window_map_event)
> >window.connect('destroy', gtk.main_quit)
> >
> >signal.signal(signal.SIGINT, signal.SIG_DFL)
> >gtk.threads_init()
> >gtk.threads_enter()
> >gtk.main()
> >gtk.threads_leave()
> >
> >There is a window which contains a TreeView (above) and a ProgressBar
> >(below). When the window gets mapped, it shows up (just because
> >gtk.main_iteration(False) got called). At this point the timer and the
> >new thread begins to run. The timer should pluse the ProgressBar in
> >every 50 msec and the new thread should call a computationally intensive
> >code 25 times and add a new line to the TreeView each time. I'd expect
> >them to run simultaneously, but the application freezes here.
> >
> >The output looks like this:
> >
> >Window mapped
> >Appending to TreeView "foo 0"
> >
> >I don't know why because I guarded GTK calls with gtk.threads_enter()
> >and gtk.threads_leave() in the new thread as well as in the timer
> >function as described the documentation.
> >
> >I've tried various combinations of the issues 1) and 2) I mentioned
> >above and experimented with several things with no success at all.
> >
> >I'd gladly contribute to some parts of the documentation if I'd know
> >more details on this issue.
> >
> >Could anyone shed some lights on what's really going on here?
Well, problem solved, great. There were some minor errors in the code
beyond thread.start(). I corrected them all and attached the source.
It would make a nice threading example IMO. I don't remember any
examples where more than one thread would manipulate the GUI
simultaneously. Someone could add it to some parts of the documentation
or should I contact with a documentation manintainer?
--
L�szl� Monda <http://mondalaci.objectis.net>
pygtk-threading-example-2-right.py
Description: application/python
_______________________________________________ pygtk mailing list [email protected] http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://www.async.com.br/faq/pygtk/
