我是wxPython的新手,也不熟悉线程概念。如果有人能提供我的问题的信息来源或建议,我将非常感激。
我使用wxpython创建了一个GUI,允许用户使用输入运行我的脚本。由于一步需要20分钟才能运行,因此我计划创建一个进度对话框以显示用户进度并允许他们中止。我使用下面的示例代码对此进行了测试。
但是,即使我点击进度对话框中的停止按钮,我也无法停止WorkThread。我试过了 1.使用pb.sendMessage()的返回值创建if语句 2.在WorkThread启动时创建ProgressDialog对象并调用ProgressDialog.abort 但它们都不起作用。我想知道是否存在实现此类代码的概念错误以实现我想要做的事情?或者,如果这可以纠正?任何提示都将不胜感激!!
class WorkThread(Thread):
def __init__(self):
"""Init Worker Thread Class."""
Thread.__init__(self)
self.start() # start the thread
def run(self):
for i in range(10):
time.sleep(1)
val = 100 / 10
wx.CallAfter(pub.sendMessage, "update", step=val)
print 'Finish Run'
class ProgressDialog(wx.Dialog):
def __init__(self):
wx.Dialog.__init__(self, None)
self.abort = False
self.progress = 0
bSizer2 = wx.BoxSizer(wx.VERTICAL)
self.gauge = wx.Gauge(self, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, wx.GA_HORIZONTAL)
self.gauge.SetValue(0)
self.m_button1 = wx.Button(self, wx.ID_ANY, u"Stop Training", wx.DefaultPosition, wx.DefaultSize, 0)
bSizer2.Add(self.gauge, 0, 0, 5)
bSizer2.Add(self.m_button1, 0, 0, 5)
self.SetSizer(bSizer2)
self.Layout()
self.Centre(wx.BOTH)
## Connect Events
self.m_button1.Bind(wx.EVT_BUTTON, self.on_cancel)
pub.subscribe(self.updateProgress, "update")
def updateProgress(self, step):
self.progress += step
if self.abort:
self.Update()
self.Close()
elif self.progress >= 100:
self.gauge.SetValue(self.progress)
self.Update()
self.Close()
else:
self.gauge.SetValue(self.progress)
def on_cancel(self, event):
"""Cancels the conversion process"""
self.abort = True
print 'Click'
# pub.unsubscribe(self.if_abort, 'cancel')
def __del__(self):
pass
########################################################################################
class MainFrame(wx.Frame):
# ----------------------------------------------------------------------
def __init__(self,parent):
wx.Frame.__init__(self,parent)
# Add a panel so it looks the correct on all platforms
panel = wx.Panel(self, wx.ID_ANY)
self.btn = btn = wx.Button(panel, label="Start Thread")
btn.Bind(wx.EVT_BUTTON, self.onButton)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(btn, 0, wx.ALL | wx.CENTER, 5)
panel.SetSizer(sizer)
# ----------------------------------------------------------------------
def onButton(self, event):
btn = event.GetEventObject()
btn.Disable()
WorkThread()
self.dlg = ProgressDialog()
self.dlg.ShowModal()
btn.Enable()
app = wx.App()
frame = MainFrame(None)
frame.Show(True)
# start the applications
app.MainLoop()
答案 0 :(得分:0)
你需要一个方法来阻止它 你也应该等它停下来 以下是使用您的代码的选项:
from threading import Thread
import wx
from wx.lib.pubsub import pub
import time
class WorkThread(Thread):
def __init__(self):
"""Init Worker Thread Class."""
Thread.__init__(self)
self.stop_work_thread = 0
self.start() # start the thread
def run(self):
for i in range(10):
if self.stop_work_thread == 1:
break
time.sleep(1)
val = 100 / 10
wx.CallAfter(pub.sendMessage, "update", step=val)
wx.CallAfter(pub.sendMessage, "finish")
return
def stop(self):
self.stop_work_thread = 1
class ProgressDialog(wx.Dialog):
def __init__(self,parent):
wx.Dialog.__init__(self, parent)
self.parent = parent
self.abort = False
self.progress = 0
bSizer2 = wx.BoxSizer(wx.VERTICAL)
self.gauge = wx.Gauge(self, wx.ID_ANY, 100, wx.DefaultPosition, wx.DefaultSize, wx.GA_HORIZONTAL)
self.gauge.SetValue(0)
self.m_button1 = wx.Button(self, wx.ID_ANY, u"Stop Training", wx.DefaultPosition, wx.DefaultSize, 0)
bSizer2.Add(self.gauge, 0, 0, 5)
bSizer2.Add(self.m_button1, 0, 0, 5)
self.SetSizer(bSizer2)
self.Layout()
self.Centre(wx.BOTH)
## Connect Events
self.m_button1.Bind(wx.EVT_BUTTON, self.on_cancel)
pub.subscribe(self.updateProgress, "update")
pub.subscribe(self.on_finish, "finish")
def updateProgress(self, step):
self.progress += step
self.gauge.SetValue(self.progress)
def on_cancel(self, event):
"""Cancels the conversion process"""
self.parent.work.stop()
self.parent.work.join()
pub.unsubscribe(self.updateProgress, "update")
pub.unsubscribe(self.on_finish, "finish")
self.Destroy()
# pub.unsubscribe(self.if_abort, 'cancel')
def on_finish(self):
"""conversion process finished"""
pub.unsubscribe(self.updateProgress, "update")
pub.unsubscribe(self.on_finish, "finish")
self.Close()
def __del__(self):
pass
########################################################################################
class MainFrame(wx.Frame):
# ----------------------------------------------------------------------
def __init__(self,parent):
wx.Frame.__init__(self,parent)
# Add a panel so it looks the correct on all platforms
self.panel = wx.Panel(self, wx.ID_ANY)
self.btn = btn = wx.Button(self.panel, label="Start Thread")
btn.Bind(wx.EVT_BUTTON, self.onButton)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(btn, 0, wx.ALL | wx.CENTER, 5)
self.panel.SetSizer(sizer)
# ----------------------------------------------------------------------
def onButton(self, event):
btn = event.GetEventObject()
btn.Disable()
self.panel.work = WorkThread()
self.dlg = ProgressDialog(self.panel)
self.dlg.ShowModal()
btn.Enable()
app = wx.App()
frame = MainFrame(None)
frame.Show(True)
# start the applications
app.MainLoop()