国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

分析Python編程時利用wxPython來支持多線程的方法

2020-02-23 00:35:33
字體:
來源:轉載
供稿:網友

如果你經常使用python開發GUI程序的話,那么就知道,有時你需要很長時間來執行一個任務。當然,如果你使用命令行程序來做的話,你回非常驚訝。大部分情況下,這會堵塞GUI的事件循環,用戶會看到程序卡死。如何才能避免這種情況呢?當然是利用線程或進程了!本文,我們將探索如何使用wxPython和theading模塊來實現。

wxpython線程安全方法

wxPython中,有三個“線程安全”的函數。如果你在更新UI界面時,三個函數都不使用,那么你可能會遇到奇怪的問題。有時GUI也忙運行挺正常,有時卻會無緣無故的崩潰。因此就需要這三個線程安全的函數:wx.PostEvent, wx.CallAfter和wx.CallLater。據Robin Dunn(wxPython作者)描述,wx.CallAfter使用了wx.PostEvent來給應用程序對象發生事件。應用程序會有個事件處理程序綁定到事件上,并在收到事件后,執行處理程序來做出反應。我認為wx.CallLater是在特定時間后調用了wx.CallAfter函數,已實現規定時間后發送事件。

Robin Dunn還指出Python全局解釋鎖 (GIL)也會避免多線程同時執行python字節碼,這會限制程序使用CPU內核的數量。另外,他還說,“wxPython發布GIL是為了在調用wx API時,其他線程也可以運行”。換句話說,在多核機器上使用多線程,可能效果會不同。

總之,大概的意思是桑wx函數中,wx.CallLater是最抽象的線程安全函數, wx.CallAfter次之,wx.PostEvent是最低級的。下面的實例,演示了如何使用wx.CallAfter和wx.PostEvent函數來更新wxPython程序。

wxPython, Theading, wx.CallAfter and PubSub

wxPython郵件列表中,有些專家會告訴其他人使用wx.CallAfter,并利用PubSub實現wxPython應用程序與其他線程進行通訊,我也贊成。如下代碼是具體實現:

import time import wx    from threading import Thread from wx.lib.pubsub import Publisher    ######################################################################## class TestThread(Thread):   """Test Worker Thread Class."""     #----------------------------------------------------------------------   def __init__(self):     """Init Worker Thread Class."""    Thread.__init__(self)     self.start()  # start the thread      #----------------------------------------------------------------------   def run(self):     """Run Worker Thread."""    # This is the code executing in the new thread.     for i in range(6):       time.sleep(10)       wx.CallAfter(self.postTime, i)     time.sleep(5)     wx.CallAfter(Publisher().sendMessage, "update", "Thread finished!")      #----------------------------------------------------------------------   def postTime(self, amt):     """    Send time to GUI    """    amtOfTime = (amt + 1) * 10    Publisher().sendMessage("update", amtOfTime)    ######################################################################## 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)        # create a pubsub receiver     Publisher().subscribe(self.updateDisplay, "update")      #----------------------------------------------------------------------   def onButton(self, event):     """    Runs the thread    """    TestThread()     self.displayLbl.SetLabel("Thread started!")     btn = event.GetEventObject()     btn.Disable()      #----------------------------------------------------------------------   def updateDisplay(self, msg):     """    Receives data from thread and updates the display    """    t = msg.data     if isinstance(t, int):       self.displayLbl.SetLabel("Time since thread started: %s seconds" % t)     else:       self.displayLbl.SetLabel("%s" % t)       self.btn.Enable()    #---------------------------------------------------------------------- # Run the program if __name__ == "__main__":   app = wx.PySimpleApp()   frame = MyForm().Show()   app.MainLoop()            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 根河市| 紫云| 甘泉县| 江孜县| 双辽市| 怀远县| 扎鲁特旗| 航空| 汾阳市| 左贡县| 桐庐县| 新泰市| 永仁县| 于都县| 彭州市| 桂林市| 姚安县| 临海市| 乃东县| 扬州市| 阿克苏市| 台中县| 察雅县| 米脂县| 太和县| 岑溪市| 贺州市| 和顺县| 郴州市| 高要市| 奉节县| 太康县| 汕头市| 诏安县| 南乐县| 合水县| 东乌珠穆沁旗| 长宁区| 莱阳市| 汶川县| 马尔康县|