【问题标题】:wxpython pass variable to callback event. Lambda landwxpython 将变量传递给回调事件。拉姆达地
【发布时间】:2014-05-17 07:43:33
【问题描述】:

我不了解 lambdas 吗?或者GetValue() 我试图传递的变量是空的。最好为此创建一个global palletNumberText 吗? 在createWidgets() 中,我绑定了一个EVT_TEXT,这样当在TextCtrl 中输入文本时,它应该调用onPalletNumberText(event, variable_here)

以下行是我遇到困难的地方:

palletNumberText.Bind(wx.EVT_TEXT, lambda event, temp_str=palletNumberText.GetValue(): self.onPalletNumberText( event, temp_str ))

在这里面 代码片段:

class ClassName(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title)
        self.panel = wx.Panel(self)
        self.PhotoMaxSize = 240
        self.createWidgets()
        self.Show()

    def createWidgets(self):
        .
        .
        .
        palletNumberText = wx.TextCtrl(self.panel, size=(80,-1))
        # THIS LINE
        palletNumberText.Bind(wx.EVT_TEXT, lambda event, temp_str=palletNumberText.GetValue(): self.onPalletNumberText( event, temp_str ))
        .
        .
        .

    def onPalletNumberText(self, event, palletNumber):
        '''
        save palletNumbertTxt Value when text is entered
        '''
        print palletNumber
        print "This is a test"
        # Store Value

        return

我看过的读物:

但是我的结果:

谢谢。

【问题讨论】:

  • 您在 lambda 中使用可选参数是否有原因? wxPython 中的事件处理函数只在事件中调用,因此temp_str 参数永远不会被赋予一个值,并且总是具有默认值。

标签: python user-interface lambda wxpython


【解决方案1】:

问题是您在 lambda 中调用 GetValue 方法。这会立即执行,这意味着它将在文本控件显示之前从文本控件中获取值。换句话说,它将永远是空的。每次事件触发时都不会调用它。

相反,您应该只在事件处理程序本身内部调用 GetValue():

import wx

class ClassName(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title)
        self.panel = wx.Panel(self)
        self.PhotoMaxSize = 240
        self.createWidgets()
        self.Show()

    def createWidgets(self):
        self.palletNumberText = wx.TextCtrl(self.panel, size=(80,-1))

        self.palletNumberText.Bind(wx.EVT_TEXT, self.onPalletNumberText)


    def onPalletNumberText(self, event):
        '''
        save palletNumbertTxt Value when text is entered
        '''
        print self.palletNumberText.GetValue()
        print "This is a test"
        # Store Value

        return

#----------------------------------------------------------------------
if __name__ == "__main__":
    app = wx.App(False)
    frame = ClassName(None, "Test")
    app.MainLoop()

【讨论】:

  • 这是有道理的,但 lambda 也是如此。 lambda 对程序员来说是个难点吗?为什么“应该”我只是将GetValue() 放在事件处理程序中。只是好奇。谢谢大家的帮助。
  • 对于这个问题,我认为它更有意义。有时您确实想使用 lambda 将某些内容传递给事件处理程序。这不是正常的 wxPython 语法。像这样使用 lambdas 更像是 Tkinter 类型的东西。这本身还不错,你只是不会看到大多数 wxPython 程序员完成了很多工作。
【解决方案2】:

问题确实在您发布的那一行。问题是temp_str 的默认值是在调用Bind 方法时评估的,而不是在触发事件时评估的。绑定事件时palletNumberText 字段为空,因为您刚刚创建了palletNumberText 控件。

这行和下面两行效果一样:

default_value = palletNumberText.GetValue() # will always be "", you've only just created it 
palletNumberText.Bind(wx.EVT_TEXT, lambda event, temp_str=default_value: self.onPalletNumberText( event, temp_str ))

解决此问题的一种方法是将调用 palletNumberText.GetValue() 移动到 lambda 的主体中,并为 temp_str 参数使用默认值,例如 None

palletNumberText.Bind(wx.EVT_TEXT, lambda event, temp_str=None: self.onPalletNumberText( event, palletNumberText.GetValue() if temp_str is None else temp_str ))

但是,这行代码变得很长,您最好创建一个函数,而不是尝试将太多代码塞进 lambda。另一种选择可能是将palletNumberText 设为ClassName 类的属性,然后让self.onPalletNumberText 方法检查其内容。

【讨论】:

    【解决方案3】:

    您的默认参数在开始时进行评估

    lambda event, temp_str=None: self.onPalletNumberText( event, 
                                 temp_str if temp_str is not None else palletNumberText.GetValue() )
    

    我觉得可以

    但你真正想要的可能更像是

    lambda event, txt_instance=palletNumberText: self.onPalletNumberText( event, txt_instance.GetValue() )  
    

    【讨论】:

      猜你喜欢
      • 2011-11-13
      • 1970-01-01
      • 2014-10-03
      • 2014-01-28
      • 2012-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多