Search code examples
tcldirectoryhierarchytk-toolkit

How to show a directory structure(explorer) in tcl tk?


I am not able to add nodes recursively in a treectrl. i.e. I want to show all the directories and files as in an explorer.

Till now, this is what I have. I am adding dummy nodes in each folder currently.

package require treectrl
treectrl .t -showheader 0 -selectmode single -showroot 0 -yscrollcommand {.y set}
scrollbar .y -ori vert -command ".t yview"
pack .y  -side right -fill y
pack .t  -side right -fill both -expand 1
set columnID [.t column create -text "Column 0"]
.t configure -treecolumn $columnID
.t element create el1 text 
.t element create el2 rect -showfocus yes
.t style create s1
.t style elements s1 [list el1 el2]
.t style layout s1 el2 -union el1
.t configure -defaultstyle s1

proc add_node {parent text} {
    set itemID [.t item create -button yes ]
    .t item element configure $itemID 0 el1 -text $text
    .t item collapse $itemID
    .t item lastchild $parent $itemID
    return $itemID    
}

set images [glob -nocomplain -directory "D:/Explore" "*"]
for {set i 0} {$i<=[llength $images]} {incr i} {
    set root [lsearch $images [lindex $images $i]]
    add_node [add_node [add_node root [list directory [file tail [lindex $images $i]]]] dummy] dummy2
}

Solution

  • First of all, you need to use option -tipes of glob command. This way you can separate directories and files. And second, you need recursion to process nested files and directories.

    package require Tk
    package require treectrl
    treectrl .t -showheader 0 -selectmode single -showroot 0 -yscrollcommand {.y set}
    scrollbar .y -ori vert -command ".t yview"
    pack .y  -side right -fill y
    pack .t  -side right -fill both -expand 1
    set columnID [.t column create -text "Column 0"]
    .t configure -treecolumn $columnID
    .t element create el1 text
    .t element create el2 rect -showfocus yes
    .t style create s1
    .t style elements s1 [list el1 el2]
    .t style layout s1 el2 -union el1
    .t configure -defaultstyle s1
    
    proc add_node {parent text button} {
        set itemID [.t item create -button $button ]
        .t item element configure $itemID 0 el1 -text $text
        .t item collapse $itemID
        .t item lastchild $parent $itemID
        return $itemID
    }
    
    proc add_directory {path parent} {
      set directory_list [glob -nocomplain -types d -directory $path "*"]
      foreach directory $directory_list {
        set n [add_node $parent [file tail $directory] yes]
        add_directory $directory $n
      }
      set files_list [glob -nocomplain -types f -directory $path "*"]
      foreach file $files_list {
        set n [add_node $parent [file tail $file] no]
      }
    }
    
    add_directory "D:/Explore" root