Detener la interfaz gráfica de usuario de pygtk para que no se bloquee durante el proceso de ejecución prolongada

Tengo un proceso que tomará un tiempo (tal vez uno o dos minutos) en completarse. Cuando llamo a esto desde mi interfaz gráfica de usuario de pygtk, la ventana se bloquea (se oscurece y evita la acción del usuario) después de unos 10 segundos.

Me gustaría evitar que esto suceda, pero no estoy seguro de cómo. Pensé que el subproceso múltiple sería la respuesta, pero no parece estar funcionando. He probado dos métodos diferentes que encontré en línea. Primero modifiquéesta pregunta frecuente para tomar una función de larga duración. En segundo lugar, intenté usar threading. Thread directamente como enesta respuesta, pero eso también se bloquea.

Mis dos muestras están a continuación. Soy nuevo en multihilo, así que tal vez no sea la solución que estoy buscando. Básicamente, solo estoy tratando de evitar que la GUI se bloquee para poder actualizar con una barra de progreso y permitir que el usuario use un botón de cancelación.

#Sample 1
import threading
import time
import gobject
import gtk

gobject.threads_init()

class MyThread(threading.Thread):
    def __init__(self, label, button):
        super(MyThread, self).__init__()
        self.label = label
        self.button = button
        self.counter = 0
        button.connect("clicked", self.on_button_click)
        self.quit = False

    def update_label(self, counter):
        self.label.set_text("Counter: %i" % counter)
        time.sleep(20)
        return False

    def on_button_click(self, widget):
        self.counter += 1
        gobject.idle_add(self.update_label, self.counter)

window = gtk.Window()
label = gtk.Label()
box = gtk.VBox()
button = gtk.Button("Test")
box.pack_start(label)
box.pack_start(button)
window.add(box)
window.show_all()
window.connect("destroy", lambda _: gtk.main_quit())
thread = MyThread(label, button)
thread.start()

gtk.main()
thread.quit = True

#####################################
#Sample 2

from threading import Thread
import time
import gobject
import gtk

class Test():
    def __init__(self):
        self.counter = 0
        self.label = gtk.Label()
        button = gtk.Button("Test")

        window = gtk.Window()
        box = gtk.VBox()
        box.pack_start(self.label)
        box.pack_start(button)
        window.add(box)

        window.connect("destroy", lambda _: gtk.main_quit())
        button.connect("clicked", self.on_button_click)
        window.show_all()

    def update_label(self, counter):
        self.label.set_text("Counter: %i" % counter)
        time.sleep(20)
        return False

    def on_button_click(self, widget):
        self.counter += 1
        thread = Thread(target=self.update_label, args=(self.counter,))
        thread.start()
        while thread.is_alive():
            pass
        thread.stop()

test = Test()
gtk.main()

Respuestas a la pregunta(4)

Su respuesta a la pregunta