从另一个 Class 调用一个 Class 函数

Calling a Class function from another Class

我的局限是我最大的敌人,却是我最好的学习伙伴。

我有两个类:

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

我想找到一种从 WorkerThread 中调用 startStop 的方法。我试过 this 也无法正常工作。

编辑:下面的最终工作代码

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"

您可以将引用传递给 startStop 并从线程中调用引用 class 作为一种选择。没有看到更多代码/你的代码是如何构建的,很难说其他选项。

这是前者的人为示例。您不必以这种方式传递事物,您可以调用 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()

您还可以像这样将调用 class 传递给线程:

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 调用的。这有时可能是个问题,具体取决于您在做什么。

如果我们在没有wx.CallAfter的情况下打印出当前线程(threading.current_thread()),我们得到

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