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

原文地址:https://www.cnblogs.com/keanuyaoo/p/3278054.html