読者です 読者をやめる 読者になる 読者になる

wxPythonとthreadingで時間がかかる処理


wxPythonで、OnButton等のコールバック関数内に時間がかかる処理を書いてしまうと、
ウィンドウ全体が固まってしまいます。


そこでthreadingを使ってどうにかします。



これが最適な方法なのかどうかは知りません。


というより、きっと何かマズイ部分があると思いますが、一応。


よりよい方法をご存知の方は、コメント欄にでもご一報ください。

class SimpleThread(threading.Thread):
    """呼び出し可能オブジェクト(関数など)を実行するだけのスレッド"""
    def __init__(self, acallable):
        self.acallable = acallable
        self._result = None
        super(SimpleThread, self).__init__()
    
    def run(self):
        self._result = self.acallable()
    
    def result(self):
        return self._result

def task_takes_time(acallable):
    """
    関数デコレータ
    acallable本来の処理は別スレッドで実行しながら、
    ウィンドウを更新するwx.YieldIfNeededを呼び出し続けるようにする
    """
    @wraps(acallable)
    def f():
        t = SimpleThread(acallable)
        t.start()
        while t.isAlive():
            wx.YieldIfNeeded()
            time.sleep(0.01)
        return t.result()
    return f

class Frame(wx.Frame):
    def OnButton(self, event):
        @task_takes_time
        def doit():
            #何か時間がかかる処理をする
            return "spam"
        print doit()