前言
我们使用Python开发带有GUI的量化系统,有时候我们需要进行全市场选股、全市场行情数据下载等循环任务,这个时候往往需要执行很长时间。
我们会发现在点击“开始选股” 或者“开始下载”按钮之后,耗时任务会堵塞GUI的事件循环,于是,程序卡死了!
如何才能避免这种情况呢?我们可以利用wxPython多线程方案来完美解决!
多线程方案
我们以全市场选股为场景来介绍wxPython多线程的方案。
首先创建一个主线程和三个子线程:
AppUI:GUI的主界面
ProgressThread:进度条指示选股执行进度
SelectThread:执行选股策略
设计多线程GUI时,建议主线程进行UI相关的控件事件、显示数据绘制等任务,而子线程只进行业务逻辑处理。
当我们点击“开始选股”按钮后,主线程会触发Button事件,此时会启用子线程ProgressThread和SelectThread。如下所示:
def on_click_start(self, evt):
self.dialog = wx.ProgressDialog("选股进度", "Time remaining", 5,
style=wx.PD_AUTO_HIDE | wx.PD_ELAPSED_TIME | wx.PD_REMAINING_TIME)
self.progress = ProgressThread(self)
self.progress.start()
self.select = SelectThread(self)
self.select.start()
因为GUI的操作必须发生在主线程或者应用程序住循环所处的地方中。当涉及到子线程需要调用主线程任务时,wxPython提供了“线程安全”的函数——wx.PostEvent、wx.CallAfter和wx.CallLater。
此处,我们使用wx.CallAfter()即可,传递给wx.CallAfter()的函数对象总是在主线程中处理的。这是wxPython中子线程给主线程发送消息最简单的方法。
wxPython中子线程调用wx.CallAfter()方法之后,会使得主线程的UI可以在当前事件结束处理后,去处理子线程发送的消息。
classProgressThread(threading.Thread):
"""进度条类 """
def __init__(self, parent):
"""
:param parent: 主线程UI
:param timer: 计时器
"""
super(ProgressThread, self).__init__() # 继承
self.parent = parent
self.setDaemon(True) # 设置为守护线程, 即子线程是守护进程,主线程结束子线程也随之结束。
def run(self):
count = 0
while count < 5:
count = count + 0.5
time.sleep(0.5)
wx.CallAfter(self.parent.update_process_bar, count) # 更新进度条进度
wx.CallAfter(self.parent.close_process_bar) # destroy进度条
例程中,我们在每次循环中调用wx.CallAfter更新进度条的刻度,当执行完成后调用wx.CallAfter去摧毁进度条,而操作进度条是在主线程中处理的。
另外,wxPython线程间的调用还能使用发布-订阅机制。
在wxPython 2.8.11之前,wx.lib.pubsub模块提供了发布-订阅方式实现线程间的调用。从wxPython 2.8.11开始,wx.lib.pubsub集成了新的PyPubSub。
首先要安装下PyPubSub模块,然后导入该模块:
from pubsub import pub
其次订阅以下主题,接收以下主题的信息:
pub.subscribe(self.update_process_bar, "update")
pub.subscribe(self.close_process_bar, "close")
当要调用的时候,发布主题并向主题发送信息:
wx.CallAfter(pub.sendMessage,"update", count=count) # 更新进度条进度
wx.CallAfter(pub.sendMessage, "close") # destroy进度条
目前在QTYX量化系统中,我们已经将行情数据下载采用了多线程方式,下一步在选股分析的时候也会采用这种方式。
说明
wxPython是量化编程的基础知识,我们会把完整的源码上传到知识星球《Python量化场景编程技巧与方法》中,帮助小伙伴们更好地掌握这个方法。
《Python量化场景编程技巧和方法》围绕《玩转股票量化交易》中涉及到的一些内容,分享一些偏基础的关于Python编程技巧、Pandas编程技巧、数据库技巧、可视化编程技巧等等。
加入星球《玩转股票量化交易》的会员可以免费加入星球《Python量化场景编程技巧与方法》,微信联系我加入!!
知识星球介绍点击:知识星球《玩转股票量化交易》精华内容概览