Question

Am I not understanding something about lambdas? Or GetValue() the variable that I am trying to pass is empty. Is it best to just create a global palletNumberText for this? In createWidgets() I am binding an EVT_TEXT so that when text is entered into the TextCtrl it should call onPalletNumberText(event, variable_here)

The following line is where I am having difficulties:

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

Inside this Code Snippet:

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

Readings that I have looked at:

However my results:

results

Thanks.

Was it helpful?

Solution 3

The problem is that you are calling the GetValue method inside your lambda. That executes immediately which means it will grab the value from the text control before it's even shown. In other words, it will always be empty. It is not called every time the event fires.

Instead, you should just call GetValue() inside the event handler itself:

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

OTHER TIPS

your default argument is evaluated at start time

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

I think would work

but what you really want is probably something more like

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

The problem is indeed on the the line you posted. The problem is that the default value for the temp_str is evaluated when the Bind method is called, and not when the event is fired. The palletNumberText field is empty when the event is being bound, because you've only just created the palletNumberText control.

This line has the same effect as the following two:

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

One way around the problem is to move the call to palletNumberText.GetValue() into the body of the lambda, and use a default value such as None for the temp_str parameter:

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

However, this line is getting quite long and you may be better creating a function instead of trying to cram too much code into a lambda. Another alternative might be to make palletNumberText an attribute of your ClassName class and then have your self.onPalletNumberText method check its contents.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top