customtreectrl - list of checked items?

Hello all,

In Customtreectrl, is there a simple way to get a list of all the
_checked_ items? There is GetSelections(), for multiple selected
items, but I couldn't find a similar for checked items. I'm working on
an app that should plot data for the checked items only.

cheers

Carlos

Hi Carlos,

Hello all,

In Customtreectrl, is there a simple way to get a list of all the
_checked_ items? There is GetSelections(), for multiple selected
items, but I couldn't find a similar for checked items. I'm working on
an app that should plot data for the checked items only.

There is currently no function/method to retrieve the list of checked
items, but rolling your own is not that hard. For instance, assuming
that "self" represent your subclass of CustomTreeCtrl (untested
code!):

def GetCheckedItems(self, itemParent=None, checkedItems=):

    if itemParent is None:
        itemParent = self.GetRootItem()

    child, cookie = self.GetFirstChild(itemParent)

    while child:
        if tree.IsItemChecked(child):
            checkedItems.append(child)

        checkedItems = self.GetCheckedItems(child, checkedItems)
        child, cookie = self.GetNextChild(itemParent, cookie)

    return checkedItems

HTH.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

···

On Mon, Jun 1, 2009 at 2:47 AM, Carlos Grohmann wrote:

Many thanks for your quick reply, Andrea.

Your function (method?) works, but not in the way I expected. (I'm
also kinda new to python so I don't understand how things work when
you call self.GetCheckedItems inside itself..)

I added this to my code to test it:

    def OnItemCheck(self, event):

        checked = self.GetCheckedItems()
        for i in checked:
            print self.GetItemText(i)

And with this I get an ever-growing list of the items in the tree,
both checked and unchecked. Is this the right way to get a constantly-
updated list of the checked items or I should do it in other way?

again, thanks

Carlos

···

On Jun 1, 5:38 am, Andrea Gavana <andrea.gav...@gmail.com> wrote:

Hi Carlos,

On Mon, Jun 1, 2009 at 2:47 AM, Carlos Grohmann wrote:

> Hello all,

> In Customtreectrl, is there a simple way to get a list of all the
> _checked_ items? There is GetSelections(), for multiple selected
> items, but I couldn't find a similar for checked items. I'm working on
> an app that should plot data for the checked items only.

There is currently no function/method to retrieve the list of checked
items, but rolling your own is not that hard. For instance, assuming
that "self" represent your subclass of CustomTreeCtrl (untested
code!):

def GetCheckedItems(self, itemParent=None, checkedItems=):

if itemParent is None:
    itemParent = self\.GetRootItem\(\)

child, cookie = self\.GetFirstChild\(itemParent\)

while child:
    if tree\.IsItemChecked\(child\):
        checkedItems\.append\(child\)

    checkedItems = self\.GetCheckedItems\(child, checkedItems\)
    child, cookie = self\.GetNextChild\(itemParent, cookie\)

return checkedItems

HTH.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."http://xoomer.alice.it/infinity77/http://thedoomedcity.blogspot.com/

Hi Carlos,

Many thanks for your quick reply, Andrea.

Your function (method?) works, but not in the way I expected. (I'm
also kinda new to python so I don't understand how things work when
you call self.GetCheckedItems inside itself..)

The GetCheckedItems is a recursive method (i.e., it calls itself
recursively) because your tree may have children of the root item,
children of the children, children of the children of the children...
and so on. In order to capture all checked items at any level, one of
the easiest way is to write a recursive function.

I added this to my code to test it:

def OnItemCheck(self, event):

^^^^^

What event are you binding with the OnItemCheck method?

   checked = self\.GetCheckedItems\(\)
   for i in checked:
       print self\.GetItemText\(i\)

And with this I get an ever-growing list of the items in the tree,
both checked and unchecked. Is this the right way to get a constantly-
updated list of the checked items or I should do it in other way?

Uhm, my brain may still be a bit disconnected today, but I can't see
what's wrong with the approach I sent you, but I can see that it is
not working... ?!?

Maybe after the coffee I will be able to think more clearly, or
someone else will be able to point out my mistake :smiley:

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

···

On Mon, Jun 1, 2009 at 1:10 PM, Carlos Grohmann wrote:

I'm binding it with:
        self.Bind(CT.EVT_TREE_ITEM_CHECKED, self.OnItemCheck)

Carlos

···

On Jun 1, 10:27 am, Andrea Gavana <andrea.gav...@gmail.com> wrote:

Hi Carlos,

On Mon, Jun 1, 2009 at 1:10 PM, Carlos Grohmann wrote:

> Many thanks for your quick reply, Andrea.

> Your function (method?) works, but not in the way I expected. (I'm
> also kinda new to python so I don't understand how things work when
> you call self.GetCheckedItems inside itself..)

The GetCheckedItems is a recursive method (i.e., it calls itself
recursively) because your tree may have children of the root item,
children of the children, children of the children of the children...
and so on. In order to capture all checked items at any level, one of
the easiest way is to write a recursive function.

> I added this to my code to test it:

> def OnItemCheck(self, event):

^^^^^

What event are you binding with the OnItemCheck method?

> checked = self.GetCheckedItems()
> for i in checked:
> print self.GetItemText(i)

> And with this I get an ever-growing list of the items in the tree,
> both checked and unchecked. Is this the right way to get a constantly-
> updated list of the checked items or I should do it in other way?

