Остановить блокировку графического интерфейса pygtk во время длительного процесса

У меня есть процесс, который займет некоторое время (может быть, минуту или две). Когда я вызываю это из своего графического интерфейса pygtk, окно блокируется (затемняется и предотвращает действия пользователя) примерно через 10 секунд.

Я бы хотел, чтобы этого не произошло, но я не знаю, как это сделать. Я думал, что многопоточность будет ответом, но, похоже, это не работает. Я пробовал два разных метода, которые нашел в Интернете. Во-первых, я модифицировал этот FAQ , чтобы он выполнял долгую работу. Во-вторых, я попытался использовать threading.Thread напрямую, как в , этот ответ , но он также блокируется.

Ниже приведены два моих образца.Я новичок в многопоточности, поэтому, возможно, это не то решение, которое я ищу. Я в основном просто пытаюсь не допустить блокировки графического интерфейса, чтобы я мог обновляться с помощью индикатора выполнения и позволять пользователю использовать кнопку отмены.

#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()

5
задан Community 23 May 2017 в 11:53
поделиться