zoukankan      html  css  js  c++  java
  • wxpython线程安全的方法

    wx中实现了3个线程安全的函数。如果在线程中,直接访问并更新主线程的UI,会遇到问题,有时候阻塞UI或者更新不起作用,有时严重的话会引起python崩溃。

    三个安全线程如下:

    • wx.PostEvent
    • wx.CallAfter
    • wx.CallLater

    其中,wx.CallLater是最抽象的线程安全函数,其次是callAfter,最后是PostEvent。

    PostEvent用法:

    import time
    from threading import *
    import wx
    
    # Button definitions
    ID_START = wx.NewId()
    ID_STOP = wx.NewId()
    
    # Define notification event for thread completion
    EVT_RESULT_ID = wx.NewId()
    
    def EVT_RESULT(win, func):
        """Define Result Event."""
        win.Connect(-1, -1, EVT_RESULT_ID, func)
    
    class ResultEvent(wx.PyEvent):
        """Simple event to carry arbitrary result data."""
        def __init__(self, data):
            """Init Result Event."""
            wx.PyEvent.__init__(self)
            self.SetEventType(EVT_RESULT_ID)
            self.data = data
    
    # Thread class that executes processing
    class WorkerThread(Thread):
        """Worker Thread Class."""
        def __init__(self, notify_window):
            """Init Worker Thread Class."""
            Thread.__init__(self)
            self.setDaemon(1)
            self._notify_window = notify_window
            self._want_abort = 0
            # This starts the thread running on creation, but you could
            # also make the GUI thread responsible for calling this
            self.start()
    
        def run(self):
            """Run Worker Thread."""
            # This is the code executing in the new thread. Simulation of
            for i in range(10):
                time.sleep(1)
                if self._want_abort:
                    # Use a result of None to acknowledge the abort (of
                    # course you can use whatever you'd like or even
                    # a separate event type)
                    wx.PostEvent(self._notify_window, ResultEvent(None))
                    return
                wx.PostEvent(self._notify_window, ResultEvent(i))
            # Here's where the result would be returned (this is an
            # example fixed result of the number 10, but it could be
            # any Python object)
            wx.PostEvent(self._notify_window, ResultEvent(10))
    
        def abort(self):
            """abort worker thread."""
            # Method for use by main thread to signal an abort
            self._want_abort = 1
    
    # GUI Frame class that spins off the worker thread
    class MainFrame(wx.Frame):
        """Class MainFrame."""
        def __init__(self, parent, id):
            """Create the MainFrame."""
            wx.Frame.__init__(self, parent, id, 'Thread Test')
    
            # Dumb sample frame with two buttons
            self.OkButton = wx.Button(self, ID_START, 'Start', pos=(0,0))
            wx.Button(self, ID_STOP, 'Stop', pos=(0,50))
            self.status = wx.StaticText(self, -1, '', pos=(0,100))
    
            self.Bind(wx.EVT_BUTTON, self.OnStart, id=ID_START)
            self.Bind(wx.EVT_BUTTON, self.OnStop, id=ID_STOP)
    
            # Set up event handler for any worker thread results
            EVT_RESULT(self,self.OnResult)
    
            # And indicate we don't have a worker thread yet
            self.worker = None
            
        def __Onfunc(self):
            import time
            time.sleep(10)
    
        def OnStart(self, event):
            """Start Computation."""
            # Trigger the worker thread unless it's already busy
            if not self.worker:
                self.status.SetLabel('Starting computation')
                self.worker = WorkerThread(self)
    
        def OnStop(self, event):
            """Stop Computation."""
            # Flag the worker thread to stop if running
            if self.worker:
                self.status.SetLabel('Trying to abort computation')
                self.worker.abort()
    
        def OnResult(self, event):
            """Show Result status."""
    
            # Process results here
            self.status.SetLabel('Computation Result: %s' % event.data)
            # In either event, the worker is done
            self.worker = None
    
    class MainApp(wx.App):
        """Class Main App."""
        def OnInit(self):
            """Init Main App."""
            self.frame = MainFrame(None, -1)
            self.frame.Show(True)
            self.SetTopWindow(self.frame)
            return True
    
    if __name__ == '__main__':
        app = MainApp(0)
        app.MainLoop()
  • 相关阅读:
    Android_listview设置每条信息的间距
    Android实现ListView或GridView首行/尾行距离屏幕边缘距离
    实现类似微信的延迟加载的Fragment——LazyFragment
    struts2的Action该方法不能去
    (工具)source insight高速增加时间代码
    猫学习IOS(十五)UI以前的热的打砖块游戏
    java语言内部类和匿名内部类
    JVM截至多少线程可以创建: unable to create new native thread
    linux下一个Oracle11g RAC建立(八)
    转基因小麦--主题在农业科技的最前沿
  • 原文地址:https://www.cnblogs.com/ankier/p/3221098.html
Copyright © 2011-2022 走看看