Uhm, my brain may still be a bit disconnected today, but I can't see
what's wrong with the approach I sent you, but I can see that it is
not working... ?!?

Maybe after the coffee I will be able to think more clearly, or
someone else will be able to point out my mistake :smiley:

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."http://xoomer.alice.it/infinity77/http://thedoomedcity.blogspot.com/

Got it!

instead of calling OnItemCheck as:

    def OnItemCheck(self, event):

        checked = self.GetCheckedItems()
        for i in checked:
            print self.GetItemText(i)

calling it like:

    def OnItemCheck(self, event):

        checked = self.GetCheckedItems(None, checkedItems=)
        for i in checked:
            print self.GetItemText(i)

works! forcing the list of checked items to be empty every time solves
it.

cheers

Carlos

···

On Jun 1, 10:27 am, Andrea Gavana <andrea.gav...@gmail.com> wrote:

Hi Carlos,

On Mon, Jun 1, 2009 at 1:10 PM, Carlos Grohmann wrote:

> Many thanks for your quick reply, Andrea.

> Your function (method?) works, but not in the way I expected. (I'm
> also kinda new to python so I don't understand how things work when
> you call self.GetCheckedItems inside itself..)

The GetCheckedItems is a recursive method (i.e., it calls itself
recursively) because your tree may have children of the root item,
children of the children, children of the children of the children...
and so on. In order to capture all checked items at any level, one of
the easiest way is to write a recursive function.

> I added this to my code to test it:

> def OnItemCheck(self, event):

^^^^^

What event are you binding with the OnItemCheck method?

> checked = self.GetCheckedItems()
> for i in checked:
> print self.GetItemText(i)

> And with this I get an ever-growing list of the items in the tree,
> both checked and unchecked. Is this the right way to get a constantly-
> updated list of the checked items or I should do it in other way?

Uhm, my brain may still be a bit disconnected today, but I can't see
what's wrong with the approach I sent you, but I can see that it is
not working... ?!?

Maybe after the coffee I will be able to think more clearly, or
someone else will be able to point out my mistake :smiley:

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."http://xoomer.alice.it/infinity77/http://thedoomedcity.blogspot.com/

Carlos Grohmann wrote:

Got it!

instead of calling OnItemCheck as:

    def OnItemCheck(self, event):

        checked = self.GetCheckedItems()
        for i in checked:
            print self.GetItemText(i)

calling it like:

    def OnItemCheck(self, event):

        checked = self.GetCheckedItems(None, checkedItems=)
        for i in checked:
            print self.GetItemText(i)

works! forcing the list of checked items to be empty every time solves
it.

This is a common Python glitch that happens when you use a mutable object as a default value for a parameter. In this case when you append to the list in the function you are actually appending to the list that is part of the function definition, and that same list (including the values you put into it) will be used when you call the function again. The way to fix this is to ensure that you are creating a new list each time you use the function. For example:

def GetCheckedItems(self, itemParent=None, checkedItems=None):

     if itemParent is None:
         itemParent = self.GetRootItem()

     if checkedItems is None:
         checkedItems =

     child, cookie = self.GetFirstChild(itemParent)

     while child:
         if tree.IsItemChecked(child):
             checkedItems.append(child)

         checkedItems = self.GetCheckedItems(child, checkedItems)
         child, cookie = self.GetNextChild(itemParent, cookie)

     return checkedItems

···

--
Robin Dunn
Software Craftsman

Hi Robin,

Carlos Grohmann wrote:

Got it!

instead of calling OnItemCheck as:

def OnItemCheck\(self, event\):

    checked = self\.GetCheckedItems\(\)
    for i in checked:
        print self\.GetItemText\(i\)

calling it like:

def OnItemCheck\(self, event\):

    checked = self\.GetCheckedItems\(None, checkedItems=\[\]\)
    for i in checked:
        print self\.GetItemText\(i\)

works! forcing the list of checked items to be empty every time solves
it.

This is a common Python glitch that happens when you use a mutable
object as a default value for a parameter. In this case when you append
to the list in the function you are actually appending to the list that
is part of the function definition, and that same list (including the
values you put into it) will be used when you call the function again.
The way to fix this is to ensure that you are creating a new list each
time you use the function.

Thank you for the explanation. I can't think of a single useful reason
for that Python behaviour to be there. But hey, if Python-devs were
able to create Python 3.0, no wonder if many more of these quirks can
be found in the core language... Thank God our BDFL is not as the
Python one.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

···

On Mon, Jun 1, 2009 at 7:07 PM, Robin Dunn wrote:

Andrea Gavana wrote:

This is a common Python glitch that happens when you use a mutable
object as a default value for a parameter. In this case when you append
to the list in the function you are actually appending to the list that
is part of the function definition, and that same list (including the
values you put into it) will be used when you call the function again.
The way to fix this is to ensure that you are creating a new list each
time you use the function.

Thank you for the explanation. I can't think of a single useful reason
for that Python behaviour to be there. But hey, if Python-devs were
able to create Python 3.0, no wonder if many more of these quirks can
be found in the core language...

In this case it probably came down to a design choice of whether the default value should be recreated every time the function is called, or if the value should be created at compile time and become part of the function object. Since function calls are already very expensive, and since for most types there isn't a problem, and since the hardware of the time was a lot slower than today, then I can see why the choice was made.

···

--
Robin Dunn
Software Craftsman