Takes a nested [dict], made here using makeNestedDict, and populates a [ttk::treeview] The nested dict is of the form `{node1 {node1Child1 {child1Leaf1 {} child1Leaf2 {}}} node2 {node2Child1 ...}}`, where * Nodes with children are keys pointing to values which are themselves keys pointing to more values, and * Leaves are nodes whose children are empty {} An example of a function which makes a nested dict follows. ====== # builds a flat list of files/directories one level under $path proc ls {path} { # catch permissions errors if {[catch {glob -nocomplain -tails -directory $path *} result]} { set result {} } return $result } # recursively builds a nested dict of all files/directories under $path proc ls-R {path} { set result {} foreach item [ls $path] { if {[file isdirectory [file join $path $item]]} { dict set result $item [ls-R [file join $path $item]] } else { dict set result $item {} } } return $result } # makes the filesystem tree proc makeNestedDict {path} { return [ls-R $path] } ====== Here is the code to populate a ttk::treeview given a nested dict ====== # returns bool: is the element a leaf? proc isLeaf element { return [expr {$element == {}}] } # fills given ttk::treeview $tree with contents of nested dict $dic proc populateTreeView {tree parent dic} { foreach {k v} $dic { set text [file rootname $k] $tree insert $parent end -id [list {*}$parent $k] -text $text if {![isLeaf $v]} { populateTreeView $tree [list {*}$parent $k] $v } } } proc makeTreeView { } { ttk::treeview .tree .tree configure -columns "items" .tree configure -height 20 .tree column "items" -width 200 -anchor center set nestedDict [makeNestedDict /var] populateTreeView .tree {} $nestedDict pack .tree } makeTreeView ====== ''rgf 2011-07-18 : Interesting implementation - very small amount of code to show nested directory listings but ... the command 'makeNestedDict' needs a path argument in proc 'makeTreeView', and the procedures need to be declared before 'makeTreeView' can be evaluated.'' ''daedra 2011-07-31 : Fixed.'' ''[aspect]: Nice. I tidied up some little things in the above implementation but I like its brevity. Below is an alternative to populateTreeView that is maybe a little more Tclish and perhaps a bit harder to understand at first:'' ====== # for every node in a tree, call $cmd # first argument to $cmd is a list describing the path to this node # second argument is the name of this node's child, or {} for leaves proc walkTree {path tree cmd} { foreach k [dict keys $tree] { {*}$cmd $path $k set v [dict get $tree $k] if {$v == {}} { {*}$cmd [list {*}$path $k] {} } else { walkTree [list {*}$path $k] $v $cmd } } } # the path is passed as a list proc treeviewInsert {tree path name} { $tree insert $path end -id [list {*}$path $name] -text $name } ====== Using the above you would replace the `populateTreeView` call with: ====== walkTree {} $nestedDict {treeviewInsert .tree} ====== Another thing that would be nice is to differentiate files from empty directories in the result of `ls-R`, but I can't decide how to fit this into the nested dictionary data structure best. <>TreeView