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 focussing any other widget and confirmed with `Return`. ====== # ------------------------------------------------------------------------ # editwin, version 0.1 # 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 {validatecommand ""}} { variable {} set ($w,var) $var set ($w,validate) $validatecommand bind $w [namespace code [list _do $w]] } proc editwin::_do {w args} { variable {} set var $($w,var) set top $w.edit set ($w,top) $top catch {destroy $top} toplevel $top -class EditWin wm overrideredirect $top 1 wm transient $top $w if {[string equal [tk windowingsystem] aqua]} { ::tk::unsupported::MacWindowStyle style $top help none } set ($w,value) [set $var] set e $top.entry ttk::entry $e -textvariable [namespace current]::($w,value) -width 4 if {$($w,validate) ne ""} { $e configure -validate key -validatecommand $($w,validate) } pack $e set wmx [winfo rootx $w] set wmy [expr {[winfo rooty $w] + [winfo height $w]}] set wmw [winfo reqwidth $e] set wmh [winfo reqheight $e] wm geometry $top ${wmw}x${wmh}+${wmx}+${wmy} raise $top $w $e selection range 0 end bind $e [namespace code [list _end $w]] bind $e [namespace code [list _set $w]] # FIXME: destroy the widget if the user clicks anywhere outside # destroy on FocusOut is a good workaround bind $e [namespace code [list _end $w]] focus $e } proc editwin::_set {w} { variable {} set $($w,var) $($w,value) _end $w } # FIXME: on Linux the focus will be empty after destroy proc editwin::_end {w} { variable {} destroy $($w,top) } ====== And here an overly complex demo app that shows a problem on linux: When leaving the edit entry with Escape or Return, the focus becomes an empty string and the next invocation of the edit window doesn't change the focus and so the entry cannot be controlled with the keyboard. On windows it works as expected and after closing the entry, the focus is back to what it was before. ====== #! /usr/bin/env wish8.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} { puts "focus = '$focus'" 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 .num1 -textvariable mynum -background lightgreen -width 5 editwin::editwin .num1 ::mynum $validatecommand ttk::button .b1 -text "Button 1" ttk::button .b2 -text "Button 2" ttk::entry .e1 -textvariable myentry pack .b1 .e1 .num1 .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) <>GUI