dynamically using e.g. checkboxes and ids

Hi, sorry again a newbie question,

I like to allocate a lot of wx Gui elements and refer to them
dynamically( and be able to refer to them individually on event).
What I am doing now is really horrible:

Firstly I need a of lines like this:
ID_SpinCtrl01, ID_SpinCtrl02,ID_SpinCtrl03 =wx.NewId(),
wx.NewId(),wx.NewId()
ID_SpinCtrl04, ID_SpinCtrl05,ID_SpinCtrl06 =wx.NewId(),
wx.NewId(),wx.NewId()
ID_SpinCtrl07, ID_SpinCtrl08,ID_SpinCtrl09 =wx.NewId(),
wx.NewId(),wx.NewId()

And then I need a lot of lines like this:
      self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl01)
        self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl02)
        self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl03)
        self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl04)
        self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl05)
        self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl06)
        self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl07)
        self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl08)

Which is even worse. Obviously I tried to use RANGE but it didn't work
(syntax error).

How can I do something like this: SEMI CODE DOESN"T WORK
for x in range(0,10):
   counter = str(x)

   ID_SpinCtrl+str(x)= wx.NewID()

...sorry my notebook is more intelligent than I am, it especially sees
fit to press the enter button when I don't want to.

How can I do something like this: SEMI CODE DOESN"T WORK
for x in range(0,10):
   counter = str(x)
   if len(counter)<0: counter ="0" + counter
   ID_SpinCtrl+counter= wx.NewID()

and something like
for x in range(0,10):
   counter = str(x)
   if len(counter)<0: counter ="0" + counter
   self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl+counter)

or
   self.Bind(wx.EVT_SPINCTRL_RANGE, self.onSpinCtrl, id=ID_SpinCtrl01,
id2=ID_SpinCtrl09)

Please help. I find myself writing Python code just for inserting into
to my Python program source, I am sure this shouldn;t be the case.

TIA Samuel

Hi, sorry again a newbie question,

This is better asked to comp.lang.python ...

I like to allocate a lot of wx Gui elements and refer to them
dynamically( and be able to refer to them individually on event).
What I am doing now is really horrible:

Firstly I need a of lines like this:
ID_SpinCtrl01, ID_SpinCtrl02,ID_SpinCtrl03 =wx.NewId(),
wx.NewId(),wx.NewId()
ID_SpinCtrl04, ID_SpinCtrl05,ID_SpinCtrl06 =wx.NewId(),
wx.NewId(),wx.NewId()
ID_SpinCtrl07, ID_SpinCtrl08,ID_SpinCtrl09 =wx.NewId(),
wx.NewId(),wx.NewId()

And then I need a lot of lines like this:
self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl01)
self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl02)
self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl03)
self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl04)
self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl05)
self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl06)
self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl07)
self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl08)

Which is even worse. Obviously I tried to use RANGE but it didn't work
(syntax error).

How can I do something like this: SEMI CODE DOESN"T WORK
for x in range(0,10):
counter = str(x)

ID_SpinCtrl+str(x)= wx.NewID()

There are many alternatives and ways to work around this but if you
need the names bound to the global namespace then I suggest you to do
something like

{{{
#!python

for x in range(0,10):
exec("ID_SpinCtrl%s = wx.NewID()" % (x,))
}}}

···

On Tue, Mar 2, 2010 at 3:37 PM, samuel en <samuel110011@gmail.com> wrote:

--
Regards,

Olemis.

Blog ES: http://simelo-es.blogspot.com/
Blog EN: http://simelo-en.blogspot.com/

Featured article:
Comienza la era de la televisión 3D (el 10 de marzo ;o) -
http://feedproxy.google.com/~r/simelo-es/~3/mPcmLbduWJU/despues-del-gran-exito-del-largometraje.html

Use globals()

···

On Tue, Mar 2, 2010 at 3:44 PM, samuel en <samuel110011@gmail.com> wrote:

and something like
for x in range(0,10):
counter = str(x)
if len(counter)<0: counter ="0" + counter
self.Bind(wx.EVT_SPINCTRL, self.onSpinCtrl, id=ID_SpinCtrl+counter)

or
self.Bind(wx.EVT_SPINCTRL_RANGE, self.onSpinCtrl, id=ID_SpinCtrl01,
id2=ID_SpinCtrl09)

--
Regards,

Olemis.

Blog ES: http://simelo-es.blogspot.com/
Blog EN: http://simelo-en.blogspot.com/

Featured article:
Robots activos para Google Wave: introducción a la versión 2 de la API
- http://feedproxy.google.com/~r/simelo-es/~3/ltPGNuqYzOM/google-wave-developer-blog-introducing.html

Olemis Lang wrote:

How can I do something like this: SEMI CODE DOESN"T WORK
for x in range(0,10):
  counter = str(x)

  ID_SpinCtrl+str(x)= wx.NewID()

There are many alternatives and ways to work around this but if you
need the names bound to the global namespace then I suggest you to do
something like

{{{
#!python

for x in range(0,10):
   exec("ID_SpinCtrl%s = wx.NewID()" % (x,))
}}}

