2015-08-17 2 views
1

У меня есть gui wxPython, который контролирует некоторое оборудование. Мне нужна кнопка для отключения во время работы функции. Эта функция также принимает значение аргументаКак правильно наследовать значения в классе потоков с помощью 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 right, метод 'run' не принимает никаких аргументов. Однако, если вы передаете целевую функцию, вы можете также предоставить аргументы, а метод 'Thread.run' по умолчанию будет вызывать целевой вызываемый с помощью аргументов, которые вы предоставляете. 't = Thread (target = my_func, args = (" arg1 "," arg2 "), kwargs = {" kwarg1 ":" val "})' 't.start()' – GP89

0

Не называйте run() от __init__(). 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") 

Вы также могли бы назвать start() метод Нить в пределах __init__(), однако, более общий путь - вызвать начало самого экземпляра потока. Это более гибкое решение, потому что поток может быть создан первым, а затем запущен позже, например. если у вас есть пул потоков, в котором сначала создаются все потоки, а затем начинаются вместе.

Смежные вопросы