如何解决wx.Python 杀死子线程
我有一个 GUI 应用程序,在我的主线程中运行,一些子线程在后台执行操作。我将关闭按钮绑定到一个方法,在关闭软件之前做一些事情,但我不知道如何停止子线程
self.Bind(wx.EVT_CLOSE,self.onCloseFrame)
def onCloseFrame(self,event):
do_stuff()
# stop threads here
self.Destroy()
有没有办法做到这一点?
解决方法
这是我模拟的一个测试。
它比实际需要的要复杂一些,因为我想要多个进度指示器,但您应该能够了解其要点。
包含一个终止函数并触发它,如果您希望在线程自然完成之前结束它。
在这种情况下,线程在一分钟后超时,但它可以做任何事情。
点击 Start
以查看您希望同时运行的多个线程。
import time
import wx
from threading import Thread
import wx.lib.newevent
progress_event,EVT_PROGRESS_EVENT = wx.lib.newevent.NewEvent()
class ProcessingFrame(wx.Frame):
def __init__(self,title,parent=None):
wx.Frame.__init__(self,parent=parent,title=title)
panel = wx.Panel(self)
self.parent = parent
self.btn = wx.Button(panel,label='Stop processing',size=(200,30),pos=(10,10))
self.btn.Bind(wx.EVT_BUTTON,self.OnExit)
self.progress = wx.Gauge(panel,size=(240,10),50),range=60)
self.process = wx.TextCtrl(panel,size = (200,250),100),style = wx.TE_MULTILINE)
#Bind to the progress event issued by the thread
self.Bind(EVT_PROGRESS_EVENT,self.OnProgress)
#Bind to Exit on frame close
self.Bind(wx.EVT_CLOSE,self.OnExit)
self.Show()
self.mythread = TestThread(self)
def OnProgress(self,event):
self.progress.SetValue(event.count)
self.process.write("Checking process: "+event.process+"\n")
self.Refresh()
if event.count >= 60:
self.OnExit(None)
def OnExit(self,event):
if self.mythread.isAlive():
self.mythread.terminate() # Shutdown the thread
self.mythread.join() # Wait for it to finish
self.Destroy()
class TestThread(Thread):
def __init__(self,parent_target):
Thread.__init__(self)
self.parent = parent_target
self.stopthread = False
self.time = time.time()
self.process = 1 # Testing only - mock process id
self.start() # start the thread
def run(self):
# A loop that will run for a while then terminate
while self.stopthread == False:
curr_loop = int(time.time() - self.time)
self.process += 10 # Testing only - mock process id
if curr_loop <= 60: # Update progress bar
time.sleep(0.1)
evt = progress_event(count=curr_loop,process=str(self.process))
#Send back current count for the progress bar
try:
wx.PostEvent(self.parent,evt)
except: # The parent frame has probably been destroyed
self.terminate()
def terminate(self):
self.stopthread = True
class MyPanel(wx.Panel):
def __init__(self,parent):
wx.Panel.__init__(self,parent)
self.text_count = 0
self.parent=parent
btn_start = wx.Button(self,wx.ID_ANY,label='Start Long running process',size=(180,10))
btn_test = wx.Button(self,label='Is the GUI still active?',50))
self.txt = wx.TextCtrl(self,style= wx.TE_MULTILINE,90),size=(400,100))
btn_end = wx.Button(self,label='Stop All',size=(100,200))
btn_start.Bind(wx.EVT_BUTTON,self.Start_Process)
btn_test.Bind(wx.EVT_BUTTON,self.ActiveText)
btn_end.Bind(wx.EVT_BUTTON,self.End_AllProcesses)
self.activeframes = [] # 1 per live process
def Start_Process(self,event):
#thread_count = active_count()
thread_count = len(self.activeframes) + 1
self.activeframes.append(ProcessingFrame(title='Threaded Task '+str(thread_count),parent=self))
def End_AllProcesses(self,event):
while len(self.activeframes) > 0:
try:
self.activeframes[-1].OnExit(None)
self.activeframes.pop(-1)
except: # process may have finished or been stopped individually
self.activeframes.pop(-1)
def ActiveText(self,event):
self.text_count += 1
txt = "Gui is still active " + str(self.text_count)+"\n"
self.txt.write(txt)
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None,title='Main Frame',size=(600,400))
panel = MyPanel(self)
self.Show()
if __name__ == '__main__':
app = wx.App(False)
frame = MainFrame()
app.MainLoop()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。