Selecting an item (on a wxChoice) based on its string ClientData value

You might be interested in the background of this. wxWidgets has mostly concentrated on exposing the features of the underlying GUI, not in adding additional features. In Windows, the extra data for items in a listbox is just a 32-bit value. Many people use that value to point to a structure, or to point to a string, but it could just as easily be a plain integer counter. Because of that genericness, Windows does not provide a way to search the entries of a listbox by the extra data. All you can do is set it and fetch it.

Besides, it is trivially easy to do this mapping in Python. All you need to do is create an dictionary, where the keys are your strings, and the values are the index of the entry. Then your loop becomes

    choiceCtrl.SetSelection( lookupClientData["some random data"] );

Now, in reality, the total amount of work done is about the same, but that certainly reads nicer.

···

On: Mon, 23 Aug 2004 10:38:39 -0300, Jorge Godoy <godoy@ieee.org> wrote:

Not for this project, but I think it is never too late to learn
something. I've seen some new stuff that made me even more interested
in wxPython 2.5... When I'm able to switch, I'll have a great
enhancement in my code, since I'll be able to cut out some things that
are now available.

for index in range(choiceCtrl.GetCount()):
    if choiceCtrl.GetClientData() == "some random data":
        choiceCtrl.SetSelection(index)

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

Tim Roberts <timr@probo.com> writes:

You might be interested in the background of this. wxWidgets has
mostly concentrated on exposing the features of the underlying GUI, not
in adding additional features. In Windows, the extra data for items in
a listbox is just a 32-bit value. Many people use that value to point
to a structure, or to point to a string, but it could just as easily be
a plain integer counter. Because of that genericness, Windows does not
provide a way to search the entries of a listbox by the extra data. All
you can do is set it and fetch it.

Thanks for the explanation.

I'm not much in the Windows stuff :wink: And the docs didn't make it clear
that strings would work.

Besides, it is trivially easy to do this mapping in Python. All you
need to do is create an dictionary, where the keys are your strings, and
the values are the index of the entry. Then your loop becomes

   choiceCtrl.SetSelection( lookupClientData["some random data"] );

Now, in reality, the total amount of work done is about the same, but
that certainly reads nicer.

Not if the contents of the widget are dinamically generated from a
database. I don't want to have several shared variables just for that
and even if the widget gets bigger, I don't think it will be noticeable
to the user how long does it take for such a 'lookup'.

But, if in the future this becomes a problem, then using a dictionary is
a way to optimize such thing. Now I'm iterating through some of the
items and I iterate over all of them only if the desired one is in the
last position of the control.

···

--
Godoy. <godoy@ieee.org>

maybe have a method like:

def IndexFromData(self, data):
     for index in range(self.GetCount()):
         if self.GetClientData() == data:
             return index

in a custom wxChoice

and then do something like
     myChoiceCtrl.SetSelection(myChoiceCtrl.IndexFromData("some random data"))

or even better implement a

def SetDataSelection(self, data):
     self.SetSelection(self.IndexFromData(data))

and then use it like
  myChoiceCtrl.SetDataSelection("some random data")

the main advantage of this is that if sometime in the future SetDataSelection gets implemented in the wxpython all you'll have to do is replace your custom control with a default one. :slight_smile:

···

On Mon, 23 Aug 2004 21:35:37 -0300, Jorge Godoy <godoy@ieee.org> wrote:

Tim Roberts <timr@probo.com> writes:

   choiceCtrl.SetSelection( lookupClientData["some random data"] );

Now, in reality, the total amount of work done is about the same, but
that certainly reads nicer.

Not if the contents of the widget are dinamically generated from a
database. I don't want to have several shared variables just for that
and even if the widget gets bigger, I don't think it will be noticeable
to the user how long does it take for such a 'lookup'.

--
Peter Damoc
Hacker Wannabe

"Peter Damoc" <pdamoc@gmx.net> writes:

maybe have a method like:

def IndexFromData(self, data):
    for index in range(self.GetCount()):
        if self.GetClientData() == data:
            return index

Just to let you know that it should be

     def IndexFromData(self, data):
         for index in range(self.GetCount()):
             if self.GetClientData(index) == data:
                 return index

(Just a change on the GetClientData method so that it uses the
index... you misstyped it ;-))

in a custom wxChoice

<...>

I've done that in a library of the application. The effect is the same
and it is also easy to change the code in the future if anything shows
up. :wink:

Thanks.

···

--
Godoy. <godoy@ieee.org>