[Arjen Markus] (1 july 2005) I am not sure whether the name "properties editor" is the official name for a widget like this, but given the context in which I have seen it in use, I'd say it is pretty close. The idea is that some entity in a program has a bunch of properties and rather than designing a specific dialogue/window to view and change the values of these properties, you simply use a generic one. The only thing you need as a programmer is the ''names'' of these properties, supposedly descriptive and informative to the actual user, and the ''types'' of these properties, an arbitrary string, a file name, ... So, when I had seen this type of widget for the n'th time, I thought: I can do this in Tk, can't I? The script below is the result of about half an evening at the keyboard and screen. It is not perfect, it does not classify as a (meta-)widget, but in principle it is useful. Enjoy and improve! (Oh, yes, some statements are more complicated than they need to be, but they are internal, so I do not care too much :)) Things to improve: * Add a scrollbar * Make sure the names of the variables are lined up (columns of equal width for all frames) * Make sure the names of the variables are justified to the left * More variable types * Turn it into an actual meta-widget Things puzzling: * The [[grid]] geometry manager does not always comply to the sticky option - or at least that is what I saw with Tcl/Tk 8.4.1 (I know, oldish ;)) (Peter Spjuth helped with this one: I needed to allow the grid's columns to expand. Just a note, as below I use a spinbox instead) * The width of the widgets inside this "editor" must be carefully controlled, otherwise you get different results with different platforms. ---- # properties.tcl -- # Simple properties editor # # PropertiesColor -- # Select a new color # # Arguments: # wcolor Name of the label that gets the color # var Name of the variable associated with it # Result: # None # proc PropertiesColor { wcolor var } { set color [uplevel #0 [list set $var]] set color [tk_chooseColor -initialcolor $color -parent $wcolor] if { $color != "" } { $wcolor configure -bg $color uplevel #0 [list set $var $color] } } # PropertiesShow -- # Show or hide a frame # # Arguments: # wcheck Name of the checkbutton # wframe Name of the frame # Result: # None # proc PropertiesShow { wcheck wframe row } { set var [$wcheck cget -variable] if { [uplevel #0 [list set $var]] == 1 } { grid configure $wframe -row $row -sticky news } else { grid forget $wframe } } # propertiesEditor -- # Create a new window to edit properties # # Arguments: # widget Widget name # properties Definition of the properties # valuesName Name of a (global) variable containing the values # Result: # The widget name # proc propertiesEditor { widget properties valuesName } { upvar #0 $valuesName values set group 0 set row 0 set count 0 set w [frame $widget] set wg $w foreach {type name} $properties { switch -- $type { "group" { set values($name) 1 set wt [checkbutton $widget.t$group -text $name \ -variable "${valuesName}($name)" \ -offrelief flat \ -overrelief flat ] set wg [frame $widget.w$group -relief solid -bd 2 \ -bg white] grid $wt -sticky w grid $wg -sticky news incr group incr row $wt configure -command [list PropertiesShow $wt $wg $row] incr row set count 0 } "string" { set wl [label $wg.l$count -text $name -fg black -bg white] set we [entry $wg.e$count -textvariable "${valuesName}($name)" ] grid $wl $we - -sticky w incr count } "logical" { #set wc [checkbutton $wg.c$count -text $name \ # -variable "${valuesName}($name)" -justify left] #set dummy [label $wg.l$count -text " " ] #grid $wc $dummy -sticky news ;# Stickiness does not work as I expected set wl [label $wg.l$count -text $name \ -fg black -bg white] set ws [spinbox $wg.s$count -values "True False" \ -textvariable "${valuesName}($name)" \ -fg black -bg white] grid $wl $ws - -sticky w incr count } "color" { set wl [label $wg.l$count -text $name -fg black -bg white] set wc [label $wg.c$count -text \ [string repeat " " 20] -bg $values($name)] set wb [button $wg.b$count -text "Choose" \ -command [list PropertiesColor $wc "${valuesName}($name)"]] grid $wl $wc $wb -sticky w incr count } } } return $w } # main -- # Testing the above procedures # set valuesx(name) "My name" set valuesx(address) "My address" set valuesx(value) 0 set valuesx(myfavourite) red set props {group Personalia string name string address group Data logical value color myfavourite } set w [propertiesEditor .w $props valuesx] pack $w -fill both ---- [[ [Category design] ]]