python主线程执行_wxpython中工作线程与主线程交互

import wx

import threading

def call_and_wait(target, *args, **kwargs):

if wx.Thread_IsMain():

return target(*args, **kwargs)

else:

context = {}

context['event'] = threading.Event()

wx.CallAfter(call_in_mainthread, context, target, *args, **kwargs)

context['event'].wait()

return context['result']

def call_in_mainthread(context, target, *args, **kwargs):

context['result'] = target(*args, **kwargs)

context['event'].set()

主要思想是在工作线程创建一个Event对象,然后利用CallAfter放在主线程中去调用,工作线程调用event.wait()开始等待,当主线程执行完调用之后,设置event的状态,这样工作线程开始继续运行。下面是使用这个方法的一个例子:

class WorkThread(Thread):

def run():

# ...

call_and_wait(ShowSomeDialog)

def ShowSomeDialog():

# display some dialog

dlg = UserPassDialg(None)

if dlg.ShowModel() == wx.ID_OK:

return (dlg.Username, dlg.Password)

else:

return None

call_and_wait调用很别扭,利用decorator我们可以取消该方法的调用,取而代之我们把它的调用放到decorator去做。

def mainthread(func, *args, **kwargs):

'''ensure func invoked in main thread'''

def _func():

return call_and_wait(func, *args, **kwargs)

return _func

这样我们可以将前面的例子改写成:

class WorkThread(Thread):

def run():

# ...

ShowSomeDialog()

@mainthread

def ShowSomeDialog():

# display some dialog

dlg = UserPassDialg(None)

if dlg.ShowModel() == wx.ID_OK:

return (dlg.Username, dlg.Password)

else:

return None

似乎上面的代码并没有简洁多少,但是如果碰到需要大量调用主线程的方法时候,使用decorator可以避免创建许多一次性的方法。例如,在应用使用sqlite的情况下,由于sqlite只能单线程使用,所以也不能在工作线程中调用sqlite方法,通常的方法就是将所有sqlite调用都放到主线程中去做。

@mainthread

def get_account(id):

#....

@mainthread

def save_account(account):

#...

# more sqlite methods

分享到:

sina.jpg

tec.jpg

2011-01-15 23:56

浏览 5721

评论

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值