wxPython跨线程调用

版权所有,转载请注明出处:http://guangboo.org/2013/08/23/wxpython-non-gui-thread-call-gui-method

之前有介绍了《wxPython多线程支持》,包含了wx.CallAfter, wx.PostEvent, wxCallLater的用法,本文将wx.CallAfter封装成decorator,使得UI线程中的方法可以在非UI线程中调用。

本文将wx.CallAfter方法进行了封装,代码如下:

import wx



def call_after(func):

    def _wrapper(*args, **kwargs):

        return wx.CallAfter(func, *args, **kwargs)

    return _wrapper

当UI线程中的方法需要被非UI线程调用时,只有使用call_after进行修饰即可。如下对《wxPython多线程》中的实例改进:

import time

import wx

 

from threading import Thread

from wx.lib.pubsub import Publisher



def call_after(func):

    def _wrapper(*args, **kwargs):

        return wx.CallAfter(func, *args, **kwargs)

    return _wrapper



class MyForm(wx.Frame):

    #----------------------------------------------------------------------

    def __init__(self):

        wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial")

 

        # Add a panel so it looks the correct on all platforms

        panel = wx.Panel(self, wx.ID_ANY)

        self.displayLbl = wx.StaticText(panel, label="Amount of time since thread started goes here")

        self.btn = btn = wx.Button(panel, label="Start Thread")

 

        btn.Bind(wx.EVT_BUTTON, self.onButton)

 

        sizer = wx.BoxSizer(wx.VERTICAL)

        sizer.Add(self.displayLbl, 0, wx.ALL|wx.CENTER, 5)

        sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)

        panel.SetSizer(sizer)

 

        self._thread = Thread(target = self.run, args = ())

        self._thread.daemon = True

        



    def run(self):

        i = 0

        while True:

            i += 1

            time.sleep(1)

            self.updateDisplay('Seconds: %d' % i)



    #----------------------------------------------------------------------

    def onButton(self, event):

        """

        Runs the thread

        """

        self._thread.start()

        self.started = True

        self.displayLbl.SetLabel("Thread started!")

        btn = event.GetEventObject()

        btn.Disable()



    @call_after

    def updateDisplay(self, msg):

        """

        Receives data from thread and updates the display

        """

        self.displayLbl.SetLabel(msg)

 

#----------------------------------------------------------------------

# Run the program

if __name__ == "__main__":

    app = wx.PySimpleApp()

    frame = MyForm().Show()

    app.MainLoop()

源代码下载:demo.py

你可能感兴趣的:(wxPython)