• Multi Selection in treeview

    From GeorgeB@21:1/5 to All on Wed Sep 28 08:43:14 2022
    Is it possible to multi select and keep the selection persistent without holding Ctrl.

    Basically I would like to make selection easier for User (tree is has grown to 10 nodes each with several children).

    1) select item
    2) to deselect User will have to click item in tree again, until then it remains persistent.

    I'd prefer to have a checkbox facility where User can check/uncheck selection, but checkbox is not possible in treeview.

    I've tried with image of check and unchecked that can be toggled upon selection, I can add the image but can't seem to understand where to set it such that it toggles to unchecked (not sure if this is a wise approach).

    Any help/advice is appreciated. Code is below.

    package req Tk

    image create photo ::img::cbu(0) -data { R0lGODlhDwAPANUAANnZ2Y6Pj/T09K6zua+0urS5vbu+wcvP1dDT2NXY3Nvd38HDxc3R1tLV2tjb 3t3f4eLj5MbHyM3R19DU2dTX2+Hi4+Xm5ujo6MzNzbK3vNrc3+Dh4+zs7O3t7dTV1ri7v+Tl5erq 6u/v7/Ly8tzd3ry/wuPk5enp6fX19eHi4sLExvDw8Pb29ubm5srLzNTU1dvb3ODh4ebn5+rr6+vs 7Ovr7Onp6v///////////////////////////////////yH5BAEAAAAALAAAAAAPAA8AAAZvQIBw SCwCAsikMikMCJ7QqCDQFAyuWELBMK0ODuADIqFYdI9WMKPheEAiZ+dAMqEoKpYLJi7IJDQbFxwd HR58Hw8gISIjjSR8JSYnHSMCKAIpfCqTKwIsny18Li8wMTIzNDU2fFJSVEdLsa9GtABBADs=}
    image create photo ::img::cbc(1) -data { R0lGODlhDwAPAOYAANnZ2Y6Pj/T09Pj4+Pn5+fb29q6zucnM0J2nwHeGq9zf5PX19cvP1czQ1u3u 8VdqnURakrm/0M3R1uDi5q+4z0VakmV3pefn6NXZ3d/i5dXY3PLz9F5xoUdclLzD1tvc3MXJzcnP 3aOuyO3u7rrB1UlelmR2pdXV1t7g4W5/qs/U4md4p0tgl7e/1dzd3s3P0d7h6UhdlUlflmFzpPj5 +uHi4sbIyurs8IuZu0pfl0xhmLC50ebm5srLzNra29/i6YyZupCdvfLz9uzt7evr7Onp6v////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////yH5 BAEAAAAALAAAAAAPAA8AAAeFgACCg4SFAAGIiYqJggECj5ACAwQFAgGNAgaamgcICQoLl4eZDKUN Dg8QEQWijgalEhMUFRYXlpgGGBkaGxwdHh+3oyAhIiMkJSYDJ8KOKCkdKissLQUuzQIvMDEyLDM0 AjXYNjc4OTo7lDzYPT4/QEFCQ0RF2I8LBAMLka2L/qKGAgIIBAA7}


    proc populateRoots {tree ROOT SHOW_TYPES} {
    populateTree $tree \
    [$tree insert {} end -text "Network File" \
    -values [list $ROOT directory] \
    -open 1] \
    $SHOW_TYPES
    }

    ## Code to populate a node of the tree
    proc populateTree {tree node SHOW_TYPES} {

    if {[$tree set $node type] ne "directory"} {
    return
    }
    set path [$tree set $node fullpath]
    $tree delete [$tree children $node]



    ### display so that folders comes before files at the same level
    ### files and folders are displayed in alphabetical order
    set folders [lsort -dictionary [glob -nocomplain -type d -dir \
    $path *]]
    set files [lsort -dictionary [glob -nocomplain -type f -dir \
    $path *]]


    foreach f [list {*}$folders {*}$files] {
    set type [file type $f]
    if {$type eq "directory"} {
    ### this is a folder
    ### Make it so that this node is openable
    set id [$tree insert $node end -text [file tail $f] \
    -values [list $f $type] \
    -open 0]

    $tree insert $id 0 -text dummy ;# a dummy
    $tree item $id -text [file tail $f]/


    ### this folder has sub-folders
    ### process them automatically
    ### so the user does not have to click on each one
    ### to find where actual files are
    populateTree $tree $id $SHOW_TYPES

    } elseif {($type eq "file") && \
    ([file extension $f] in $SHOW_TYPES)} {


    ### get basic info on the file to display

    ### Format the file size nicely
    set size [file size $f]
    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"
    }


    ### format the date and time nicely
    set ttime [file mtime $f]
    set fdate [clock format $ttime -format "%Y-%m-%d"]
    set ftime [clock format $ttime -format "%H-%M-%S"]


    ### display the file in the tree
    set id [$tree insert $node end \
    -tags SHOW_FILE \
    -text [file tail $f] \
    -values [list $f $type $size $fdate $ftime]]

    # set id [$tree insert $node end \
    # -tags SHOW_FILE \
    # -text [file tail $f] \
    # -values [list $f $type $size $fdate $ftime] \
    # -image ::img::cbu(0)]


    ### only open folders that are not empty
    ### THIS FOLDER HAS A DISPLAYABLE FILE IN IT
    ### AUTOMATICALLY OPEN IT
    $tree set $id size $size
    $tree item [$tree parent $id] -open 1 -tags FOLDER_HAS_ITEM

    } else {
    # a file type that will not be shown
    }
    }


    # Stop this code from rerunning on the current node
    $tree set $node type processedDirectory
    }


    # ## Create the tree and set it up
    proc display_tree {tw ROOT SHOW_TYPES} {
    catch { destroy $tw.tree }
    catch { destroy $tw.vsb }
    catch { destroy $tw.hsb }
    catch { destroy $tw.dummy }

    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" -anchor w
    $tw.tree heading date -text "Last Mod Date" -anchor w
    $tw.tree heading time -text "Last Mod Time" -anchor w

    $tw.tree column size -stretch 1 -width 20
    $tw.tree column date -stretch 1 -width 20
    $tw.tree column time -stretch 1 -width 20


    ### you can make files and non-empty folders more visible
    ### by playing around with colors and fonts as below
    ### change or remove as needed
    $tw.tree tag config SHOW_FILE -foreground blue -font bold
    $tw.tree tag config FOLDER_HAS_ITEM -foreground red -font bold


    populateRoots $tw.tree $ROOT $SHOW_TYPES
    bind $tw.tree <<TreeviewOpen>> {populateTree %W [%W focus]
    $SHOW_TYPES}


    # ## 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


    }


    proc run_test {} {

    wm iconify .


    ### first window
    set ROOT_1 "C:/Dev"
    set SHOW_TYPES [list .ini .txt .docx]


    catch {destroy .t1 }
    toplevel .t1
    wm title .t1 $ROOT_1
    wm geom .t1 500x400

    display_tree .t1 $ROOT_1 $SHOW_TYPES


    ### second window with different files to show
    set ROOT_2 "C:/Windows/INF"
    set SHOW_TYPES [list .ini .csv]

    catch {destroy .t2 }
    toplevel .t2
    wm title .t2 $ROOT_2
    wm geom .t2 800x600

    display_tree .t2 $ROOT_2 $SHOW_TYPES
    }


    ### start here
    run_test

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@21:1/5 to GeorgeB on Wed Sep 28 14:38:17 2022
    On 9/28/22 11:43 AM, GeorgeB wrote:
    Is it possible to multi select and keep the selection persistent without holding Ctrl.

    Basically I would like to make selection easier for User (tree is has grown to 10 nodes each with several children).

    1) select item
    2) to deselect User will have to click item in tree again, until then it remains persistent.

    I'd prefer to have a checkbox facility where User can check/uncheck selection, but checkbox is not possible in treeview.



    ## put this bind inside display_tree with the other bind
    bind $tw.tree <ButtonRelease-1> {manage_sel %W}

    proc manage_sel {tw} {
    set sel [$tw item {} -values]
    set new [$tw focus]

    if {$new eq ""} {
    return
    } elseif {[$tw set $new type] ne "file"} {
    set sel [lremove $sel $new]
    } elseif {$new in $sel} {
    set sel [lremove $sel $new]
    } else {
    lappend sel $new
    }

    $tw item {} -values $sel
    $tw selection set {}
    $tw selection set $sel
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@21:1/5 to All on Wed Sep 28 14:42:50 2022
    On 9/28/22 2:38 PM, saitology9 wrote:


    ## put this bind inside display_tree with the other bind
    bind $tw.tree <ButtonRelease-1> {manage_sel %W}


    Or try these bindings to reduce flashing:

    bind $tw.tree <Button-1> {}
    bind $tw.tree <ButtonRelease-1> {manage_sel %W}

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From GeorgeB@21:1/5 to All on Thu Sep 29 01:30:13 2022
    On Wednesday, September 28, 2022 at 7:42:56 PM UTC+1, saitology9 wrote:
    On 9/28/22 2:38 PM, saitology9 wrote:


    ## put this bind inside display_tree with the other bind
    bind $tw.tree <ButtonRelease-1> {manage_sel %W}

    Or try these bindings to reduce flashing:

    bind $tw.tree <Button-1> {}
    bind $tw.tree <ButtonRelease-1> {manage_sel %W}

    I seem to get error invalid command name "lremove"

    Just a thought, can I use the same logic to change ::img::cbu(0) to ::img::cbc(1) upon selection of Item?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@21:1/5 to GeorgeB on Thu Sep 29 20:47:46 2022
    On 9/29/22 4:30 AM, GeorgeB wrote:
    On Wednesday, September 28, 2022 at 7:42:56 PM UTC+1, saitology9 wrote:
    On 9/28/22 2:38 PM, saitology9 wrote:


    ## put this bind inside display_tree with the other bind
    bind $tw.tree <ButtonRelease-1> {manage_sel %W}

    Or try these bindings to reduce flashing:

    bind $tw.tree <Button-1> {}
    bind $tw.tree <ButtonRelease-1> {manage_sel %W}

    I seem to get error invalid command name "lremove"


    Interesting. Here is the definition from tkcon:

    ## lremove - remove items from a list
    # OPTS:
    # -all remove all instances of each item
    # -glob remove all instances matching glob pattern
    # -regexp remove all instances matching regexp pattern
    # ARGS: l a list to remove items from
    # args items to remove (these are 'join'ed together)
    ##
    proc lremove {args} {
    array set opts {-all 0 pattern -exact}
    while {[string match -* [lindex $args 0]]} {
    switch -glob -- [lindex $args 0] {
    -a* { set opts(-all) 1 }
    -g* { set opts(pattern) -glob }
    -r* { set opts(pattern) -regexp }
    -- { set args [lreplace $args 0 0]; break }
    default {return -code error "unknown option \"[lindex $args 0]\""}
    }
    set args [lreplace $args 0 0]
    }
    set l [lindex $args 0]
    foreach i [join [lreplace $args 0 0]] {
    if {[set ix [lsearch $opts(pattern) $l $i]] == -1} continue
    set l [lreplace $l $ix $ix]
    if {$opts(-all)} {
    while {[set ix [lsearch $opts(pattern) $l $i]] != -1} {
    set l [lreplace $l $ix $ix]
    }
    }
    }
    return $l
    }

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to GeorgeB on Fri Sep 30 02:47:18 2022
    GeorgeB <george.booth3182@gmail.com> wrote:
    I seem to get error invalid command name "lremove"

    What version of Tcl are you using?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From GeorgeB@21:1/5 to Rich on Fri Sep 30 00:50:56 2022
    On Friday, September 30, 2022 at 3:47:23 AM UTC+1, Rich wrote:
    GeorgeB <george.b...@gmail.com> wrote:
    I seem to get error invalid command name "lremove"
    What version of Tcl are you using?

    @saitology9, thanks that got rid of the error message but the bandings seem to have disappeared.

    @Rich, using TCL 8.6.9

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to GeorgeB on Fri Sep 30 14:14:35 2022
    GeorgeB <george.booth3182@gmail.com> wrote:
    On Friday, September 30, 2022 at 3:47:23 AM UTC+1, Rich wrote:
    GeorgeB <george.b...@gmail.com> wrote:
    I seem to get error invalid command name "lremove"
    What version of Tcl are you using?

    @saitology9, thanks that got rid of the error message but the bandings seem to have disappeared.

    @Rich, using TCL 8.6.9

    Ok, that explains why you saw no lremove, lremove was added in of 8.7.

    Note, it is better to reply to each message, not "group replies" into a
    single one. Most of us here are not using that absolutely awful google
    groups interface, and doing "group replies" breaks the message
    threading for everyone else.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From GeorgeB@21:1/5 to Rich on Fri Sep 30 07:46:01 2022
    On Friday, September 30, 2022 at 3:14:40 PM UTC+1, Rich wrote:
    GeorgeB <george.b...@gmail.com> wrote:
    On Friday, September 30, 2022 at 3:47:23 AM UTC+1, Rich wrote:
    GeorgeB <george.b...@gmail.com> wrote:
    I seem to get error invalid command name "lremove"
    What version of Tcl are you using?

    @saitology9, thanks that got rid of the error message but the bandings seem to have disappeared.

    @Rich, using TCL 8.6.9
    Ok, that explains why you saw no lremove, lremove was added in of 8.7.

    Note, it is better to reply to each message, not "group replies" into a single one. Most of us here are not using that absolutely awful google
    groups interface, and doing "group replies" breaks the message
    threading for everyone else.

    Ahh, understood.

    Btw in my earlier message I mentioned that banding i.e. highlighted row upon selection seemed to have disappeared. That does happen but only when I run the code with other parts of my GUI application.

    If I run the code (shown below) in a fresh clean script and run it from command line....all is good.

    So, where would I start looking if I had to debug. I think "$tw selection set $sel" is not being set hence I can not see selection on screen but if I print $sel to console, then it shows the items that I have clicked on the tree.



    package req Tk

    ## lremove - remove items from a list
    # OPTS:
    # -all remove all instances of each item
    # -glob remove all instances matching glob pattern
    # -regexp remove all instances matching regexp pattern
    # ARGS: l a list to remove items from
    # args items to remove (these are 'join'ed together)
    ##
    proc lremove {args} {
    array set opts {-all 0 pattern -exact}
    while {[string match -* [lindex $args 0]]} {
    switch -glob -- [lindex $args 0] {
    -a* { set opts(-all) 1 }
    -g* { set opts(pattern) -glob }
    -r* { set opts(pattern) -regexp }
    -- { set args [lreplace $args 0 0]; break }
    default {return -code error "unknown option \"[lindex $args 0]\""}
    }
    set args [lreplace $args 0 0]
    }
    set l [lindex $args 0]
    foreach i [join [lreplace $args 0 0]] {
    if {[set ix [lsearch $opts(pattern) $l $i]] == -1} continue
    set l [lreplace $l $ix $ix]
    if {$opts(-all)} {
    while {[set ix [lsearch $opts(pattern) $l $i]] != -1} {
    set l [lreplace $l $ix $ix]
    }
    }
    }
    return $l
    }

    image create photo ::img::cb(0) -data { R0lGODlhDwAPANUAANnZ2Y6Pj/T09K6zua+0urS5vbu+wcvP1dDT2NXY3Nvd38HDxc3R1tLV2tjb 3t3f4eLj5MbHyM3R19DU2dTX2+Hi4+Xm5ujo6MzNzbK3vNrc3+Dh4+zs7O3t7dTV1ri7v+Tl5erq 6u/v7/Ly8tzd3ry/wuPk5enp6fX19eHi4sLExvDw8Pb29ubm5srLzNTU1dvb3ODh4ebn5+rr6+vs 7Ovr7Onp6v///////////////////////////////////yH5BAEAAAAALAAAAAAPAA8AAAZvQIBw SCwCAsikMikMCJ7QqCDQFAyuWELBMK0ODuADIqFYdI9WMKPheEAiZ+dAMqEoKpYLJi7IJDQbFxwd HR58Hw8gISIjjSR8JSYnHSMCKAIpfCqTKwIsny18Li8wMTIzNDU2fFJSVEdLsa9GtABBADs=}
    image create photo ::img::cb(1) -data { R0lGODlhDwAPAOYAANnZ2Y6Pj/T09Pj4+Pn5+fb29q6zucnM0J2nwHeGq9zf5PX19cvP1czQ1u3u 8VdqnURakrm/0M3R1uDi5q+4z0VakmV3pefn6NXZ3d/i5dXY3PLz9F5xoUdclLzD1tvc3MXJzcnP 3aOuyO3u7rrB1UlelmR2pdXV1t7g4W5/qs/U4md4p0tgl7e/1dzd3s3P0d7h6UhdlUlflmFzpPj5 +uHi4sbIyurs8IuZu0pfl0xhmLC50ebm5srLzNra29/i6YyZupCdvfLz9uzt7evr7Onp6v////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////yH5 BAEAAAAALAAAAAAPAA8AAAeFgACCg4SFAAGIiYqJggECj5ACAwQFAgGNAgaamgcICQoLl4eZDKUN Dg8QEQWijgalEhMUFRYXlpgGGBkaGxwdHh+3oyAhIiMkJSYDJ8KOKCkdKissLQUuzQIvMDEyLDM0 AjXYNjc4OTo7lDzYPT4/QEFCQ0RF2I8LBAMLka2L/qKGAgIIBAA7}


    proc populateRoots {tree ROOT SHOW_TYPES} {
    populateTree $tree \
    [$tree insert {} end -text "Network File" \
    -values [list $ROOT directory] \
    -open 1] \
    $SHOW_TYPES
    }

    ## Code to populate a node of the tree
    proc populateTree {tree node SHOW_TYPES} {

    if {[$tree set $node type] ne "directory"} {
    return
    }
    set path [$tree set $node fullpath]
    $tree delete [$tree children $node]



    ### display so that folders comes before files at the same level
    ### files and folders are displayed in alphabetical order
    set folders [lsort -dictionary [glob -nocomplain -type d -dir \
    $path *]]
    set files [lsort -dictionary [glob -nocomplain -type f -dir \
    $path *]]


    foreach f [list {*}$folders {*}$files] {
    set type [file type $f]
    if {$type eq "directory"} {
    ### this is a folder
    ### Make it so that this node is openable
    set id [$tree insert $node end -text [file tail $f] \
    -values [list $f $type] \
    -open 0]

    $tree insert $id 0 -text dummy ;# a dummy
    $tree item $id -text [file tail $f]/


    ### this folder has sub-folders
    ### process them automatically
    ### so the user does not have to click on each one
    ### to find where actual files are
    populateTree $tree $id $SHOW_TYPES

    } elseif {($type eq "file") && \
    ([file extension $f] in $SHOW_TYPES)} {


    ### get basic info on the file to display

    ### Format the file size nicely
    set size [file size $f]
    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"
    }


    ### format the date and time nicely
    set ttime [file mtime $f]
    set fdate [clock format $ttime -format "%Y-%m-%d"]
    set ftime [clock format $ttime -format "%H-%M-%S"]


    ### display the file in the tree

    set id [$tree insert $node end \
    -tags SHOW_FILE \
    -text [file tail $f] \
    -values [list $f $type $size $fdate $ftime]]

    # set id [$tree insert $node end \
    # -tags SHOW_FILE \
    # -text [file tail $f] \
    # -values [list $f $type $size $fdate $ftime] \
    # -image ::img::cb(0)]


    ### only open folders that are not empty
    ### THIS FOLDER HAS A DISPLAYABLE FILE IN IT
    ### AUTOMATICALLY OPEN IT
    $tree set $id size $size
    $tree item [$tree parent $id] -open 1 -tags FOLDER_HAS_ITEM

    } else {
    # a file type that will not be shown
    }
    }


    # Stop this code from rerunning on the current node
    $tree set $node type processedDirectory
    }


    # ## Create the tree and set it up
    proc display_tree {tw ROOT SHOW_TYPES} {
    catch { destroy $tw.tree }
    catch { destroy $tw.vsb }
    catch { destroy $tw.hsb }
    catch { destroy $tw.dummy }

    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" -anchor w
    $tw.tree heading date -text "Last Mod Date" -anchor w
    $tw.tree heading time -text "Last Mod Time" -anchor w

    $tw.tree column size -stretch 1 -width 20
    $tw.tree column date -stretch 1 -width 20
    $tw.tree column time -stretch 1 -width 20


    ### you can make files and non-empty folders more visible
    ### by playing around with colors and fonts as below
    ### change or remove as needed
    $tw.tree tag config SHOW_FILE -foreground blue -font bold
    $tw.tree tag config FOLDER_HAS_ITEM -foreground red -font bold


    populateRoots $tw.tree $ROOT $SHOW_TYPES
    bind $tw.tree <<TreeviewOpen>> {populateTree %W [%W focus]
    $SHOW_TYPES}

    ## put this bind inside display_tree with the other bind
    bind $tw.tree <ButtonRelease-1> {manage_sel %W}
    #bind $tw.tree <Button-1> {manage_sel %W}

    # ## 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


    }



    proc manage_sel {tw} {
    set sel [$tw item {} -values]
    set new [$tw focus]
    #set img 0
    if {$new eq ""} {
    return
    } elseif {[$tw set $new type] ne "file"} {
    set sel [lremove $sel $new]
    #set img 0
    } elseif {$new in $sel} {
    #set img 1
    set sel [lremove $sel $new]
    } else {
    lappend sel $new
    #set img 1
    }

    $tw item {} -values $sel
    # try and change checkbutton image
    #$tw item {} -values $sel -image ::img::cb($img)
    #$tw item {} -image ::img::cb($img)
    $tw selection set {}
    $tw selection set $sel
    }


    proc run_test {} {

    wm iconify .


    ### first window
    set ROOT_1 "C:/Dev"
    set SHOW_TYPES [list .ini .txt .docx]


    catch {destroy .t1 }
    toplevel .t1
    wm title .t1 $ROOT_1
    wm geom .t1 500x400

    display_tree .t1 $ROOT_1 $SHOW_TYPES


    ### second window with different files to show
    set ROOT_2 "C:/Windows/INF"
    set SHOW_TYPES [list .ini .csv]

    catch {destroy .t2 }
    toplevel .t2
    wm title .t2 $ROOT_2
    wm geom .t2 800x600

    display_tree .t2 $ROOT_2 $SHOW_TYPES
    }


    ### start here
    run_test

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to GeorgeB on Fri Sep 30 18:06:51 2022
    GeorgeB <george.booth3182@gmail.com> wrote:
    On Friday, September 30, 2022 at 3:14:40 PM UTC+1, Rich wrote:
    GeorgeB <george.b...@gmail.com> wrote:
    On Friday, September 30, 2022 at 3:47:23 AM UTC+1, Rich wrote:
    GeorgeB <george.b...@gmail.com> wrote:
    I seem to get error invalid command name "lremove"
    What version of Tcl are you using?

    @saitology9, thanks that got rid of the error message but the
    bandings seem to have disappeared.

    @Rich, using TCL 8.6.9

    Ok, that explains why you saw no lremove, lremove was added in of 8.7.

    Note, it is better to reply to each message, not "group replies" into a
    single one. Most of us here are not using that absolutely awful google
    groups interface, and doing "group replies" breaks the message
    threading for everyone else.

    Ahh, understood.

    Btw in my earlier message I mentioned that banding i.e. highlighted
    row upon selection seemed to have disappeared. That does happen but
    only when I run the code with other parts of my GUI application.

    If I run the code (shown below) in a fresh clean script and run it
    from command line....all is good.

    So, where would I start looking if I had to debug. I think "$tw
    selection set $sel" is not being set hence I can not see selection on
    screen but if I print $sel to console, then it shows the items that I
    have clicked on the tree.

    If the color highlight of selected rows disappears when you've run that
    code along with the rest of the script, then 'where' is: "somewhere in
    that other code". I.e. something is being done by that other code that
    is causing you the troubles.

    Some possibilities might include:

    1) changing the default colors for 'highlights' to be the same as
    'not highlighted'

    2) mucking about with the event bindings that provide the abililty to
    select rows and cause them to be highlighted.

    You can see how the various 'interactions' between the mouse
    cursor/buttons and keyboard keys work for the treeview widget by
    looking at the bindings in the treeview.tcl file in your Tcl
    installation.

    For me, on Linux, that file is located at: /usr/lib/tk8.6/ttk/treeview.tcl

    For you, on windows, it will obviously be somewhere else within the Tcl installation location.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)