Introduction
Traverse all items of a wxTreeCtrl
What Objects are Involved
Python wxTreeCtrl
Process Overview
Looking for a possibility to recursively traversing and expanding all items of a tree Control i was not able to find samples how to do it. The solution found passes the expand or collapse function to the traverse method and applies it to on each tree node:
Code Sample
1 from wxPython.wx import *
2
3 # .... handle the expandAll / collapseAll Event coming from a Menu
4
5 def OnExpandAll(self, e):
6 """ expand all nodes """
7 root = self.tree.GetRootItem()
8 fn = self.tree.Expand
9 self.traverse(root, fn)
10
11 def OnCollapseAll(self, e):
12 """ collapse all nodes of the tree """
13 root = self.tree.GetRootItem()
14 fn = self.tree.Collapse
15 self.traverse(root, fn)
16
17 def traverse(self, traverseroot, function, cookie=0):
18 """ recursivly walk tree control """
19 # step in subtree if there are items or ...
20 if self.tree.ItemHasChildren(traverseroot):
21 firstchild, cookie = self.tree.GetFirstChild(traverseroot, cookie)
22 function(firstchild)
23 self.traverse(firstchild, function, cookie)
24
25 # ... loop siblings
26 child = self.tree.GetNextSibling(traverseroot)
27 if child:
28 function(child)
29 self.traverse(child, function, cookie)
Comments
This didn't work for me, but it was a great starting point. What I had to change:
GetFirstChild() takes one arg, not two
GetRootItem() doesn't work if wx.TR_HIDE_ROOT is used, so I kept a list of children of my root, and instead of self.traverse(root,fn), I called that for every "root" in self.roots
- It doesn't touch the 'traverseroot' passed to it (I guess it assumes the root node is already expanded), so I added a function(traverseroot) call to the start of traverse().
- It's somewhat slow, and steals control of my computer while it's running, so I'm going to look into using threading now...
I haven't tried to come up with a way to do this that works equally well for both states of wx.TR_HIDE_ROOT.
Strange things happen if the root is hidden with wx.TR_HIDE_ROOT. For example, ItemHasChildren(root) fails an assertion. So I tried taking out that check, and calling GetFirstChild(), and then calling IsOk() on the result -- that seemed to work fine (it expanded a lot of things), but then it crashed. I didn't investigate further.
FWIW, the assertion failed was:
File "C:\Python23\Lib\site-packages\wx-2.6-msw-unicode\wx\_controls.py", line 5406, in ItemHasChildren return _controls_.TreeCtrl_ItemHasChildren(*args, **kwargs) wx._core.PyAssertionError: C++ assertion "wxAssertFailure" failed in ..\..\src\msw\treectrl.cpp(808): can't retrieve virtual root item