wxpython将变量传递给回调事件。 Lambda土地

时间:2014-04-04 20:14:26

标签: python user-interface lambda wxpython

我不了解lambda的内容吗?或者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

我看过的读物:

然而我的结果是:

results

感谢。

3 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

问题确实在你发布的那一行。问题是在调用temp_str方法时评估Bind的默认值,而不是在触发事件时评估。{1}}的默认值。绑定事件时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的主体,并使用None的默认值作为temp_str参数:

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方法检查其内容。

答案 2 :(得分: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()