Handling EVT_TEXT from multiple TextCtrls

This is the flip side of a question
<http://wxpython-users.1045709.n5.nabble.com/Intercepting-wx-EVT-TEXT-for-multiple-TextCtrls-td2358423.html>
that was asked a while back. I have several TextCtrls, each one accepting
input for a different variable. What I want is a compact way to get the
information from the TextCtrl into the appropriate variable. For instance,
what I /don't/ want to do is something like:

def handleText(self,event):
     widg_src = event.GetEventObject()
     if widg_src == self.grass_count_txt:
         self.model.grass_count = int(event.GetString())
     elif widg_src == self.bunny_count_txt:
         self.model.bunny_count = int(event.GetString())
     elif widg_src == self.fox_count_txt:
         self.model.fox_count = int(event.GetString())
     elif .....

What I would like is some way to "associate" each TextCtrl with its intended
little piece of data and then let my function be something very compact like

def handleText(self,event):
    event.GetEventObject().associtated_data = int(event.GetString())

and be done with it. I know this code as I have written it is impossible,
but is there some way to do something like this? Thanks.

···

--
View this message in context: http://wxpython-users.1045709.n5.nabble.com/Handling-EVT-TEXT-from-multiple-TextCtrls-tp5716938.html
Sent from the wxPython-users mailing list archive at Nabble.com.

Just subclass wx.TextCtrl and add an associated_data attribute. Although why you want the associated attribute to be set to the same object’s value I don’t really understand.

  • Mike
···

On Friday, April 12, 2013 11:53:30 AM UTC-5, bob.s wrote:

This is the flip side of a question

<http://wxpython-users.1045709.n5.nabble.com/Intercepting-wx-EVT-TEXT-for-multiple-TextCtrls-td2358423.html>

that was asked a while back. I have several TextCtrls, each one accepting

input for a different variable. What I want is a compact way to get the

information from the TextCtrl into the appropriate variable. For instance,

what I /don’t/ want to do is something like:

def handleText(self,event):

 widg_src = event.GetEventObject()

 if widg_src == self.grass_count_txt:

     self.model.grass_count = int(event.GetString())

 elif widg_src == self.bunny_count_txt:

     self.model.bunny_count = int(event.GetString())

 elif widg_src == self.fox_count_txt:

     self.model.fox_count = int(event.GetString())

 elif .....

What I would like is some way to “associate” each TextCtrl with its intended

little piece of data and then let my function be something very compact like

def handleText(self,event):

event.GetEventObject().associtated_data = int(event.GetString())

and be done with it. I know this code as I have written it is impossible,

but is there some way to do something like this? Thanks.

Yeah, I see your question. I was trying to think of "associated_data" as a
reference to self.grass_count or self.bunny_count or whatever. My line
"event.GetEventObject().associated_data = int(event.GetString())" was
supposed to be a short hand for something like, "OK, I can just look at this
EventObject and tell from it that its input is suppsed to be funneled ...
let's see ... /here/ so I'll just go ahead and do that now." You're not the
first person I've confused. I keep trying to boil this down to bare bones
for the convenience of readers, but I guess I overdo it.

In any event, maybe I should just say, I want some compact way of sending
data from a bunch of TextCtrls to the data correct for each control without
having to write a separate method for each control, and without having to
sort through the controls in a big "if" block. Is there a way to do that?
Thanks.

···

--
View this message in context: http://wxpython-users.1045709.n5.nabble.com/Handling-EVT-TEXT-from-multiple-TextCtrls-tp5716938p5716943.html
Sent from the wxPython-users mailing list archive at Nabble.com.

bob sacamento wrote:

that was asked a while back. I have several TextCtrls, each one accepting
input for a different variable. What I want is a compact way to get the
information from the TextCtrl into the appropriate variable.
....
What I would like is some way to "associate" each TextCtrl with its intended
little piece of data and then let my function be something very compact like

