2015-12-16 55 views
1

[問題] 我想停止調用函數的線程。如何停止wxpython中的線程?

[CODE]

import wx 
app = wx.App(redirect=False) 
top = wx.Frame(None) 
sizer = wx.GridBagSizer() 
import threading 
shutdown_event = threading.Event() 
def testFunction(event): 
    while not shutdown_event.is_set(): 
     import time 
     for i in range(2): 
      print ('win','r') 
      time.sleep (0.5) 
      print ('abc') 
      time.sleep (0.5) 
      print ('enter') 
      time.sleep (0.5) 
      print 'sleep' 
      time.sleep (3) 


def startThread(event): 
    import threading 
    th = threading.Thread(target=testFunction, args=(event,)) 
    th.start() 


def stopThread(event): 
    shutdown_event.set() 



addButton = wx.Button(top, -1, "Start", style=wx.BU_EXACTFIT) 
sizer.Add(addButton, (6, 8), (2, 14), wx.EXPAND) 
stopButton = wx.Button(top, -1, "Stop", style=wx.BU_EXACTFIT) 
sizer.Add(stopButton, (8, 9), (2, 14), wx.EXPAND) 
top.Bind(wx.EVT_BUTTON, startThread, addButton) 
top.Bind(wx.EVT_BUTTON, stopThread, stopButton) 
top.Sizer = sizer 
top.Sizer.Fit(top) 
top.Show() 
app.MainLoop() 

[CURRENT]如果我點擊 「停止」 按鈕 什麼也沒有發生。

[DESIRED] 如果點擊「停止」按鈕,函數「testFunction」應該停止。

回答

1

是的,它正在停止,事情是它沒有被打斷,它正在運行,直到腳本的兩次迭代都完成,然後while condition被選中,然後停止。

import wx 
app = wx.App(redirect=False) 
top = wx.Frame(None) 
sizer = wx.GridBagSizer() 
import threading 
shutdown_event = threading.Event() 
def testFunction(event): 
    while not shutdown_event.is_set(): 
     import time 
     for i in range(2): 
      print u"Iteración {}".format(i) 
      if shutdown_event.is_set(): 
       break; 
      print ('win','r') 
      time.sleep (0.1) 
      if shutdown_event.is_set(): 
       break; 
      print ('abc') 
      time.sleep (0.1) 
      if shutdown_event.is_set(): 
       break; 
      print ('enter') 
      time.sleep (0.1) 
      if shutdown_event.is_set(): 
       break; 
      print 'sleep' 
      time.sleep (0.5) 
     print u"Fin de ejecución\n\n" 
    print u"Se detuvo la ejecución.\n\n" 


def startThread(event): 
    import threading 
    th = threading.Thread(target=testFunction, args=(event,)) 
    th.start() 


def stopThread(event): 
    shutdown_event.set() 


addButton = wx.Button(top, -1, "Start", style=wx.BU_EXACTFIT) 
sizer.Add(addButton, (6, 8), (2, 14), wx.EXPAND) 
stopButton = wx.Button(top, -1, "Stop", style=wx.BU_EXACTFIT) 
sizer.Add(stopButton, (8, 9), (2, 14), wx.EXPAND) 
top.Bind(wx.EVT_BUTTON, startThread, addButton) 
top.Bind(wx.EVT_BUTTON, stopThread, stopButton) 
top.Sizer = sizer 
top.Sizer.Fit(top) 
top.Show() 
app.MainLoop() 
+0

我理解你的觀點。我的目標是當我點擊停止btn時停止功能。換句話說,如果該功能總共有5個步驟,並且當該功能在步驟3時單擊「停止」,則不應再執行步驟4。 – george

+0

然後你必須在每一步之前添加一個「break」或者「continue」。 – tglaria

+0

[plus1],因爲我懶得查找如何最好的擺脫''while''循環:D – nepix32

1

如果你想在你的線程中有一個更精細的粒度,你必須實現它。使用類似的東西,用yield聲明拆分生成器語句中的不同步驟:

def testFunction(event): 
    def inner_gen(): 
     print ('win','r') 
     time.sleep (0.5) 
     yield 
     print ('abc') 
     time.sleep (0.5) 
     yield 
     print ('enter') 
     time.sleep (0.5) 
     yield 
     print 'sleep' 
     time.sleep (3) 
     yield 

    while True: 
     for _ in range(2): 
      for _ in inner_gen(): 
       if shutdown_event.is_set(): 
        shutdown_event.clear() 
        return 
+0

我喜歡這個:D – tglaria