如何使用 wxPython 将值正确继承到线程 class

How to proper inherit values into thread class with wxPython

我有一个控制某些硬件的 wxPython gui。 我需要一个按钮来禁用一个功能 运行ning。该函数还接收一个参数值

假设我有这个绑定到按钮按下的功能:

    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:

    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() 方法?

您对 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
        """

不要从 __init__() 调用 run()run() 休眠 5 秒,然后休眠 return 秒。但是 __init__() 需要 return 在对象完全实例化之前,调用代码会阻塞到 __init__() return 秒。大多数函数调用都是相同的情况,即调用代码在继续执行之前等待函数 return(或在生成器的情况下产生)。

要更正此问题,请从 __init__() 中删除对 运行() 的调用并在 TheThread() 实例上调用 start() 方法:

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() 方法,但是,更常见的方法是在线程实例本身上调用 start 方法。这是一个更灵活的解决方案,因为可以先创建线程,然后再启动,例如如果您有一个线程池,其中所有线程都先创建然后一起启动。