wxPython 和协程
最近写爬虫要用到 GUI,于是入坑了 wxPython,但貌似原生 wxPython 对协程的支持不是很好。遽上网搜索相关文章,然而不知道是不是由于搜索姿势不对,并没有找到相关的内容。咸鱼了一天后终于在 Google 上找到了答案——wxasync。
下面是用 wxasync 撸的一个最简单的 wx 程序,如果你和我一样碰到了同样的问题,希望本篇文章能够帮到你。
import asyncio
import wx
import wxasync
class Frame(wx.Frame):
def __init__(self, parent=None):
super(Frame, self).__init__(parent)
self.InitUI()
def InitUI(self):
panel = wx.Panel(self)
sizer = wx.BoxSizer()
self.btn = wx.Button(panel, label='Submit')
sizer.Add(self.btn, 1, flag=wx.EXPAND|wx.ALL, border=50)
panel.SetSizer(sizer)
# 绑定协程回调
wxasync.AsyncBind(wx.EVT_BUTTON, self.async_submit, self.btn)
async def async_submit(self, event):
# 假装等待 IO
self.btn.Disable()
print('Staring...')
await asyncio.sleep(1)
print('Working...')
await asyncio.sleep(1)
print('Done!')
self.btn.Enable()
if __name__ == '__main__':
# 获取 APP 实例
app = wxasync.WxAsyncApp()
frame = Frame()
frame.Show()
# 这一步很重要
# 不能 asyncio.run(app.MainLoop()) 因为该函数总是会新建一个消息循环
loop = asyncio.get_event_loop()
loop.run_until_complete(app.MainLoop())
区别在于把需要异步操作的地方换成了 wxasync 的函数,同时回调函数也被定义为协程了。