2016-04-28 2 views
0

Мои ограничения - мой злейший враг, но самый лучший обучающий приятель.Вызов функции класса из другого класса

У меня есть два класса:

class WorkerThread(Thread): 
"""Worker Thread Class.""" 
def __init__(self, notify_window): 
    """Init Worker Thread Class.""" 
    Thread.__init__(self) 
    self._notify_window = notify_window 
    self.ToKill = False 
    self._want_abort = 0 
    self.start() 

def run(self): 
    """Run Worker Thread.""" 
    while worker==True: 
     # somehow get to volumePanel.startStop() 

     if self.ToKill == True: 
      return None 
    proc.wait() 
    wx.PostEvent(self._notify_window, ResultEvent(None)) 
    return 

А:

class VolumePanel(wx.Panel): 
    #<...snip...> 
    def launchVolClick(self, event): 
     if self.bt_Launch.Label == "Enable Monitor": 
      self.worker = WorkerThread(self) 
      self.bt_Launch.Label = "Disable Monitor" 
     else: 
      self.worker.ToKill = True 
      self.bt_Launch.Label = "Enable Monitor" 

    def startStop(self): 
     print "in def startStop()" 

Я хочу найти способ вызвать startStop внутри WorkerThread. Я пробовал this и не мог заставить его работать.

EDIT: Заключительный рабочий код ниже

class WorkerThread(Thread): 
    """Worker Thread Class.""" 
    def __init__(self, notify_window, func): 
     """Init Worker Thread Class.""" 
     Thread.__init__(self) 
     self._notify_window = notify_window 
     self.ToKill = False 
     self._want_abort = 0 
     global function 
     function = func 
     self.start() 

    def run(self): 
     """Run Worker Thread.""" 
     while worker==True: 
      # somehow get to volumePanel.startStop() 
      function() 
      if self.ToKill == True: 
       return None 
     proc.wait() 
     wx.PostEvent(self._notify_window, ResultEvent(None)) 
     return 

    def launchVolClick(self, event): 
     if self.bt_Launch.Label == "Enable Volume Monitor": 
      self.worker = WorkerThread(self, self.startStop) 
      self.bt_Launch.Label = "Disable Volume Monitor" 
     else: 
      self.worker.ToKill = True 
      self.bt_Launch.Label = "Enable Volume Monitor" 

ответ

1

Вы можете передать ссылку на startStop и вызвать ссылку из класса резьбы как один из вариантов. Не видя больше кода/как ваш код структурирован, трудно сказать для других вариантов.

Вот надуманный пример первого. Вам не нужно пропускать вещи так, как вы могли бы назвать поток в VolumePanel и пройти self.startStop.

Кроме того, worker не определено, а также proc, если только это не является частью wxpython, с которой я не знаком.

from threading import Thread 

class WorkerThread(Thread): 

    def __init__(self, func): 

     Thread.__init__(self) 
     self.func = func 

    def run(self): 

     for i in range(10): 
      self.func() 

class VolumePanel: 

    def __init__(self): 

     #self.thread = WorkerThread(self.startStop) 
     #self.thread.start() #or elsewhere 
     pass 

    def startStop(self): 

     print "in def startStop()" 

vp = VolumePanel() 
thread = WorkerThread(vp.startStop) 
thread.start() 
+0

Я могу передать определение функции startStop' для ' WorkerThread (Thread) '? Я добавил событие, которое запускает «WorkerThread» выше, чтобы узнать, помогает ли это с ясностью. – chow

+0

Вы вызвали то, что мне нужно было знать - я добавил 'func' в' __init__' объявление и добавил глобальный, и это сработало. :) Обновленный, рабочий код, выше. – chow

+0

Если вы сделаете это атрибутом, вам не нужен глобальный. 'self.function' и' self.function() '. Кроме того, 'return' не нужно в конце' run'. Вы можете объединить два условия, чтобы избежать «возврата None». 'в то время как рабочий и не self.ToKill' – Pythonista

0

Вы можете также проходите мимо класс вызывающей нити так:

class WorkerThread(threading.Thread): 
    def __init__(self, parent): 
     super(WorkerThread, self).__init__() 
     self.parent = parent 

    def run(self): 
     for i in range(10): 
      wx.CallAfter(self.parent.startStop) 


class VolumePanel(object): 
    def startStop(self): 
     print "in def startStop()" 

Обратите внимание, что мы используем wx.CallAfter() вместо того, чтобы просто вызвать функцию непосредственно. Это связано с тем, что, если мы его вызываем напрямую, это фактически вызывается из потока вместо MainThread. Иногда это может быть проблемой в зависимости от того, что вы делаете.

Если распечатать текущую нить (с threading.current_thread()) без wx.CallAfter, мы получаем

<WorkerThread(Thread-1, started 6612)> 
<WorkerThread(Thread-1, started 6612)> 
<WorkerThread(Thread-1, started 6612)> 
<WorkerThread(Thread-1, started 6612)> 
<WorkerThread(Thread-1, started 6612)> 
<WorkerThread(Thread-1, started 6612)> 
<WorkerThread(Thread-1, started 6612)> 
<WorkerThread(Thread-1, started 6612)> 
<WorkerThread(Thread-1, started 6612)> 
<WorkerThread(Thread-1, started 6612)> 

Однако, с wx.CallAfter, мы получаем

<_MainThread(MainThread, started 6604)> 
<_MainThread(MainThread, started 6604)> 
<_MainThread(MainThread, started 6604)> 
<_MainThread(MainThread, started 6604)> 
<_MainThread(MainThread, started 6604)> 
<_MainThread(MainThread, started 6604)> 
<_MainThread(MainThread, started 6604)> 
<_MainThread(MainThread, started 6604)> 
<_MainThread(MainThread, started 6604)> 
<_MainThread(MainThread, started 6604)> 
Смежные вопросы