wxPython——GUI界面的设计
学习笔记总目录中包含更多python相关内容
认识wxPython
使用wxPython
遇到的坑
-
按钮按下“不弹起”——卡在循环中
在使用wxPython所提供的控件进行操作执行函数时,难免会遇到需要一个函数运行的时间过长或是直接进入一个
Loop
,这个时候整个GUI界面就会卡住。问题的出现是因为在编写python代码时,会有一个默认的线程供我们使用,也就是说我们所写的代码是
串行
的,这时当某一部分执行的代码进入了死循环,那么整个界面卡死是必然的。下面是原始代码:
# 有问题的代码
# -*- coding: utf-8 -*-
import wx
import wx.xrc
import itchat
class MainFrame ( wx.Frame ):
'''
这里漫长的窗口构建代码略过
'''
def __del__( self ):
pass
# Virtual event handlers, overide them in your derived class
def LogIn(self, event): # 当LogIn的触发条件发生时,执行下述函数
itchat.auto_login(hotReload=True) # 登录网页版微信(itchat为第三方库)
print("微信开始运行!")
itchat.run() # 令微信保持登录
'''
上面的 itchat.run() 是一个始终循环的函数,只有当网页版微信登出时才能跳出循环
因此如果此时执行这个事件函数,就会出现“按钮按下起不来”的情况
'''
if __name__ == '__main__':
appmain = wx.App()
winmain = MainFrame(None)
winmain.Show()
appmain.MainLoop()
发现问题后,我只采用了一种解决办法,还有其他办法也能解决,欢迎大家在评论区留言。下面是修正后的代码:
# 修正后的代码
# -*- coding: utf-8 -*-
import wx
import wx.xrc
import itchat
import threading # 管理线程的第三方库
class MainFrame ( wx.Frame ):
'''
这里漫长的窗口构建代码略过
'''
def __del__( self ):
pass
# Virtual event handlers, overide them in your derived class
def LogIn(self, event): # 当LogIn的触发条件发生时,执行下述函数
thread1 = threading.Thread(target = _LogIn)
thread1.start()
def _LogIn():
itchat.auto_login(hotReload=True)
print("微信开始运行!")
itchat.run()
'''
上面的解决方案是将登陆微信的函数进行打包变为一个函数,并通过新的方法调用
即为 itchat.run() 新开了一个线程,这样不占用主线程的使用程序GUI就不会卡了
'''
if __name__ == '__main__':
appmain = wx.App()
winmain = MainFrame(None)
winmain.Show()
appmain.MainLoop()
threading库的使用可以看这个大佬的文章:
《Python多线程编程(一):threading 模块 Thread 类的用法详解》