TreeView Tooltips

Difference between version 3 and 4 - Previous - Next
[Keith Vetter] 2009-11-07 : I love tile's [ttk::treeview%|%treeview%|%] widget but 
one thing it lacks are the virtual events needed for [balloon help%|%tooltips].
Specifically, it lacks the <Enter> and <Leave> events that are
needed to know when to post or remove a tooltip window.

This page is mis-titled--there's no code here for actually
creating [balloon help%|%tooltips]. Rather this package allows an [ttk::treeview%|%treeview%|%]
widget to generate two new virtual events when the mouse
moves between rows in the tree. (Taking this and creating
actual tooltips is left as an exercise for the reader.)

The two new virtual events for a [ttk::treeview%|%treeview%|%]
widget are: <<RowEnter>> and <<RowLeave>>. Both provide
five event fields: %d => treeview row id plus %x, %y, %X 
and %Y. It works by hooking into the <Motion> event,
tracking the row the mouse is in and firing events when
that changes.

As always, there's some demo code to show how to
use it.

----

======
namespace eval ::ToolTipTV {}

proc ::ToolTipTV::Init {W} {
    set ::ToolTipTV::LAST($W) ""
    set ::ToolTipTV::AFTERS($W) ""
    bind $W <Motion> [list ::ToolTipTV::_onMotion %W %x %y %X %Y]
}
proc ::ToolTipTV::_onMotion {W x y rootX rootY} {
    variable LAST
    
    set id [$W identify row $x $y]
    set lastId $::ToolTipTV::LAST($W)
    set ::ToolTipTV::LAST($W) $id

    if {$id ne $lastId} {
        after cancel $::ToolTipTV::AFTERS($W)
        if {$lastId ne ""} {
            event generate $W <<RowLeave>> \
                -data $lastId -x $x -y $y -rootx $rootX -rooty $rootY
        }
        if {$id ne ""} {
            set ::ToolTipTV::AFTERS($W) \
                [after 300 event generate $W <<RowEnter>> \
                     -data $id -x $x -y $y -rootx $rootX -rooty $rootY]
        }
    }
}

################################################################
#
# Demo code
#

::ttk::label .msg -font "Times 24 bold" -textvariable ::msg -width 20 \
    -background yellow -borderwidth 2 -relief ridge

::ttk::treeview .tree -height 15 -show tree \
    -yscroll ".vsb set" -xscroll ".hsb set" -selectmode browse
::ttk::scrollbar .vsb -orient vertical -command ".tree yview"
::ttk::scrollbar .hsb -orient horizontal -command ".tree xview"

grid .msg - -sticky ew
grid .tree .vsb -sticky nsew
grid .hsb       -sticky nsew
grid column . 0 -weight 1
grid row    . 1 -weight 1

foreach txt {first second third} {
    set id [.tree insert {} end -text "$txt item" -open 1]
    for {set i [expr {1+int(rand()*5)}]} {$i > 0} {incr i -1} {
        set child [.tree insert $id 0 -text "child $i"]
        for {set j [expr {int(rand()*3)}]} {$j > 0} {incr j -1} {
            .tree insert $child 0 -text "grandchild $i"
        }
    }
}
::ToolTipTV::Init .tree
bind .tree <<RowEnter>> { set ::msg "Entering row %d"}
bind .tree <<RowLeave>> { set ::msg "Leaving row %d"}
return
======
----

**Discussion**

[DDG] 2020-06-07: on [ttk::treeview mixins] I created a snit widgetadaptor based on the code above which simplifies the addition of multiple of such small additions such as tooltips, banding stripes  to the [ttk::treeview] widget.
<<categories>> balloon help | GUI | Tk | treeview Widget