Tk Source Code

View Ticket
Login
Ticket UUID: 2a6c62afd9c0d1d84ec0ef8407eb5613686a8b52
Title: ttk::treeview <<TreeviewSelect>> event bug
Type: Bug Version: 8.6.1
Submitter: anonymous Created on: 2014-01-19 23:52:17
Subsystem: 88. Themed Tk Assigned To: fvogel
Priority: 5 Medium Severity: Minor
Status: Closed Last Modified: 2022-03-07 22:06:09
Resolution: Fixed Closed By: fvogel
    Closed on: 2022-03-07 22:06:09
Description:
Tcl/Tk version 8.6.1

I just noticed while experimenting with the ttk::treeview that the treeview widget does not fire a <<TreeviewSelect>> event when an item that is presently selected is deleted.

Is this an intended outcome?  The manpage says:

       <<TreeviewSelect>>
           Generated whenever the selection changes.

It would seem that deleting an item that is selected is also a change to the selection, which should have fired a TreeviewSelect event.

Demo code:

  #!/usr/bin/wish

  ttk::treeview .t

  pack .t

  for {set i 1} {$i < 6} {incr i} {
    .t insert {} end -text "Item # $i"
  }

  bind .t <<TreeviewSelect>> show

  proc show {} {
    puts "TreeviewSelect fired"
    puts "Current selection is '[ .t selection ]'"
  }

  button .b1 -text "Clear Selection" -command {.t selection set ""}
  button .b2 -text "Delete Selected" -command {.t delete [.t selection]}

  pack .b1 .b2 -side top

Run the demo from a terminal so you can see the output of the puts.  Select one or more items with the mouse, notice the event fires.  While one or more items are selected, clear the selection using the "Clear Selection" button.  Notice that the event fires.

Now select one or more items and push the "delete selected" button.  Notice the items are deleted (and the selection disappears, because the selected items no longer exist) but no event fires.
User Comments: fvogel added on 2022-03-07 22:06:09:

Peter Spjuth sent me note of two important points and I thank him a lot for having done so:

  1. The implementation in commit [3bf60fa90a7ae1f9] is of quadratic complexity, which is not really acceptable.
2. It is virtually impossible to guarantee that a change has happened when the Virtual Event is resolved. Multiple selection commands can lead to multiple fired events before the event loop is entered and any event is resolved. This is illustrated by an example script I'm attaching. Thus we might end back where we started before the event handler sees anything. Any event handler for <<TreeviewSelect>> must thus cope with that nothing changed, and thus there is not much point in jumping through hoops to avoid that situation.

All this makes perfect sense and I have therefore applied the patch he proposed to deal with this situation, see [040f5aa0cb]. I have also backported this patch for 8.6, and this is [4a2f99f6].


fvogel added on 2021-12-04 18:39:05:
Merged into core-8-6-branch and trunk.

fvogel added on 2021-11-21 19:42:09:

All issues I know of are now fixed regarding <<TreeviewSelect>>.

I have added new tests (treeview-8.8 to -8.11) failing before the fix and passing after the fix. See branch bug-2a6c62afd9.


fvogel added on 2021-11-20 15:16:21:

In [comp.lang.tcl] there was a report about remaining issues regarding <<TreeviewSelect>>.

Specifically:

  1. .t selection set "" triggers <<TreeviewSelect>> even if there was no selection
  2. .t selection remove "" triggers <<TreeviewSelect>> even if there was no selection
  3. selecting already selected elements triggers <<TreeviewSelect>>
  4. .t selection toggle "" triggers <<TreeviewSelect>>

The following script can be used to see the issues:

  package require Tk
  ttk::treeview .t
  pack .t
  for {set i 1} {$i < 6} {incr i} {
    .t insert {} end -text "Item # $i"
  }
  bind .t <<TreeviewSelect>> show
  proc show {} {
    puts "TreeviewSelect fired"
    puts "Current selection is '[ .t selection ]'"
  }
  button .b1 -text "Clear Selection" -command {.t selection set ""}
  button .b2 -text "Delete Selected" -command {.t delete [.t selection]}
  button .b3 -text "Remove Selection" -command {.t selection remove [.t selection]}
  button .b4 -text "Add item" -command {.t insert {} end -text "Item  # [incr i]"}
  button .b5 -text "Set Focus 1" -command {.t focus I001}
  button .b6 -text "Get Focus" -command {puts [.t focus]}
  button .b7 -text "Select add 4 and 5" -command { .t selection add {I004 I005}}
  button .b8 -text "Select toggle 4" -command { .t selection toggle I004 }
  button .b9 -text "Select 2" -command { .t selection set I002 }
  pack .b1 .b2 .b3 .b4 .b5 .b6 .b7 .b8 .b9 -side top


fvogel added on 2019-05-26 19:08:25:
Merged to core-8-6-branch and trunk.

fvogel added on 2019-05-14 20:54:39:

Thanks for this excellent report and test script.

I have proposed a patch to fix this, see [1ce97bf4].

<<TreeviewSelect>> was not tested at all. In [e4000f37] I have therefore added two new tests, among which treeview-8.7 is speifically testing the fix of the present ticket.


Attachments: