Here's a working example of what you want.
You need to grasp the concept of what the GTK main loop does to understand why it is important to separate GUI manipulation code from long blocking code. Hopefully, the comments and the debugging statements in my example will help you understand. This PyGTK FAQ entry is useful, and the concept applies to Python with GTK3 and GObject introspection as well.
This code creates a window with a simple button labelled "Click me". Once you click it, it will change to "Working", the cursor will become an hourglass, and the GUI will remain responsive. Once ten seconds have elapsed, the button label will change to "Done" and the cursor will return to normal.
from gi.repository import Gtk, Gdk, GObject
window = None
# Build GUI:
window = Gtk.Window()
button = Gtk.Button(label="Click me")
# Connect signals:
print "Debug on_button_click: current_thread name:", threading.current_thread().name
# This is a callback called by the main loop, so it's safe to
# manipulate GTK objects:
watch_cursor = Gdk.Cursor(Gdk.CursorType.WATCH)
print "Debug lengthy_process: current_thread name:", threading.current_thread().name
# We're in a new thread, so we can run lengthy processes without
# freezing the GUI, but we can't manipulate GTK objects except
# through GObject.idle_add
print "Debug done: current_thread name:", threading.current_thread().name
thread = threading.Thread(target=lengthy_process)
if __name__ == "__main__":