Editwin is a simple package that adds a toplevel edit entry to a widget. You can use it for example to change the value of a label.
The entry can be canceled with Escape or clicking anywhere in the containing toplevel. Confirmed your edit with Return.
# ------------------------------------------------------------------------
# editwin, version 0.2
# a simple toplevel entry bound to a widget and a variable
#
# Copyright (c) 2009 Uwe Koloska, voice INTER connect GmbH
# ------------------------------------------------------------------------
#
# This library is free software; you can use, modify, and redistribute it
# for any purpose, provided that existing copyright notices are retained
# in all copies and that this notice is included verbatim in any
# distributions.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# ------------------------------------------------------------------------
package require Tk 8.5
namespace eval editwin {
namespace export editwin
}
proc editwin::editwin {w var args} {
variable {}
array set opts {
-validatecommand ""
-width 20
}
array set opts $args
set ($w,var) $var
set ($w,validate) $opts(-validatecommand)
set ($w,width) $opts(-width)
bind $w <Double-ButtonPress-1> [namespace code [list _do $w]]
}
proc editwin::_do {w args} {
variable {}
set var $($w,var)
set tl [winfo toplevel $w]
if {$tl eq "."} {
set ewin .edit
} else {
set ewin $tl.edit
}
set ewinRoot $ewin
set num 0
while {[winfo exists $ewin]} {
incr num
set ewin ${ewinRoot}$num
}
unset ewinRoot num
set ($w,widget) $ewin
catch {destroy $ewin}
set ($w,value) [set $var]
ttk::entry $ewin -textvariable [namespace current]::($w,value) -width $($w,width)
if {$($w,validate) ne ""} {
$ewin configure -validate key -validatecommand $($w,validate)
}
set x [expr {[winfo rootx $w] - [winfo rootx $tl]}]
set y [expr {[winfo rooty $w] + [winfo height $w] - [winfo rooty $tl]}]
place $ewin -x $x -y $y
$ewin selection range 0 end
bind $ewin <Escape> [namespace code [list _end $w]]
bind $ewin <Return> [namespace code [list _set $w]]
set ($w,bpCallback) [bind $tl <ButtonPress>]
bind $tl <ButtonPress> [namespace code [list _end $w]]
focus $ewin
}
proc editwin::_set {w} {
variable {}
set $($w,var) $($w,value)
_end $w
}
proc editwin::_end {w} {
variable {}
destroy $($w,widget)
bind [winfo toplevel $w] <ButtonPress> $($w,bpCallback)
set ($w,bpCallback) {}
}And here an overly complex demo app that had shown a problem with the focus -- this was fixed in 0.2.
#! /usr/bin/env tclkit8.5
package require Tk 8.5
set scriptdir [file dirname [info script]]
source [file join $scriptdir editwin.tcl]
set __oldFocus ""
proc showFocus {} {
set focus [focus]
if {$focus ne $::__oldFocus} {
set last [focus -lastfor .]
puts "focus = '$focus' (last = '$last')"
set ::__oldFocus $focus
}
after 1000 showFocus
}
proc validateMynum {value} {
if {$value eq "+" || [string length $value] == 0} {
set result 1
} elseif {[string is double $value]} {
set result [expr {$value > 0.0 && $value < 30.0}]
} else {
set result 0
}
return $result
}
set validatecommand {validateMynum %P}
ttk::label .edit -textvariable mynum -background lightgreen -width 5
editwin::editwin .edit ::mynum -validatecommand $validatecommand -width 5
ttk::button .b1 -text "Button 1"
ttk::button .b2 -text "Button 2"
ttk::entry .e1 -textvariable myentry
pack .b1 .e1 .edit .b2 -side top -padx 64 -pady 32
set mynum 31.2
set myentry "some text"
showFocus2009-11-06 UKo: v0.1 first version that needs a focus fix on linux (tested with 8.5.7) 2009-12-07 UKo: v0.2 the version that fixes this nasty focus bug