2016-04-28 17 views
0

Meine Einschränkungen sind mein schlimmster Feind, aber bestest Lernpartner.Aufruf einer Klassenfunktion von einer anderen Klasse

Ich habe zwei Klassen:

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 

Und:

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()" 

ich startStop von rufen im WorkerThread einen Weg finden wollen. Ich habe versucht this und konnte es auch nicht funktionieren.

EDIT: Abschlussarbeits Code unter

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" 

Antwort

1

Sie könnten einen Hinweis auf startStop und rufen Sie die Referenz aus der Thread-Klasse als eine Option übergeben. Ohne mehr Code zu sehen/wie Ihr Code strukturiert ist, ist es schwer für andere Optionen zu sagen.

Hier ist ein erfundenes Beispiel der ehemaligen. Sie müssen die Dinge nicht so herumreichen, Sie könnten den Thread in VolumePanel aufrufen und self.startStop übergeben.

Auch worker ist undefined und so ist proc, wenn dies ein Teil von wxpython, die ich nicht vertraut bin.

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

Ich kann die 'def startStop' passieren zu' WorkerThread (Thema) '? Ich fügte das Ereignis hinzu, das den "WorkerThread" oben startet, um zu sehen, ob das mit Klarheit hilft. – chow

+0

Sie lösten das, was ich wissen musste - ich fügte der '__init__' Deklaration' func' hinzu und fügte ein globales hinzu und es funktionierte. :) Aktualisiert, funktionierender Code, oben. – chow

+0

Wenn Sie es zu einem Attribut machen, brauchen Sie das Globale nicht. 'self.function' und' self.function() '. Auch 'return' ist am Ende von' run' unnötig. Sie können Ihre beiden Bedingungen zusammenführen, um das 'return None' zu ​​vermeiden. 'während Arbeiter und nicht selbst. ToKill' – Pythonista

0

Sie können auch die anrufende Klasse auf den Thread passs etwa so:

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()" 

Beachten Sie, dass wir wx.CallAfter() verwenden, anstatt nur direkt die Funktion aufrufen. Wenn wir es direkt aufrufen, wird es tatsächlich aus dem Thread statt MainThread aufgerufen. Dies kann manchmal ein Problem sein, abhängig davon, was Sie gerade tun.

Wenn wir den aktuellen Thread ausdrucken (mit threading.current_thread()) ohne wx.CallAfter, erhalten wir

<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)> 

jedoch mit wx.CallAfter, wir bekommen

<_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)> 
Verwandte Themen