wxpython中如何按键停止死循环?

目前点击stop按钮就卡死,无法实现停止循环


# coding:utf-8


import wx
import threading
import time



threadLock = True


class AvoidObs(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        print("开启线程:" + self.name)
        self.startavoid()
        print("关闭线程:" + self.name)

    def startavoid(self):
        count = 0
        while threadLock:
            count += 1
            time.sleep(1)
            print(count)

    def stopavoid(self):
        global threadLock
        threadLock = False
        print("结束运动")

t = AvoidObs()
class MyFrame(wx.Frame):

    def __init__(self):
        super().__init__(None, title='ClickFarming  V1.0T', size=(250, 180))                    # 窗口标题栏
        panel = wx.Panel(parent=self)                                                           # 创建面板,传递self(让当前窗口为面板的父类)
        self.b1 = wx.ToggleButton(parent=panel, label='START', pos=(100, 50))                               # 创建按钮
        self.Bind(wx.EVT_TOGGLEBUTTON, self.__on_click, self.b1)                                              # 绑定事件
        self.i = 0
        self.__stopped = False

        # 创建垂直方向的盒子布局管理器对象
        vbox = wx.BoxSizer(wx.VERTICAL)
        # 添加按钮b到vbox布局管理器
        vbox.Add(self.b1, proportion=1, flag=wx.ALIGN_CENTRE_HORIZONTAL | wx.SHAPED | wx.BOTTOM, border=10)
        # 设置面板panel采用vbox布局管理器
        panel.SetSizer(vbox)

    def __on_click(self, event):
        self.i += 1
        if self.i % 2 != 0:
            self.b1.SetLabel('STOP')
            time.sleep(1)
            t.run()
            print("死循环")

        else:
            self.b1.SetLabel('START')
            t.stopavoid()






if __name__ == '__main__':

# 创建应用程序对象
    app = wx.App()

# 创建窗口对象
    frm = MyFrame()

# 显示窗口
    frm.Show()

# 进入主事件循环
    app.MainLoop()

题主的代码,即使不点击停止按钮,只要点击了开始,GUI线程就已经被全局的线程对象阻塞了。也许题主对于GUI主线程的地位理解有误,我的建议是:所以的子线程均应置于GUI主线程的管理之下。略微修改了一下题主的代码,可以正常运行了。

# coding:utf-8
 
import wx
import threading
import time

class MyFrame(wx.Frame):
    def __init__(self):
        super().__init__(None, title='ClickFarming  V1.0T', size=(250, 180))
        panel = wx.Panel(parent=self)
        self.b1 = wx.ToggleButton(parent=panel, label='START', pos=(100, 50))
        self.Bind(wx.EVT_TOGGLEBUTTON, self.__on_click, self.b1)
        
        self.i = 0
        self.__stopped = False # 此属性未使用
        self.running = False
        
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(self.b1, proportion=1, flag=wx.ALIGN_CENTRE_HORIZONTAL | wx.SHAPED | wx.BOTTOM, border=10)
        panel.SetSizer(vbox)
    
    def __on_click(self, event):
        """启动或停止线程"""
        self.i += 1
        if self.i % 2 != 0:
            self.running = True
            th = threading.Thread(target=self.do_something)
            th.start()
            self.b1.SetLabel('STOP')
        else:
            self.running = False
            self.b1.SetLabel('START')
    
    def do_something(self):
        """线程函数"""
        
        count = 0
        while self.running:
            count += 1
            time.sleep(1)
            print(count)
 
if __name__ == '__main__':
    app = wx.App()
    frm = MyFrame()
    frm.Show()
    app.MainLoop()