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" showFocus
2009-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