Ho un processo che richiederà un po '(forse un minuto o due) per completare. Quando chiamo questo dalla mia GUI pygtk la finestra si blocca (si scurisce e impedisce l'azione dell'utente) dopo circa 10 secondi.Arresta la GUI pygtk dal blocco durante il processo di lunga durata
Mi piacerebbe evitare che ciò accada, ma non so come. Pensavo che il multithreading sarebbe stata la risposta, ma non sembra funzionare. Ho provato due metodi diversi che ho trovato online. Innanzitutto, ho modificato this FAQ per eseguire una funzione di esecuzione prolungata. In secondo luogo ho provato a utilizzare threading.Thread direttamente come in this answer, ma anche questo si blocca.
I miei due campioni sono sotto. Sono nuovo nel multithreading, quindi forse non è la soluzione che sto cercando. In pratica sto solo provando a mantenere la GUI bloccata, così posso aggiornare con una barra di avanzamento e lasciare che l'utente usi un pulsante di annullamento.
#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()
Ok, questo ha senso. Capisco perché non riesco a sondare costantemente lo stato del thread. Ma ho bisogno di sapere quando finisce il thread. Se aggiungo una barra di stato per l'avanzamento del thread, come posso sapere quando interrompere la barra di stato? –
Ho aggiunto una barra di avanzamento all'esempio. 'glib.timeout_add' consente di eseguire il polling dello stato del thread senza rendere l'appplicazione non rispondente. – jcollado
Ok, bene. Questo ha senso. Non sapevo di 'glib.timeout_add'. Grazie per l'aiuto. –