wxPython 解决底层函数运行时间长导致GUI卡死的问题
带界面的Python程序,当底层函数运行时间过长,这时界面就会产生卡死的现象,体验极差。
1 def do_test(self, event): 2 print("Test Begin!!!") 3 4 test_run() 5 6 print("Test Over!!!") 7 8 #底层需要执行的函数 9 def test_run() 10 time.sleep(60)
上面这段代码在执行过程中,界面会卡死60s,只有等 test_run()执行完成后才能恢复正常。
所以应该给底层函数test_run()重新开辟一个线程,这样就能解决界面卡死的现象了
1 class MyThread(Thread): 2 def __init__(self, 3 parent=None): 4 Thread.__init__(self) 5 6 def run(self): 7 test_run() 8 9 def do_test(self, event): 10 print("Test Begin!!!") 11 #创建新线程 12 testthread = MyThread(parameter_a, parameter_b) 13 #运行底层函数 14 testthread.start() 15 16 print("Test Over!!!") 17 18 #底层需要执行的函数 19 def test_run() 20 time.sleep(60)
但这里又出现一个问题,子线程test_run()函数还没执行完成,主进程 do_test()已经全部执行结束了,“Test Over!”已经心安理得的打印出来了,这就尴尬了!
找了一些方法,比如 在 testthread.start()代码后加一句 testthread.join(),这句话的作用是等待test_run()执行完成后才继续执行do_test(),但是这样运行结果跟第一段代码一样了,界面还是会卡死!!!
所以解决该问题,我用了以下方法:
第一步:子线程中添加代码,当子线程执行完毕后通知主进程
#发送信息“Over”给主进程
wx.CallAfter(pub.sendMessage,"Over",msg="Thread finished!")
第二步 :主进程中添加接受消息代码块:
#主进程接受到消息“Over”后执行函数“task_over”
pub.subscribe(self.task_over,"Over")
完整代码如下:
1 class MyThread(Thread): 2 def __init__(self, 3 parent=None): 4 Thread.__init__(self) 5 6 def run(self): 7 test_run() 8 #执行完test_run()后给主进程发送“Over”信息 9 wx.CallAfter(pub.sendMessage,"Over",msg="Thread finished!") 10 11 def do_test(self, event): 12 print("Test Begin!!!") 13 #创建新线程 14 testthread = MyThread(parameter_a, parameter_b) 15 #运行底层函数 16 testthread.start() 17 18 #接收到“Over”信息后,执行task_over函数 19 pub.subscribe(self.task_over,"Over") 20 21 def task_over() 22 print("Test Over!!!") 23 24 #底层需要执行的函数 25 def test_run() 26 time.sleep(60)
这样就解决print打印信息的问题。