def handleText(self,event):
    event.GetEventObject().associtated_data = int(event.GetString())

and be done with it. I know this code as I have written it is impossible,
but is there some way to do something like this?

As you have designed it, there is no way[1]. You can't store a
reference to those fields anywhere. However, it wouldn't take much to
make it doable. For example, if you had self.model.counts as a dict,
then you could set
    self.grass_count_txt.name = 'grass'
    self.bunny_count_txt.name = 'bunny'
    self.fox_count_txt.name = 'fox'
    ...
Then you could do:
    def handleText(self,event):
        self.model.counts[event.GetEventObject().name] =
int(event.GetString())

- - -
[1] OK, I acknowledge there is a way, but I think it's uglier. You
could do:
    self.grass_count_txt.name = 'grass_count'
    self.bunny_count_txt.name = 'bunny_count'
    self.fox_count_txt.name = 'fox_count'
...
    def handleText(self.event):
        setattr( self.model, event.GetEventObject().name,
int(event.GetString() )

···

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

TIm,

Thanks!

I prefer your first way.

So I guess setting the "name" property of the widget is the key. Did I
mention I'm very new to wxPython? Thanks again!

···

--
View this message in context: http://wxpython-users.1045709.n5.nabble.com/Handling-EVT-TEXT-from-multiple-TextCtrls-tp5716938p5716945.html
Sent from the wxPython-users mailing list archive at Nabble.com.

There is indeed - there are several ways, several involve binding
several controls to a single handler but the first few I can think
of:

  1. Use when you create the control add a reference to the control,
    (the handle that you bind), to a dictionary of the methods to call
    then in your handler use ctrl = evt.GetCtrl() then
    fn_dict.get(ctrl)()
  2. Set the name of each control and have a dictionary of names →
    functions and lookup evt.Getctrl().Name which is similar, better for
    debugging, etc., BUT means you are left with the work of maintaining
    the unique names.
  3. Add a MethodToCall member to each control at creation and do
    something like:
    if hasattr(evt.GetCtrl(), ‘MethodToCall’):
    evt.GetCtrl().MethodToCall()
    3a) as 3 but store a string in MethodToCall and exec or eval it in
    your handler.
    Both the 3 methods above could be implelented as a derived class say
    TextWithMethodCtrl 4) If you are updating your data on change to a text control data
    then you could have a DataStore member for each that the single
    handler gets the new data and stores it in the correct place, (again
    this could be a reference to the data store or a string to eval or
    pass to an update member - you could even use the standard Name
    member to store this in).
  4. If you have an update button or some such you could use the
    storing where to put the data in the control and have an array of
    references to the actual controls and update the data in a for
    loop…
    One of the tricks that Python programmers use that C/C++ programmers
    are more reluctant to use is the realisation that the data members
    that things like controls have been provided with can be simply
    added to with additional members with OR WITHOUT sub-classing the
    control type and without messing with the control source code.
    Gadget/Steve
···

On 12/04/13 18:58, bob sacamento wrote:


Yeah, I see your question. I was trying to think of "associated_data" as a
reference to self.grass_count or self.bunny_count or whatever. My line
"event.GetEventObject().associated_data = int(event.GetString())" was
supposed to be a short hand for something like, "OK, I can just look at this
EventObject and tell from it that its input is suppsed to be funneled ...
let's see ... /here/ so I'll just go ahead and do that now." You're not the
first person I've confused. I keep trying to boil this down to bare bones
for the convenience of readers, but I guess I overdo it.
In any event, maybe I should just say, I want some compact way of sending
data from a bunch of TextCtrls to the data correct for each control without
having to write a separate method for each control, and without having to
sort through the controls in a big "if" block. Is there a way to do that? Thanks.
--
View this message in context: Sent from the wxPython-users mailing list archive at Nabble.com.


Steve Gadget Barnes

