populating wxtreectrl

hi,
i am migrating an app from perl/tk to wxpython

i have a list of the form:

root
root/animals
root/animals/dogs
root/animals/cats
root/animals/cats/small
root/birds
root/birds/parrots
root/fish

etc etc

can anyone point me to a painless way of populating a treectrl with this
list?

regards
kg

the naive approach (the process is split in 2: first turn the list into a tree then add the python tree to the wx.TreeCtrl. Reusability... bla bla... so on and so forth)

import wx

paths = [
         'root',
         'root/animals',
         'root/animals/dogs',
         'root/animals/cats',
         'root/animals/cats/small',
         'root/birds',
         'root/birds/parrots',
         'root/fish',
         ]

tree = {}

def paths2tree(tree, paths):
     if len(paths) >0:
         if not paths[0] in tree.keys():
             tree[paths[0]] = {}
         paths2tree(tree[paths[0]], paths[1:])

for item in paths:
     path = item.split('/')
     paths2tree(tree, path)

class MyFrame(wx.Frame):
     def __init__(self):
         wx.Frame.__init__(self, None, -1, "Test")
         self.tree = wx.TreeCtrl(self, -1)
         self.root = self.tree.AddRoot("root")
         self.AddTree(self.root, tree['root'])
         self.Show()

     def AddTree(self, treeId, dict):
         if len(dict)>0:
             for key in dict.keys():
                 newId = self.tree.AppendItem(treeId, key)
                 self.AddTree(newId, dict[key])

app = wx.PySimpleApp()
app.SetTopWindow(MyFrame())
app.MainLoop()

···

On Tue, 25 May 2004 06:23:21 +0530 (IST), kg <lawgon@thenilgiris.com> wrote:

hi,
i am migrating an app from perl/tk to wxpython

i have a list of the form:

root
root/animals
root/animals/dogs
root/animals/cats
root/animals/cats/small
root/birds
root/birds/parrots
root/fish

etc etc

can anyone point me to a painless way of populating a treectrl with this
list?

regards
kg

--
Peter Damoc
Hacker Wannabe

thanks, works well, but when using dictionaries, the orginal order, which i
want to preserve, gets messed up ... any work around for that?

···

On Tuesday 25 May 2004 11:40 am, you wrote:

the naive approach (the process is split in 2: first turn the list into a
tree then add the python tree to the wx.TreeCtrl. Reusability... bla
bla... so on and so forth)

--
regards
kg

http://www.ootygolfclub.org

here's a snippet of wxTreeCtrl with list-based populator
(just a portion of the code, to give you some of my idea).
In this case, I have tuple of data and text value (ie:
'dlgSampleDialogXrc','Normal dialog with XRC') as leaf item.

the data portion, is hidden from view, and used internally
to display assigned icon (assigned from wxImageList -- not
shown), and proper action when double-clicked (ie, for www,
the rest of the string is considered a URL, which when
clicked, open up web browser).

nav = [
    ['fld','Samples',
        [
        ['wwwhttp://www.Google.com','Link to website'],
        ['dlgSampleDialogXrc','Normal dialog with XRC'],
        ['dlgSampleDialog','Normal dialog without XRC'],
        ['frmSampleFrameXrc','Normal frame with XRC'],
        ['frmSampleFrame','Normal frame without XRC'],
        ]
    ],
    ['fld','Basic Services',
        [
        ['tbwMp3','Mp3 Client'],
        ['frmIsoCode','ISO Code Definition'],
        ['tbwSysSequences','Sys Sequences'],
        ['frmSysSequences','Sys Sequences'],
        ['tbwCurrencyAll','Currency (All)'],
        ['tbwCompanyParam','Application Parameters'],
        ]
    ],
]

class MyTreeCtrl(wx.TreeCtrl):
    def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.TR_HAS_BUTTONS | wx.TR_SINGLE):
        wx.TreeCtrl.__init__(self, parent, id, pos, size, style)
        self.stack = []
        
    def populate(self,navtree):
        self._plant_tree(self.stack,navtree)
        self.Expand(self.stack[-1])
        
    def _plant_tree(self,parent,tree):
        """internal funtion to recursively parse _tree module into wxtree's item
        """
        for element in tree:
            # item type depend on first 3 letters
            type = element[0][0:3]
            if type == 'fld': #folder!
                # create parent
                parent.append(self.AppendItem(parent[-1], element[1]))
                self.SetItemImage(parent[-1], self.icons['folder'], wx.TreeItemIcon_Normal)
                self.SetItemImage(parent[-1], self.icons['folder_open'], wx.TreeItemIcon_Expanded)
                children = element[2]
                self._plant_tree(parent,children)
                parent.pop()
            else:
                mapdict = dict(frm='frame',tbw='table',www='www',dlg='dialog',rpt='report')
                icon = self.icons[mapdict.get(type,'generic')]
                data = wx.TreeItemData(element[0]); #set filename as data for this tree item
                child = self.AppendItem(parent[-1], element[1], icon, -1, data)

···

--
Best regards,
dody mailto:dody.wijaya2@asp.co.id

you might contract the 2 phase process into one phase (instead of creating the dict you directly add the elements to the treectrl)

ofcourse if all you need is a sorted tree... you could replace the AddTree method from my previous post with:
     def AddTree(self, treeId, dict):
         if len(dict)>0:
             skeys = dict.keys()
             skeys.sort()
             for key in skeys:
                 newId = self.tree.AppendItem(treeId, key)
                 self.AddTree(newId, dict[key])

···

On Tue, 25 May 2004 12:41:37 +0530, kg <lawgon@thenilgiris.com> wrote:

On Tuesday 25 May 2004 11:40 am, you wrote:

the naive approach (the process is split in 2: first turn the list into a
tree then add the python tree to the wx.TreeCtrl. Reusability... bla
bla... so on and so forth)

thanks, works well, but when using dictionaries, the orginal order, which i
want to preserve, gets messed up ... any work around for that?

--
Peter Damoc
Hacker Wannabe