In my endeavour to create a simple treeview GUI I have come across tree.tcl which is available in the active tcl 8.6 installation.
I've managed to adapt the code to fit my purpose (hardy changed anything) and when I run the code in the same way as the demos for Active TCL 8.6 (via widget) are run the code is running as expected (though I've not tried making any selection of node within tree).
However that is not the case once I copy the code over into my gui application.
The structure is as expected but when I try to expand the nodes I get:
I get invalid command error ERROR: invalid command name "populateTree" command bound to event: "populateTree .fc.tv.tree [.fc.tv.tree focus]"
Now for some reason none of the files within the folders are read i.e. all file types are recognised as Directories hence everything under nodes shown as "dummy"
I'd also like to add filter to only read a specific file type, i.e. *.txt, if I do so then even folders are not read.
i.e foreach f [lsort -dictionary [glob -nocomplain -dir $path *]]
to
foreach f [lsort -dictionary [glob -nocomplain -dir $path *.txt]]
I'd be obliged if someone could help.
# temp dir to mimic Network dir
set ::dir "C:/Dev"
proc populateRoots {tree} {
populateTree $tree [$tree insert {} end -text "Network File" \
-values [list $::dir directory]]
}
## Code to populate a node of the tree
proc populateTree {tree node} {
if {[$tree set $node type] ne "directory"} {
return
}
set path [$tree set $node fullpath]
$tree delete [$tree children $node]
foreach f [lsort -dictionary [glob -nocomplain -dir $path *]] {
set type [file type $f]
set id [$tree insert $node end -text [file tail $f] \
-values [list $f $type]]
if {$type eq "directory"} {
## Make it so that this node is openable
$tree insert $id 0 -text dummy ;# a dummy
$tree item $id -text [file tail $f]/
} elseif {$type eq "file"} {
set size [file size $f]
set ttime [file mtime $f]
## Format the file size nicely
if {$size >= 1024*1024*1024} {
set size [format %.1f\ GB [expr {$size/1024/1024/1024.}]]
} elseif {$size >= 1024*1024} {
set size [format %.1f\ MB [expr {$size/1024/1024.}]]
} elseif {$size >= 1024} {
set size [format %.1f\ kB [expr {$size/1024.}]]
} else {
append size " bytes"
}
$tree set $id size $size
}
}
# Stop this code from rerunning on the current node
$tree set $node type processedDirectory
}
# ## Create the tree and set it up
ttk::treeview $tw.tree -columns {fullpath type size date time} -displaycolumns {size date time} \
-yscroll "$tw.vsb set" -xscroll "$tw.hsb set"
ttk::scrollbar $tw.vsb -orient vertical -command "$tw.tree yview"
ttk::scrollbar $tw.hsb -orient horizontal -command "$tw.tree xview"
$tw.tree heading \#0 -text "Directory Structure"
$tw.tree heading size -text "File Size"
$tw.tree column size -stretch 0 -width 70
populateRoots $tw.tree
bind $tw.tree <<TreeviewOpen>> {populateTree %W [%W focus]}
# ## Arrange the tree and its scrollbars in the toplevel
lower [ttk::frame $tw.dummy]
pack $tw.dummy -fill both -expand 1
grid $tw.tree $tw.vsb -sticky nsew -in $tw.dummy
grid $tw.hsb -sticky nsew -in $tw.dummy
grid columnconfigure $tw.dummy 0 -weight 1
grid rowconfigure $tw.dummy 0 -weight 1
Thanks in advance, George
The issue was that the procedure populateTree
needed to be ::populateTree
so it could be found within the namespace.
PS: I still can't print selection to console...