0
我很新的wxPython的,也並不熟悉線程的概念。如果有人能爲我的問題提供信息資源或建議,我將非常感激。如何使用wx.CallAfter()返回的條件終止線程?
我創造了使用wxPython的,允許用戶輸入的運行我的腳本的GUI。由於一步需要20分鐘才能運行,因此我打算創建一個進度對話框來顯示用戶進度並允許他們中止進度。我已經使用下面的示例代碼對此進行了測試。
但是,我不能停止WorkThread即使我點擊了進度對話框的停止按鈕。我如果使用返回值從pb.sendMessage聲明試圖 1.化妝() 2.創建ProgressDialog對象WorkThread啓動時,並呼籲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()
太謝謝你了!它完美的工作!我嘗試使用與self.stop_work_thread類似的標誌來停止WorkThread中的for-loop,但當時並不奏效。是否因爲我沒有使用MainFrame作爲ProgressDialog的父項,所以它根本沒有鏈接? – paraeve
可能,但它看起來並不像有辦法阻止線程本身,只是進度條。 'on_cancel'例程現在停止線程並等待它完成('.join'語句)。 –
謝謝你的詳細回覆! – paraeve