This kind of thing works, but my answer is, instead:

"don't do that!"

If you need to use "exec" or anything like it, you probably aren't handling your data the way you should -- everything in python is a reference to an object that can be stored in various ways -- use that!

Also, don't use IDs.

So, something like:

self.SpinControls =
for i in range(num_spins):
     Spin = wx.SpinCtrl(....)
     Spin.Bind(self.onSpinCtrl)
     SpinControls.append(Spin)

Now you can refer to an yof them by self.SpinControls[index]

If you need to have a single handler andle the events from all of them, you can find out which one sent the event in various ways. See:

http://wiki.wxpython.org/Passing Arguments to Callbacks

for one way.

Another way is to keep a dict of mapping from ID to controls by adding:

self.SpinControlIDs[Spin.ID]

inside your loop.

You can also access the object itself in the event handler.

Also, do read:

http://wiki.wxpython.org/wxPython%20Style%20Guide

HTH,

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

[...]

I think that this is a comment that doesn't consider what I mentioned
before, especially :

  - «There are many alternatives and ways to work around this »
  - «*****IF***** you need the names bound to the global namespace »

FWIW, you're definitely right, and I don't use it myself, unless I
need (be forced ;o) to create several bindings for parameterized
(variable | attribute) names (of course, it is always possible to
subclass ModuleType, redefine its getattr method, ... or inspect the
current frame ...)

PS: If somebody finds another way to bind parameterized variables
names to the (global | local) namespace, pls, let me know (we had a
looong thread about this some time ago @ AFPy and this was *THE*
solution, AFAICR)

···

On Tue, Mar 2, 2010 at 4:11 PM, Christopher Barker <Chris.Barker@noaa.gov> wrote:

Olemis Lang wrote:

How can I do something like this: SEMI CODE DOESN"T WORK
for x in range(0,10):
counter = str(x)

ID_SpinCtrl+str(x)= wx.NewID()

There are many alternatives and ways to work around this but if you
need the names bound to the global namespace then I suggest you to do
something like

{{{
#!python

for x in range(0,10):
exec("ID_SpinCtrl%s = wx.NewID()" % (x,))
}}}

This kind of thing works, but my answer is, instead:

"don't do that!"

--
Regards,

Olemis.

Blog ES: http://simelo-es.blogspot.com/
Blog EN: http://simelo-en.blogspot.com/

Featured article:

You might take a look at this:

The basic idea is to create a method or function that will take your
widgets, handlers, sizers or whatever, and do to them what is
necessary. If you have 9 buttons bound to one method, for example, and
need to know which button was clicked, do something like this in the
handler:

btn = evt.GetObject()
btnName = btn.GetName()
if btnName == "something":
    # do something

I think Chris Barker has written about using lambdas on this mailing
list for doing some interesting event bindings. Check the archives and
the wiki if you're interested in that.

···

On Mar 2, 3:26 pm, Olemis Lang <ole...@gmail.com> wrote:

On Tue, Mar 2, 2010 at 4:11 PM, Christopher Barker > > <Chris.Bar...@noaa.gov> wrote:
> Olemis Lang wrote:

>>> How can I do something like this: SEMI CODE DOESN"T WORK
>>> for x in range(0,10):
>>> counter = str(x)

>>> ID_SpinCtrl+str(x)= wx.NewID()

>> There are many alternatives and ways to work around this but if you
>> need the names bound to the global namespace then I suggest you to do
>> something like

>> {{{
>> #!python

>> for x in range(0,10):
>> exec("ID_SpinCtrl%s = wx.NewID()" % (x,))
>> }}}

> This kind of thing works, but my answer is, instead:

> "don't do that!"

[...]

I think that this is a comment that doesn't consider what I mentioned
before, especially :

- «There are many alternatives and ways to work around this »
- «*****IF***** you need the names bound to the global namespace »

FWIW, you're definitely right, and I don't use it myself, unless I
need (be forced ;o) to create several bindings for parameterized
(variable | attribute) names (of course, it is always possible to
subclass ModuleType, redefine its getattr method, ... or inspect the
current frame ...)

PS: If somebody finds another way to bind parameterized variables
names to the (global | local) namespace, pls, let me know (we had a
looong thread about this some time ago @ AFPy and this was *THE*
solution, AFAICR)

--
Regards,

Olemis.

-------------------
Mike Driscoll

Blog: http://blog.pythonlibrary.org

> Olemis Lang wrote:

[...]

PS: If somebody finds another way to bind parameterized variables
names to the (global | local) namespace, pls, let me know (we had a
looong thread about this some time ago @ AFPy and this was *THE*
solution, AFAICR)

You might take a look at this:

wxPython: Refactoring Your Program - Mouse Vs Python

[...]

I don't see how this will create `var1`, `var2`, `var3`, `var4`,
`var5`, `var6`, `var7`, `var8`, ... in the global namespace, and I
insist in the *IF*.

