views:

402

answers:

1

I'm having some problems threading my pyGTK application. I give the thread some time to complete its task, if there is a problem I just continue anyway but warn the user. However once I continue, this thread stops until gtk.main_quit is called. This is confusing me.

The relevant code:

class MTP_Connection(threading.Thread):
    def __init__(self, HOME_DIR, username):
        self.filename = HOME_DIR + "mtp-dump_" + username
        threading.Thread.__init__(self)

    def run(self):
        #test run
        for i in range(1, 10):
            time.sleep(1)
            print i

..........................

start_time = time.time()
conn = MTP_Connection(self.HOME_DIR, self.username)
conn.start()
progress_bar = ProgressBar(self.tree.get_widget("progressbar"),
                           update_speed=100, pulse_mode=True)
while conn.isAlive():
    while gtk.events_pending():
        gtk.main_iteration()
    if time.time() - start_time > 5:
        self.write_info("problems closing connection.")
        break
#after this the program continues normally, but my conn thread stops
+3  A: 

Firstly, don't subclass threading.Thread, use Thread(target=callable).start().

Secondly, and probably the cause of your apparent block is that gtk.main_iteration takes a parameter block, which defaults to True, so your call to gtk.main_iteration will actually block when there are no events to iterate on. Which can be solved with:

gtk.main_iteration(block=False)

However, there is no real explanation why you would use this hacked up loop rather than the actual gtk main loop. If you are already running this inside a main loop, then I would suggest that you are doing the wrong thing. I can expand on your options if you give us a bit more detail and/or the complete example.

Thirdly, and this only came up later: Always always always always make sure you have called gtk.gdk.threads_init in any pygtk application with threads. GTK+ has different code paths when running threaded, and it needs to know to use these.

I wrote a small article about pygtk and threads that offers you a small abstraction so you never have to worry about these things. That post also includes a progress bar example.

Ali A
From your page I found that I am supposed to write:gtk.gdk.threads_init() which I never did. It works now.What is the reason I shouldn't I subclass threading.Thread? All the examples I looked at do this.
wodemoneke
I'm running in the mainloop, but I don't want to continue until I know if the thread will fail or not, which is why I wrote this inner loop.
wodemoneke
There is just no need to subclass it. http://stackoverflow.com/questions/660961/overriding-python-threading-thread-run/660974#660974
Ali A
Ok, but as long as you realise that the rest of your UI won't get updates during that period.
Ali A