简体   繁体   中英

Wxpython: TreeCtrl: Iteration over a tree

I am using the following method to iterate over all the nodes of a wxpython treectrl.

 def get_desired_parent(self, name, selectednode = None):
    if selectednode == None:
        selectednode = self.treeCtrl.RootItem
    # First perform the action on the first object separately
    childcount = self.treeCtrl.GetChildrenCount(selectednode, False)
    if childcount == 0:
        return None

    (item,cookie) = self.treeCtrl.GetFirstChild(selectednode)
    if self.treeCtrl.GetItemText(item) == name:
        return item

    while childcount > 1:
        childcount = childcount - 1
     # Then iterate over the rest of objects
        (item,cookie) = self.treeCtrl.GetNextChild(item,cookie)
        if self.treeCtrl.GetItemText(item) == name:
            return item
    return None

This problem of excess code becomes even more apparent when I am iterating inside the structure recursively. Is there another way of performing the same actions in more compact manner, to make my code more concise / pythonic.

You could use a function that is inside this one (in its namespace only) that will check if it matches the conditiin or not. If it does return the item if it doesn't, continue.

Otherwise you could check your condition just after the while line. This way the item variable will be defined by the first child before the loop and evaluated like any other.

Still another way: (or a mix of the two)

(child, cookie) = self.GetFirstChild(item)
while child.IsOk():
    do_something(child)
     (child, cookie) = self.GetNextChild(item, cookie)

Here a full example that traverses the tree going depth first. The function was bound to the right button.

def OnRightDown(self, event):
    def showChildren(item,cookie):
        # functions goes recursively down the tree
        if item.IsOk():
            child, cookie = self.tree.GetFirstChild(item)
            while child.IsOk():
                child, cookie = self.tree.GetNextChild(child, cookie)
                if child:
                  print(self.tree.GetItemText(child)) #show child label name
                  showChildren(child,cookie)
    pt = event.GetPosition()
    item, flags = self.tree.HitTest(pt)
    if item:
        print(self.tree.GetItemText(item)) #show parent label name
        showChildren(item,0)  #iterate depth first into the tree

The best way to make your code highly readable here is to make it short and highly functional.

If you need to iterate through all the tree items and do so through depth first. Here's that as a single quick function. Hand it a function that gets each item, and where you start (usually self.root). It's also quite reusable since you might be doing this a lot.

    def depth_first_tree(self, funct, item):
        (child, cookie) = self.tree.GetFirstChild(item)
        while child.IsOk():
            self.depth_first_tree(funct, child)
            funct(child)
            (child, cookie) = self.tree.GetNextChild(item, cookie)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM