Tengo un proceso que tomará un tiempo (quizás uno o dos minutos) en completarse. Cuando llamo esto desde mi GUI de pygtk, la ventana se bloquea (se oscurece y evita la acción del usuario) después de unos 10 segundos.Detener la GUI de pygtk para que no se bloquee durante el proceso de larga ejecución
Me gustaría evitar que esto suceda, pero no estoy seguro de cómo. Pensé que la multi-lectura sería la respuesta, pero parece que no funciona. Probé dos métodos diferentes que encontré en línea. Primero, modifiqué this FAQ para tomar una función de larga ejecución. En segundo lugar, traté de usar threading. Thread directamente como en this answer, pero eso también se bloquea.
Mis dos muestras están por debajo. Soy nuevo en multihilo, así que tal vez no sea la solución que estoy buscando. Básicamente estoy tratando de evitar que la GUI se bloquee, así que puedo actualizar con una barra de progreso y dejar que el usuario use un botón de cancelar.
#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()
De acuerdo, esto tiene sentido. Entiendo por qué no puedo buscar constantemente el estado del hilo. Pero DEBO saber cuándo termina el hilo. Si agrego una barra de estado para el progreso del hilo, ¿cómo puedo saber cuándo detener la barra de estado? –
He agregado una barra de progreso al ejemplo. 'glib.timeout_add' le permite sondear el estado del hilo sin hacer que su aplicación no responda. – jcollado
Muy bien. Esto tiene sentido. No sabía sobre 'glib.timeout_add'. Gracias por tu ayuda. –