Yes, this is an annoying limitation in ListCtrl. I get round it by using a dictionary and creating arbitrary integers to map to the objects:
self.mydict = {}
number = 0
for ...:
...
self.__mLinks.SetItemData(idx, number)
self.mydict[number] = message.data
number += 1
(I don't use idx itself in case the list is being sorted.)
Phil
···
At 12:06 PM 5/6/2007, you wrote:
Hi All,
I am a bit confused and do not know how to go about doing this..
When I add a new item to a wx.Choice or wx.ComboBox I can use
SetClientData() and it accepts an arbitrary python object reference
like;
""" Tabs need to be added to the list """
# if the tab is the first to be added, select it and fill edit
idx = self.__mTabSelect.Append(message.data.getName())
self.__mTabSelect.SetClientData(idx, message.data)
message.data is a Song() object. So that's cool. But when I try to use
SetItemData from the wx.ListCtrl, it expects an int:
self.__mLinks.SetItemData(index, l)
File "C:\Python25\lib\site-packages\wx-2.8-msw-unicode\wx\_controls.py", line
4561, in SetItemData
return _controls_.ListCtrl_SetItemData(*args, **kwargs)
AttributeError: Link instance has no attribute '__int__'
With the code:
self.__mLinks.SetItemData(index, l)
Where l is a Link() object. I am confused becuase the same code seems
to work for the wx.Choice.
How do I go about converting the object reference to attach the client
data to the list ctrl item? I would like to get a reference back when
doubleclicking on the object, so that I do not have to have lookup
tables, or use special integer ID's in my object's list..
Wouldn't it be better to patch this up by overriding this int passing
to the SetItemData to a long? I believe the long <--> object reference
can be done transparently.
If I check the help of wxWidgets C++ API:
wxListCtrl::SetItemData
bool SetItemData(long item, long data)
Thanks again I will reopen the issue by posting a new message asking
for a change in the wxPython binding ..
Regards,
- Jorgen
···
On 5/7/07, Phil Mayes <phil@philmayes.com> wrote:
At 12:06 PM 5/6/2007, you wrote:
>Hi All,
>
>I am a bit confused and do not know how to go about doing this..
>
>When I add a new item to a wx.Choice or wx.ComboBox I can use
>SetClientData() and it accepts an arbitrary python object reference
>like;
>
> """ Tabs need to be added to the list """
> # if the tab is the first to be added, select it and fill edit
> idx = self.__mTabSelect.Append(message.data.getName())
> self.__mTabSelect.SetClientData(idx, message.data)
>
>message.data is a Song() object. So that's cool. But when I try to use
>SetItemData from the wx.ListCtrl, it expects an int:
>
> self.__mLinks.SetItemData(index, l)
> File "C:\Python25\lib\site-packages\wx-2.8-msw-unicode\wx\_controls.py",
> line
>4561, in SetItemData
> return _controls_.ListCtrl_SetItemData(*args, **kwargs)
>AttributeError: Link instance has no attribute '__int__'
>
>With the code:
>
> self.__mLinks.SetItemData(index, l)
>
>Where l is a Link() object. I am confused becuase the same code seems
>to work for the wx.Choice.
>
>How do I go about converting the object reference to attach the client
>data to the list ctrl item? I would like to get a reference back when
>doubleclicking on the object, so that I do not have to have lookup
>tables, or use special integer ID's in my object's list..
Yes, this is an annoying limitation in ListCtrl. I get round it by using a
dictionary and creating arbitrary integers to map to the objects:
self.mydict = {}
number = 0
for ...:
...
self.__mLinks.SetItemData(idx, number)
self.mydict[number] = message.data
number += 1
(I don't use idx itself in case the list is being sorted.)
Phil
---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org
Wouldn't it be better to patch this up by overriding this int passing
to the SetItemData to a long? I believe the long <--> object reference
can be done transparently.
If I check the help of wxWidgets C++ API:
wxListCtrl::SetItemData
bool SetItemData(long item, long data)
Thanks again I will reopen the issue by posting a new message asking
for a change in the wxPython binding ..
There are two problems with this. First of all, I don't think a long is not guaranteed to be big enough to hold a pointer on a 64-bit system. Second, just using raw pointers from the wxPython wrappers will cause problems with object reference counting. When the item is deleted or when the ListCtrl is destroyed there is no mechanism for destroying the client data, which for Python objects means decrementing the reference count of the object. So you'll end up with reference leaks and would have to run the garbage collector yourself.
The best solution would be to patch wxListCtrl to accept wxClientData object pointers which it would then own, and can delete them as needed. (This is probably not a trivial task...) In wxPython I have the wxPyClientData class that derives from wxClientData and knows how to manage the reference count of the PyObject pointer that it holds.
···
--
Robin Dunn
Software Craftsman http://wxPython.org Java give you jitters? Relax with wxPython!
Thanks again for explaining it Robin, I did reply on the other thread
thinking it was rather trivial but seeing it from the python point of
view, it is not.. Let's hope a solution can be found, client data with
object references beat integer references ... it makes development
life easier.
Regards,
- Jorgen
···
On 5/7/07, Robin Dunn <robin@alldunn.com> wrote:
Jorgen Bodde wrote:
> Hi Phil,
>
> Wouldn't it be better to patch this up by overriding this int passing
> to the SetItemData to a long? I believe the long <--> object reference
> can be done transparently.
>
> If I check the help of wxWidgets C++ API:
>
> wxListCtrl::SetItemData
> bool SetItemData(long item, long data)
>
> Thanks again I will reopen the issue by posting a new message asking
> for a change in the wxPython binding ..
There are two problems with this. First of all, I don't think a long is
not guaranteed to be big enough to hold a pointer on a 64-bit system.
Second, just using raw pointers from the wxPython wrappers will cause
problems with object reference counting. When the item is deleted or
when the ListCtrl is destroyed there is no mechanism for destroying the
client data, which for Python objects means decrementing the reference
count of the object. So you'll end up with reference leaks and would
have to run the garbage collector yourself.
The best solution would be to patch wxListCtrl to accept wxClientData
object pointers which it would then own, and can delete them as needed.
(This is probably not a trivial task...) In wxPython I have the
wxPyClientData class that derives from wxClientData and knows how to
manage the reference count of the PyObject pointer that it holds.
--
Robin Dunn
Software Craftsman http://wxPython.org Java give you jitters? Relax with wxPython!
---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org