2015-08-17 22 views
1

我有一個控制某些硬件的wxPython gui。 我需要一個按鈕在功能運行時禁用。該功能還接收參數值如何正確使用wxPython將值繼承到線程類中

讓我們說,我有這個功能綁定到一個按鈕按下:

def button_press(self, event): 

     in_val = self.num_in.GetValue() #grabs a value from a NumCtrl 
     TheThread(in_val) #initiates the thread with argument 
     btn = event.GetEventObject() 
     btn.Disable() #disables button 

此功能去以下螺紋類:

class TheThread(Thread): 
def __init__(self, in_val): 

    """Init Worker Thread Class.""" 
    Thread.__init__(self) 

    self.run(in_val) 

def run(self, in_val): 
    print val 
    time.sleep(5) 

    wx.CallAfter(Publisher.sendMessage, "ctrl") 
    """ 
    threadsafe method to call a pub.subscribe that runs a 
    function to re-enable button 
    """ 

這工作不正常,因爲gui在功能運行期間凍結,並且按鈕沒有正確禁用。

我該如何正確地繼承這個參數才能讓它正常運行? 也許涉及self.start()方法的東西?

回答

2

對於start方法的猜測,你是對的。

run是在新線程上調用的方法,而start是您想要調用的方法,以告知Thread對象執行該操作。

在您的例子,通過調用run自己正在呼叫的主線程run並沒有線程正在發生的一切。 (該線程永遠不會啓動)

class TheThread(Thread): 
    def __init__(self, in_val): 

     """Init Worker Thread Class.""" 
     Thread.__init__(self) 

     self.in_val = in_val 
     self.start() 

    def run(self): 
     print self.in_val 
     time.sleep(5) 

     wx.CallAfter(Publisher.sendMessage, "ctrl") 
     """ 
     threadsafe method to call a pub.subscribe that runs a 
     function to re-enable button 
     """ 
+0

謝謝!所以我想在線程的情況下,你不會將參數值傳遞給下一個函數,而是將它作爲self.var傳遞給函數?是否有一個原因? –

+0

@ supremus_58對,'run'方法本身不帶任何參數。但是,如果您傳遞目標函數,您也可以提供參數,並且默認的'Thread.run'方法將使用您提供的參數調用目標可調用。 't = Thread(target = my_func,args =(「arg1」,「arg2」),kwargs = {「kwarg1」:「val」})''t.start()'' – GP89

0

不要從__init__()調用run()run()睡5秒鐘然後返回。但是__init__()需要在對象完全實例化之前返回,並且調用代碼阻塞直到__init__()返回。對於大多數函數調用來說也是如此,即調用代碼在繼續執行之前等待函數返回(或者在發生器的情況下產生)。

要解決此問題__init__()刪除調用運行(),並調用start()方法上TheThread()實例:

def button_press(self, event): 
    in_val = self.num_in.GetValue() 
    TheThread(in_val).start() 
    btn = event.GetEventObject() 
    btn.Disable() #disables button 

class TheThread(Thread): 
    def __init__(self, in_val): 
     """Init Worker Thread Class.""" 
     super(TheThread, self).__init__() 
     self.in_val = in_val 

    def run(self): 
     print self.in_val 
     time.sleep(5) 
     wx.CallAfter(Publisher.sendMessage, "ctrl") 

您還可以撥打中__init__()線程的start()方法,但是,更常見方法是調用線程實例本身的啓動。這是一個更靈活的解決方案,因爲該線程可以先創建並隨後開始,例如,如果您有一個線程池,其中首先創建所有線程,然後一起啓動。