(This is my first page on the Wiki, so please forgive me if I make some mistake.)
I'm experimenting in Tcl/Tk some ui concepts often found in applications out there. The one I'm showing you this time is what I called "in place edit": a (sort of) widget linked to another one which you can use to change a value of the latter without opening dialog boxes. To be practical, this could be a sample use of the IPE (In Place Edit):
Please note that this is a (simple) experiment and not production ready code. Moreover, I'm testing the code on Linux and fixing it for that system (however, it seems to work on Windows, too).
First, let's see some pictures of the code in action!
Here, I change the text of a label, by double-clicking on it, editing it, and finally hitting Enter.
Here, I do the same with a button, but double-right-clicking on it!
Finally, let's see how the code works with toplevel captions too (by double-clicking on the toplevel empty area):
Now, this is the code I used: it contains both the code for the IPE and that for the usage samples.
namespace eval ipe { variable ipe variable tl variable tlbtnbind variable outvar } proc ipe::init {} { variable ipe set ipe [toplevel .ipe] wm withdraw $ipe wm protocol $ipe WM_DELETE_WINDOW ipe::hide wm attributes .ipe -topmost 1 wm overrideredirect .ipe 1 ttk::frame $ipe.f pack $ipe.f ttk::entry $ipe.f.e pack $ipe.f.e bind $ipe.f.e <Return> [list ipe::hide 1] bind $ipe.f.e <Escape> ipe::hide bind $ipe.f <FocusOut> ipe::hide } proc ipe::hide {{store 0}} { variable ipe variable outvar variable tl variable tlbtnbind bind $tl <Button> $tlbtnbind wm withdraw $ipe if { $store } { uplevel #0 set $outvar [list [$ipe.f.e get]] } } proc ipe::show {w txt outName} { variable ipe variable tl variable tlbtnbind variable outvar set outvar $outName set tl [winfo toplevel $w] set tlbtnbind [bind $tl <Button>] bind $tl <Button> ipe::hide $ipe.f.e delete 0 end $ipe.f.e insert 0 $txt wm deiconify $ipe wm geometry $ipe =+[winfo rootx $w]+[winfo rooty $w] focus $ipe.f.e } # # Samples # ttk::style theme use clam set labelvar "Testo" ttk::label .l -textvar labelvar pack .l set buttonvar "Pulsante" ttk::button .b -textvariable buttonvar pack .b ttk::entry .e pack .e proc tlcaption {name null op} { upvar #0 $name tlvar wm title .t $tlvar } toplevel .t trace add variable tlvar write tlcaption set tlvar "Finestra" ipe::init bind .l <Double-1> {ipe::show %W $labelvar labelvar; break} bind .b <Double-3> {ipe::show %W $buttonvar buttonvar; break} bind .t <Double-1> {ipe::show %W $tlvar tlvar; break}
The code above is really straightforward; I'm using Ttk widgets, but it seems to work with old fashioned Tk widgets, too.
(I posted a longer article about this experiment on my just created blog; you can also go there, if you like, but it is in italian: http://freeasinfreedom.altervista.org/2012/07/in-place-edit/ )
MarcoP (30 jul 2012): fixed broken image links; I changed my blog, reposted the article with the images and edited the links here.
RLE (2012-07-30): You can also achieve a similar effect using the place geometry manager to place your edit widget above the widget it is supposed to sit on top of. One advantage of using place is you avoid having to position a toplevel and thereby hope that the OS window manager obliges properly.
MarcoP (31 jul 2012): you are right, using the place geometry manager is another option; one (little) advantage of the toplevel is it becomes indepentent of the position of your application toplevel, so that you can always make it visible, even if the space in your application is too small.