I think there's basically a miss-understanding going on here . I was
trying to reproduce the exact snippet posted by the OP . I use quite
often something like `buttonData` (but recursive ;o) , especially for
(main | popup) menus but that's not even similar to the original
question (which was about creating `var1`, `var2`, `var3`, ...)

CMIIW anyway ;o)

PS: However your blog entry will be really helpful for the OP in order
to arrange the pieces
and put them all together using a nice style (a simple list is morfe
than enough to get this
done ;o)

···

On Tue, Mar 2, 2010 at 4:46 PM, Mike Driscoll <kyosohma@gmail.com> wrote:

On Mar 2, 3:26 pm, Olemis Lang <ole...@gmail.com> wrote:

On Tue, Mar 2, 2010 at 4:11 PM, Christopher Barker >> >> <Chris.Bar...@noaa.gov> wrote:

--
Regards,

Olemis.

Blog ES: http://simelo-es.blogspot.com/
Blog EN: http://simelo-en.blogspot.com/

Featured article:

>> > Olemis Lang wrote:

[...]

>> PS: If somebody finds another way to bind parameterized variables
>> names to the (global | local) namespace, pls, let me know (we had a
>> looong thread about this some time ago @ AFPy and this was *THE*
>> solution, AFAICR)

> You might take a look at this:

>wxPython: Refactoring Your Program - Mouse Vs Python

[...]

I don't see how this will create `var1`, `var2`, `var3`, `var4`,
`var5`, `var6`, `var7`, `var8`, ... in the global namespace, and I
insist in the *IF*.

It won't...that was the point. You don't need to create all those
variables unless you'll be modifying their values later. I used to
write all my programs using variable names for the widgets, but then I
realized that the only widgets I ever refer to later are the ones that
I edit, such as my TextControls or Grids. So now I don't do that as
much and try to make them simpler by using the methods I mentioned.

I think there's basically a miss-understanding going on here . I was
trying to reproduce the exact snippet posted by the OP . I use quite
often something like `buttonData` (but recursive ;o) , especially for
(main | popup) menus but that's not even similar to the original
question (which was about creating `var1`, `var2`, `var3`, ...)

Yeah...I wasn't following along very well...too much stuff going on
here, I guess.

CMIIW anyway ;o)

PS: However your blog entry will be really helpful for the OP in order
to arrange the pieces
and put them all together using a nice style (a simple list is morfe
than enough to get this
done ;o)

--
Regards,

Olemis.

Have a nice day,

···

On Mar 2, 4:04 pm, Olemis Lang <ole...@gmail.com> wrote:

On Tue, Mar 2, 2010 at 4:46 PM, Mike Driscoll <kyoso...@gmail.com> wrote:
> On Mar 2, 3:26 pm, Olemis Lang <ole...@gmail.com> wrote:
>> On Tue, Mar 2, 2010 at 4:11 PM, Christopher Barker > > >> <Chris.Bar...@noaa.gov> wrote:

-------------------
Mike Driscoll

Blog: http://blog.pythonlibrary.org

Olemis Lang wrote:

wxPython: Refactoring Your Program - Mouse Vs Python

[...]

I don't see how this will create `var1`, `var2`, `var3`, `var4`,
`var5`, `var6`, `var7`, `var8`, ... in the global namespace, and I
insist in the *IF*.

it won't. I think both Mike and are are suggesting that the OP probably shouldn't try to put a bunch of variable names in the global (or any other) namespace.

I think there's basically a miss-understanding going on here . I was
trying to reproduce the exact snippet posted by the OP.

which you did -- but I doubt that that's the best way for the OP to write their code -- some of like to think we know better and spend a lot of time on this list telling everyone else how to do things :wink:

Which brings up a good point in how to get the best help fro mailing lists:

I suggest one never ask :how can I re-write this code to work?", but rather, specify what you are trying to accomplish with your code, then maybe give a sample of how you are trying to accomplish it.

(a simple list is more than enough to get this
done ;o)

Exactly our point!

So, we all agree -- I wonder what the OP thinks!

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Let's make a big party then !

:o)

···

On Tue, Mar 2, 2010 at 5:24 PM, Christopher Barker <Chris.Barker@noaa.gov> wrote:

Olemis Lang wrote:

Exactly our point!

So, we all agree

--
Regards,

Olemis.

Blog ES: http://simelo-es.blogspot.com/
Blog EN: http://simelo-en.blogspot.com/

Featured article:

Everyone thanks for your responses.

I will need some time to figure out which one is best for my purposes
(by that I mean working, and easy to understand, code).
As a newbie I still have some problems understanding how some events
are propagated to parentclasses, or not at all.

Therefore I like the id's of widgets in global namespace. Ok they
consume unnecessary space, but who cares about 100Kb when an average
pc runs 2Gb?

Also, I like to keep it simple. Use 1 "handler class" which deals with
all mouseclicks, etc. events (except for paintevents) and lots of
"children" who are essentially only for constructing the layout of my
app and keep the code, at least for me, easy to read. After all, it
is Python, not Sanskriet.

I have found some interesting points in your links and advises and I
will follow Chr. Barkers advise for now.

Thanks a lot for all your help.