How to pass a text control value into an event handler

I’ve got a very simple application I’m trying to write. It’s a window a panel with 3 widgets on it, a text label, a TextCtrl, and a button. When I press the button, it runs an event handler. I want to pass (and use) the value of the TextCtrl field inside that button event handler and can’t figure out how.

I have read some examples that use lambda functions, but I can’t seem to get my head around them. The examples I find all seem to centre around using a single event handler for multiple buttons. This is even simpler I would think. Just pass the current value of the text ctrl (a string) into the handler for the button press. But for the life of me I can’t figure it out. My code is attached, hopefully someone can make it a little more clear what the best way to accomplish this is.

Thanks.

RQ

projectlookup2.py (2.56 KB)

Assuming the event handler is a method of the panel containing the button and the text control, you can access it directly.

It may be possible to create a PyControl with the button and text control and then all the references would be in the control.

I think looking at the code in the filebrowsebutton control in wx.lib would help you develop that sort of thing, but depending on your purpose,

that may be overcoding things.

Josh

One simple way is if you rename your textCtrl to self.inputTxtOne
(that is, you make it "global" to the whole class), you can just
access it in the event handler for the button.

def onSearch(self,event):
        value = self.inputTxtOne.GetValue()

Che

···

On Mon, Jan 17, 2011 at 10:20 PM, Richard Querin <rfquerin@gmail.com> wrote:

I've got a very simple application I'm trying to write. It's a window a
panel with 3 widgets on it, a text label, a TextCtrl, and a button. When I
press the button, it runs an event handler. I want to pass (and use) the
value of the TextCtrl field inside that button event handler and can't
figure out how.
I have read some examples that use lambda functions, but I can't seem to get
my head around them. The examples I find all seem to centre around using a
single event handler for multiple buttons. This is even simpler I would
think. Just pass the current value of the text ctrl (a string) into the
handler for the button press. But for the life of me I can't figure it out.

I can’t seem to access it from the event handler as you suggest. I receive this at the point where I try to use it:

Traceback (most recent call last):

File “projectlookup2.py”, line 59, in onSearch

checkstring = self.inputTxtOne.GetValue()

AttributeError: ‘MyFrame’ object has no attribute ‘inputTxtOne’

Don’t the controls have to be created outside of the constructor but within the class for your suggestion to work?

RQ

···

On Tue, Jan 18, 2011 at 12:54 AM, C M cmpython@gmail.com wrote:

One simple way is if you rename your textCtrl to self.inputTxtOne

(that is, you make it “global” to the whole class), you can just

access it in the event handler for the button.

def onSearch(self,event):

    value = self.inputTxtOne.GetValue()

Che

Sorry, you did step 2 of the suggestioin, but not step 1, which is
renaming your textCtrl. I didn't write the code for that part, but it
would be to first change your line 13 to this:

        self.inputTxtOne = wx.TextCtrl(panel,wx.ID_ANY,'default')

and then (step 2) change the handler as I showed before:

def onSearch(self,event):
       value = self.inputTxtOne.GetValue()

The point is, when you name an object self.object as opposed to just
object, you make it accessible from any other function in the class.
(That is, as long as "self" refers to the instance of your class...but
in Python that is the convention and you should stick with it).

Che

···

On Tue, Jan 18, 2011 at 6:31 AM, Richard Querin <rfquerin@gmail.com> wrote:

On Tue, Jan 18, 2011 at 12:54 AM, C M <cmpython@gmail.com> wrote:

One simple way is if you rename your textCtrl to self.inputTxtOne
(that is, you make it "global" to the whole class), you can just
access it in the event handler for the button.

def onSearch(self,event):
value = self.inputTxtOne.GetValue()

Che

I can't seem to access it from the event handler as you suggest. I receive
this at the point where I try to use it:
Traceback (most recent call last):
File "projectlookup2.py", line 59, in onSearch
checkstring = self.inputTxtOne.GetValue()
AttributeError: 'MyFrame' object has no attribute 'inputTxtOne'
Don't the controls have to be created outside of the constructor but within
the class for your suggestion to work?

Actually I did that after your first reply and it didn’t work. But after looking at it again I finally realized that I had forgotten to use the ‘self’ reference when I did the Add to the boxsizer. Now it works! Brilliant. Thanks so much.

RQ

···

On Tue, Jan 18, 2011 at 8:38 AM, C M cmpython@gmail.com wrote:

Sorry, you did step 2 of the suggestioin, but not step 1, which is

renaming your textCtrl.

Unless I'm mistaken, I don't that's what happened; I think if that
were true you would have gotten a different error message, one that
looked like this:

  File "projectlookup2.py", line 20, in __init__
    inputOneSizer.Add(inputTxtOne,0,wx.ALL,5)
NameError: global name 'inputTxtOne' is not defined

The point is, your error message matters, as it will tell you where in
your code Python is having trouble matching a name you are using to an
object it knows about.

But yes, you would have to change the name to self.inputTxtOne
everywhere you use it. You can use find/replace in your IDE to do
this, or by hand, or I use Bicycle Repairman to rename things
sometimes.

Che

···

On Tue, Jan 18, 2011 at 9:28 AM, Richard Querin <rfquerin@gmail.com> wrote:

On Tue, Jan 18, 2011 at 8:38 AM, C M <cmpython@gmail.com> wrote:

Sorry, you did step 2 of the suggestioin, but not step 1, which is
renaming your textCtrl.

Actually I did that after your first reply and it didn't work. But after
looking at it again I finally realized that I had forgotten to use the
'self' reference when I did the Add to the boxsizer. Now it works!
Brilliant. Thanks so much.
RQ

I sometimes just alias stuff. Like if I've done a bunch of work
without the self and then realize I need it, I'll just do this:

self.myTextCtrl = myTextCtrl

Although nowadays, my IDE can do a pretty good search and replace.

- Mike

···

On Jan 18, 9:36 am, C M <cmpyt...@gmail.com> wrote:

On Tue, Jan 18, 2011 at 9:28 AM, Richard Querin <rfque...@gmail.com> wrote:
> On Tue, Jan 18, 2011 at 8:38 AM, C M <cmpyt...@gmail.com> wrote:

>> Sorry, you did step 2 of the suggestioin, but not step 1, which is
>> renaming your textCtrl.

> Actually I did that after your first reply and it didn't work. But after
> looking at it again I finally realized that I had forgotten to use the
> 'self' reference when I did the Add to the boxsizer. Now it works!
> Brilliant. Thanks so much.
> RQ

Unless I'm mistaken, I don't that's what happened; I think if that
were true you would have gotten a different error message, one that
looked like this:

File "projectlookup2.py", line 20, in __init__
inputOneSizer.Add(inputTxtOne,0,wx.ALL,5)
NameError: global name 'inputTxtOne' is not defined

The point is, your error message matters, as it will tell you where in
your code Python is having trouble matching a name you are using to an
object it knows about.

But yes, you would have to change the name to self.inputTxtOne
everywhere you use it. You can use find/replace in your IDE to do
this, or by hand, or I use Bicycle Repairman to rename things
sometimes.

Che

That is the message I got. Whether I read it closely enough at the time is entirely another matter. :wink:

RQ

···

On Tue, Jan 18, 2011 at 10:36 AM, C M cmpython@gmail.com wrote:

Unless I’m mistaken, I don’t that’s what happened; I think if that

were true you would have gotten a different error message, one that

looked like this:

File “projectlookup2.py”, line 20, in init

inputOneSizer.Add(inputTxtOne,0,wx.ALL,5)

NameError: global name ‘inputTxtOne’ is not defined