http://wxpython-users.1045709.n5.nabble.com/Handling-EVT-TEXT-from-multiple-TextCtrls-tp5716938p5716943.html

Sorry - In the above you need to
replace GetCtrl with
didn’t take the time to check the docs
before typing.

···

On 13/04/13 07:47, Steve Barnes wrote:

  There is indeed - there are several ways, several involve binding

several controls to a single handler but the first few I can think
of:

  1. Use when you create the control add a reference to the control,
    (the handle that you bind), to a dictionary of the methods to call
    then in your handler use ctrl = evt.GetCtrl() then
    fn_dict.get(ctrl)()
  2. Set the name of each control and have a dictionary of names
    → functions and lookup evt.Getctrl().Name which is similar,
    better for debugging, etc., BUT means you are left with the work
    of maintaining the unique names.
  3. Add a MethodToCall member to each control at creation and do
    something like:
    if hasattr(evt.GetCtrl(), ‘MethodToCall’):
    evt.GetCtrl().MethodToCall()
    3a) as 3 but store a string in MethodToCall and exec or eval it in
    your handler.
    Both the 3 methods above could be implelented as a derived class
    say TextWithMethodCtrl 4) If you are updating your data on change to a text control data
    then you could have a DataStore member for each that the single
    handler gets the new data and stores it in the correct place,
    (again this could be a reference to the data store or a string to
    eval or pass to an update member - you could even use the standard
    Name member to store this in).
  4. If you have an update button or some such you could use the
    storing where to put the data in the control and have an array of
    references to the actual controls and update the data in a for
    loop…
    One of the tricks that Python programmers use that C/C++
    programmers are more reluctant to use is the realisation that the
    data members that things like controls have been provided with can
    be simply added to with additional members with OR WITHOUT
    sub-classing the control type and without messing with the control
    source code.
    Gadget/Steve
    – You received this message because you are subscribed to the Google
    Groups “wxPython-users” group.
    To unsubscribe from this group and stop receiving emails from it,
    send an email to .
    For more options, visit .
    GetEventObject


Steve Gadget Barnes

    On 12/04/13 18:58, bob sacamento

wrote:


Yeah, I see your question. I was trying to think of "associated_data" as a
reference to self.grass_count or self.bunny_count or whatever. My line
"event.GetEventObject().associated_data = int(event.GetString())" was
supposed to be a short hand for something like, "OK, I can just look at this
EventObject and tell from it that its input is suppsed to be funneled ...
let's see ... /here/ so I'll just go ahead and do that now." You're not the
first person I've confused. I keep trying to boil this down to bare bones
for the convenience of readers, but I guess I overdo it.
In any event, maybe I should just say, I want some compact way of sending
data from a bunch of TextCtrls to the data correct for each control without
having to write a separate method for each control, and without having to
sort through the controls in a big "if" block. Is there a way to do that? Thanks.
--
View this message in context: Sent from the wxPython-users mailing list archive at Nabble.com.

http://wxpython-users.1045709.n5.nabble.com/Handling-EVT-TEXT-from-multiple-TextCtrls-tp5716938p5716943.html


Steve Gadget Barnes

wxpython-users+unsubscribe@googlegroups.com
https://groups.google.com/groups/opt_out

It would be easier as long as an extra
argument can be passed to the handler. Python lambda function does this trick:

def handleText(self, event, associtated_data):
    associtated_data = int(event.GetString())

When binding, write codes like:

self.grass_count_txt.Bind(wx.EVT_TEXT, lambda e: self.handleText(e, self.model.grass_count))
self.bunny_count_txt.Bind(wx.EVT_TEXT, lambda e: self.handleText(e, self.model.bunny_count))
...

bob sacamento wrote:

So I guess setting the "name" property of the widget is the key. Did I
mention I'm very new to wxPython?

Note that I was suggesting you add your own property. You can add
whatever properties you want to these objects. That's the beauty of Python.

···

--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.