peter
peter

Reputation: 4411

python main window hangs with timer

I need to turn on function from my main window and keep this function running because it checks some state ( it is again() function and I removed checking from this example ). This function must stay intact as it is now. But main window hangs. Please help.

# -*- coding: utf-8 -*-
import pygtk
pygtk.require("2.0")
import gtk 
import gobject
import time
gtk.gdk.threads_init()

class App:
    def __init__(self):
        self.okno = gtk.Window(gtk.WINDOW_TOPLEVEL) 
        self.okno.resize(400,150)
        self.okno.show_all()

        self.again()


    def again(self):
        i=0
        while 1:
            print i
            i=i+1           

if __name__ == "__main__":
    app = App()
    gtk.threads_enter()
    gtk.main()
    gtk.threads_leave()

CHANGED:

# -*- coding: utf-8 -*-
import pygtk
pygtk.require("2.0")
import gtk 
import gobject
import time
import threading, sys

gtk.gdk.threads_init()

class App(threading.Thread):
    def __init__(self):
        self.okno = gtk.Window(gtk.WINDOW_TOPLEVEL) 
        self.okno.resize(400,150)
        self.okno.show_all()
        self.again()        

    def again(self):
        i=0
        while 1:
            print i
            sys.stdout.flush()
            i=i+1       
            time.sleep(1)

if __name__ == "__main__":
    gtk.threads_enter()
    threading.Thread(target=App).start()
    gtk.threads_leave()
    gtk.main()

Upvotes: 0

Views: 232

Answers (1)

ebassi
ebassi

Reputation: 8815

You cannot use GTK API from different threads; only one thread is allowed to use GTK, and it's the thread that called Gtk.main() (and initialized the library, which is done automatically by the Python bindings when you import the Gtk module).

The correct way to use a thread with GTK is to create a worker thread to do a long-running job, and whenever the UI needs to be updated you should schedule a callback in the main loop, using GLib.idle_add(). The callable you pass to the idle_add() function is guaranteed to be called in the same thread as the one running the main loop.

You don't need to use the threads_enter() and threads_leave() API if you use a worker thread (and those functions are not portable anyway; they have been deprecated in GTK 3.0).

Upvotes: 1

Related Questions