【问题标题】:How to proper inherit values into thread class with wxPython如何使用 wxPython 将值正确地继承到线程类中
【发布时间】:2015-08-17 09:27:43
【问题描述】:

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

假设我有这个绑定到按钮按下的函数:

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

【问题讨论】:

    标签: python python-2.7 wxpython wxwidgets


    【解决方案1】:

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

    【讨论】:

    • 谢谢!所以我猜在线程的情况下,你不会将参数值传递给下一个函数,而是将它作为 self.var 传递给函数?这是有原因的吗?
    • @supremus_58 对,run 方法本身不接受任何参数。但是,如果您传递一个目标函数,您也可以提供参数,默认的Thread.run 方法将使用您提供的参数调用目标可调用对象。 t = Thread(target=my_func, args=("arg1", "arg2"), kwargs={"kwarg1":"val"})t.start()
    【解决方案2】:

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

    要纠正此问题,请从 __init__() 中删除对 run() 的调用,并在 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。这是一个更灵活的解决方案,因为线程可以先创建,然后再启动,例如如果您有一个线程池,其中所有线程首先创建然后一起启动。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-13
      • 1970-01-01
      相关资源
      最近更新 更多