wxpython使用多进程_线程执行wxPython使用delayedresult进行耗时处理 线程执行

PS:今天上午,非常郁闷,有很多简单基础的问题搞得我有些迷茫,哎,代码几天不写就忘。目前又不当COO,还是得用心记代码哦!

delayedresult应用背景绍介

在行进wxPython GUI画面编程时,如直接在画面主线程行进大批耗时算计处置,就会成造画面假死,不能响应用户输入。

应用wxPython的delayedresult块模,可省力处理该问题,甚至都不需要懂得相干线程处置机制,可即便方的把耗时处置放到独单的线程中,处置结束后把结果返回GUI画面主线程,并调用先预义定的相干处置,行进画面更新等。

为了演示delayedresult的应用情况,先新建一TestWindow框架,doSomeThing()是我们模拟行进大批耗时处置的数函。

1 import wx

2 from wx.lib.delayedresult import startWorker

3 import threading

4

5 class TestWindow(wx.Frame):

6 def __init__(self, title='Test Window'):

7 self.app = wx.App(False)

8 wx.Frame.__init__(self, None, -1, title)

9 panel = wx.Panel(self)

10 self.btnBegin = wx.Button(panel, -1, label='Begin')

11 self.Bind(wx.EVT_BUTTON, self.handleButton, self.btnBegin)

12 self.txtCtrl = wx.TextCtrl(panel, style=wx.TE_READONLY, size=(300, -1))

13 vsizer = wx.BoxSizer(wx.VERTICAL)

14 vsizer.Add(self.btnBegin, 0, wx.ALL, 5)

15 vsizer.Add(self.txtCtrl, 0, wx.ALL, 5)

16 panel.SetSizer(vsizer)

17 vsizer.SetSizeHints(self)

18 self.Show()

19

20 #处置Begin按钮件事

21 def handleButton(self, event):

22 self.workFunction()

23

24 #开始执行耗时处置,有继承类实现

25 def workFunction(self, *args, **kwargs):

26 print'In workFunction(), Thread=', threading.currentThread().name

27 print '\t*args:', args

28 print '\t**kwargs:', kwargs

29

30 self.btnBegin.Enable(False)

31

32 #耗时处置处置成完后,调用该数函执行画面更新示显,由继承类实现

33 def consumer(self, delayedResult, *args, **kwargs):

34 print 'In consumer(), Thread=', threading.currentThread().name

35 print '\tdelayedResult:', delayedResult

36 print '\t*args:', args

37 print '\t**kwargs:', kwargs

38

39 self.btnBegin.Enable(True)

40

41 #模拟行进耗时处置并返回处置结果,给继承类应用

42 def doSomeThing(self, *args, **kwargs):

43 print'In doSomeThing(), Thread=', threading.currentThread().name

44 print '\t*args:', args

45 print '\t**kwargs:', kwargs

46

47 count = 0

48 while count < 10**8:

49 count += 1

50

51 return count

行运面界:

e4d5021a8bd2f401ddbc1d19e3946fd4.png

先看看如在GUI画面主线程行进doSomeThing()处置的

1 class DoSomeThingInGUI(TestWindow):

2 def __init__(self):

3 TestWindow.__init__(self, 'Do Something In GUI Thread')

4 self.app.MainLoop()

5

6 #执行doSomeThing(),并在执行成完后,动主调用consumer()更新画面示显

7 def workFunction(self, *args, **kwargs):

8 TestWindow.workFunction(self, args, kwargs)

9 var = self.doSomeThing()

10 self.consumer(var)

11

12 def consumer(self, delayedResult, *args, **kwargs):

13 TestWindow.consumer(self, delayedResult, args, kwargs)

14 self.txtCtrl.SetValue(str(delayedResult))

15

16 if __name__ == '__main__':

17 win = DoSomeThingInGUI()

执行后,点Begin开始后,直到处置成完画面口窗没法动移。

由以下log出输可以晓得,处置都是在GUI画面主线程中成完的。

In workFunction(), Thread= MainThread

*args: ((), {})

**kwargs: {}

In doSomeThing(), Thread= MainThread

*args: ()

**kwargs: {}

In consumer(), Thread= MainThread

delayedResult: 100000000

*args: ((), {})

**kwargs: {}

应用wx.lib.delayedresult后的处置情况:

1 class DoSomeThingInSeperateThread(TestWindow):

2 def __init__(self):

3 TestWindow.__init__(self, 'Do Something In Seperate Thread')

4 self.jobId = 100

5 self.app.MainLoop()

6

7 #调用wx.lib.delayedresult.startWorker,把数函处置放到独单的线程中去成完。

8 #成完后会动主调用consumer行进画面更新处置

9 #startWorker数函的各数参接下来分析

10 def workFunction(self, *args, **kwargs):

11 TestWindow.workFunction(self, args, kwargs)

12 startWorker(self.consumer, self.doSomeThing, jobID=self.jobId)

13

14 #第一数参要为DelayedResult类型,即含包处置结果或常异息信,调用get口接获得。

15 def consumer(self, delayedResult, *args, **kwargs):

16 TestWindow.consumer(self, delayedResult, args, kwargs)

17 assert(self.jobId == delayedResult.getJobID())

18 try:

19 var = delayedResult.get()

20 except Exception, e:

21 print 'Result for job %s raised exception:%s' %(delayedResult.getJobID, e)

22

23 self.txtCtrl.SetValue(str(var))

24

25 if __name__ == '__main__':

26 win = DoSomeThingInSeperateThread()

执行后,点Begin开始后,口窗动移不受影响,也就是说处置是异步的。

由以下log出输可以晓得,耗时处置doSomeThing是在独立线程行运的。

处置成完后的画面更新处置consumer还是在GUI画面主线程成完的。

In workFunction(), Thread= MainThread

*args: ((), {})

**kwargs: {}

In doSomeThing(), Thread= 100

*args: ()

**kwargs: {}

In consumer(), Thread= MainThread

delayedResult:

*args: ((), {})

**kwargs: {}

startWorker数函绍介

该数函创立独立线程(Producer线程)执行workerFn(*wargs, **wkwargs),并将其结果发送给行运在Main线程的consumer(*cargs, ckwargs)。

jobID即为创立的Producer线程的名字,也可在consumer中判断是那个Producer线程。

具体可考参 help(wx.lib.delayedresult)

startWorker(consumer,

workerFn,

cargs=(), ckwargs={},

wargs=(), wkwargs={},

jobID=None,

group=None,

daemon=False,

sendReturn=True,

senderArg=None)

注意事项:

1)sendResurn为True的情况下,workFn执行结束后才执行consumer处置。

2)consumer第一数参为DelayedResult,可应用其结果get()获得workFn中返回的结果,getJobID()用于返回数参jobID或者None(jobID未指定时)

3)cargs, ckwargs传递给consumer;wargs, wkargs传递给workerFn

文章结束给大家分享下程序员的一些笑话语录: 不会,Intel会维持高利润,也会维持竞争局面,国外的竞争不是打死对方的那种。你看日本有尼康,佳能,索尼,都做相机,大家都过得很滋润。别看一堆厂,其实真正控制的是后面的那几个财团——有些竞争对手,后面其实是一家人。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值