如何实施废除行动?

时间:2014-04-13 10:40:22

标签: python multithreading gtk pygtk pygobject

我用Python和PyGObject编写了一些简单的程序。我希望她通过ProgressBar告知用户进度。我用谷歌搜索这个过程应该是一个单独的线程,否则接口保持,现在有一些这样的测试:

import time
import threading
from gi.repository import Gtk, GObject

GObject.threads_init()

def tread_function():
    progress.set_fraction(0)
    time.sleep(5)
    progress.set_fraction(0.25)
    time.sleep(5)
    progress.set_fraction(0.5)
    time.sleep(5)
    progress.set_fraction(0.75)
    time.sleep(5)
    progress.set_fraction(1)


def clickOk(*args):
    t = threading.Thread(target=tread_function)
    t.start()

def clickCancel(*args):
    pass

buttonOk = Gtk.Button("Start Count")
buttonOk.connect("clicked", clickOk)

buttonCancel = Gtk.Button("Cancel Count")
buttonCancel.connect("clicked", clickCancel)

progress = Gtk.ProgressBar()
progress.set_show_text(True)

vBox = Gtk.VBox()
vBox.pack_start(buttonOk, True, True, 10)
vBox.pack_start(buttonCancel, True, True, 10)
vBox.pack_start(progress, True, True, 10)

window = Gtk.Window()
window.connect('destroy', Gtk.main_quit)
window.add(vBox)
window.show_all()

Gtk.main()

现在当界面没有按住时,如果他在设置中犯了错误,我想给用户一个机会让它完全停止工作。但是我无法用Google搜索,或者在文档中找到如何在完成执行之前杀死一个线程。

1 个答案:

答案 0 :(得分:0)

在python中杀死一个线程没有什么琐碎的方法。要解决这个问题,你需要构建自己的钩子来触发早期的线程退出。执行此操作的一种好方法是使用Event,这是一个可以设置的线程安全触发器。

在您这样做之前,您可能希望将代码包装在某些类中。编写没有类的GUI只会让你长期痛苦。

from threading import Event,Thread


class FakeClass(object):
    def __init__(self):
        self.progress = Gtk.ProgressBar()
        self.progress.set_show_text(True)
        self.buttonOk = Gtk.Button("Start Count")
        self.buttonOk.connect("clicked", self.clickOk)
        self.buttonCancel = Gtk.Button("Cancel Count")
        self.buttonCancel.connect("clicked", self.clickCancel)

        #create an event to trigger in your thread
        self.trigger = Event() 
        self.t = None

        #Other GTK stuff here...

    def tread_function(self):
        progress_fraction = 0.0

        #keep looping while the trigger is not set and the 
        #progress is not > 1.0
        while not self.trigger.is_set() and progress <= 1.0:
            progress.set_fraction(progress_fraction)
            time.sleep(1)
            progress_fraction += 0.1

    def clickOk(self, *args):
        # reset the trigger
        self.trigger.clear()
        #launch the thread
        self.t = threading.Thread(target=self.tread_function)
        self.t.start()

    def clickCancel(self, *args):
        # set the trigger (interrupting the thread)
        self.trigger.set()
        # join the thread so it is not left hanging
        if not self.t is None:
            self.t.join()


    # More other GTK stuff here...