2010-08-31 59 views
1

我剛剛用我的noob方式結束一個線程,但我不知道爲什麼它不起作用。有人請幫我嗎?如何結束一個線程這種方式不工作?

這裏是我的示例代碼:

import wx 
import thread 
import time 
import threading 

class TestFrame(wx.Frame): 
    def __init__(self): 
     wx.Frame.__init__(self, parent = None, id = -1, title = "Testing", pos=(350, 110), size=(490, 200), style=wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.MINIMIZE_BOX) 
     self.panel = wx.Panel(self) 

     self.stop = False 

     self.StartButton = wx.Button(parent = self.panel, id = -1, label = "Start", pos = (110, 17), size = (50, 20)) 
     self.MultiLine = wx.TextCtrl(parent = self.panel, id = -1, pos = (38, 70), size = (410, 90), style = wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_AUTO_URL) 


     self.Bind(wx.EVT_BUTTON, self.OnStart, self.StartButton) 
     self.Bind(wx.EVT_CLOSE, self.OnClose) 

    def OnStart(self, event): 
     self.StartButton.Disable() 
     self.NewThread = threading.Thread(target = self.LongRunning) 
     self.NewThread.start() 

    def OnClose(self, event): 
     self.stop = True 
     BusyBox = wx.BusyInfo("Just a moment please!", self) 
     wx.Yield() 

     while True: 
      try: 
       if not self.NewThread.isAlive(): 
        self.Destroy() 
        break 
       time.sleep(0.5) 
      except: 
       self.Destroy() 
       break 

    def LongRunning(self): 
     Counter = 1 

     while True: 
      time.sleep(2) 
      print "Hello, ", Counter 
      self.MultiLine.AppendText("hello, " + str(Counter) + "\n") #If you comment out this line, everything works fine. Why can't I update the fame after I hit the close button? 
      Counter = Counter + 1 
      if self.stop: 
       break 

class TestApp(wx.App): 
    def OnInit(self): 
     self.TestFrame = TestFrame() 
     self.TestFrame.Show() 
     self.SetTopWindow(self.TestFrame) 
     return True 

def main(): 
    App = TestApp(redirect = False) 
    App.MainLoop() 

if __name__ == "__main__": 
    main() 

正如你可以在我的代碼中看到,有一個在線程無限循環,我告訴線程要做的就是打破循環的,一旦我點擊關閉按鈕。但問題是,每當我點擊關閉按鈕時,似乎代碼卡在self.MultiLine.AppendText("hello, " + str(Counter) + "\n")行,我不知道爲什麼。任何人都可以幫忙?

+0

'if not self.NewThread.isAlive():' 你正在使用哪個版本的python? 2.5?你應該先更新你的python版本! – 2010-08-31 14:00:23

+0

我在Python 2.7上已經 – Shane 2010-08-31 15:04:49

回答

2

嘗試更新多在使用一個線程安全的方法,如wx.CallAfter

def LongRunning(self): 
    Counter = 1 

    while True: 
     time.sleep(2) 
     print "Hello, ", Counter 

     wx.CallAfter(self.updateMultiLine, "hello, " + str(Counter) + "\n") 
     Counter = Counter + 1 
     if self.stop: 
      break 

def updateMultiLine(self, data): 
    self.MultiLine.AppendText(data) 
+0

你已經回答了我的幾個虛擬問題,所以非常感謝你的耐心! – Shane 2010-08-31 16:38:11

+0

@Shane:您的歡迎,隨時樂意幫助! :) – volting 2010-08-31 19:33:30

1

通常使用GUI工具包,只有一個線程應該訪問GUI功能。一個例外是wx.CallAfter

正如你(應該)知道,軟件缺陷可以分爲三組:

  1. 你的錯誤。
  2. 他們的錯誤。
  3. 線程。

;)

+0

我只是在一個線程啓動時禁用了啓動按鈕,這是一個訪問GUI功能的線程,仍然有同樣的問題......會有人給我一個詳細的理由嗎? – Shane 2010-08-31 15:14:28

+1

@Shane:「一個線程」並不意味着「一次一個線程」。這意味着無論什麼線程啓動事件循環都應該是直接更新UI的唯一線程。您不能創建單獨的線程,然後切換到更新UI的那個線程。 – 2010-08-31 18:18:39