[Keith Vetter] 2005-10-27 : A recent project of mine required using [Tktable] for three tables. One of the tables was complex, with scrolling, spans and conditional formatting, but the other two tables were just simple forms with a title row, some readonly columns and the rest were editable cells. I found for those simple tables that Tktable was a bad fit. The biggest problem was that the users expected the editable cells to act like entry widgets but they don't: you can't select with the mouse, arrow keys take you out of the cell, and tabbing takes you out of the table. So instead I cobbled together what I call a '''simpleTable''' megawidget. It's a grid of entry and label widgets tied together with a shared -variable array. It has a simple subset of Tktable's options, including ''-variable'', ''-rows'', ''-cols'', ''-titlerows'', ''-titlecols'', ''-readonlyrows'', ''-readonlycols'', and ''-vcmd''. Fairly simple code--if you take out the error checking code, it's not much longer than the code to create a tktable with all its options and necessary tag configures. ---- ====== ##+########################################################################## # # simpleTable.tcl -- replacement of tktable for simple tables # by Keith Vetter, October 2005 # proc simpleTable {pathName args} { set legal {-rows -cols -titlerows -titlecols -vcmd -readonlyrows -readonlycols -variable} array set A {-rows 5 -cols 5 -titlerows 0 -titlecols 0 -readonlyrows {} -readonlycols {}} if {[llength $args] == 0} { error "usage: simpleTable pathName -variable varName ?options...?" } set idx -1 foreach {opt value} $args { if {[lsearch $legal $opt] == -1} { error "unknown option \042$opt\042" } if {[incr idx 2] >= [llength $args]} { error "value for \042$opt\042 missing" } set A($opt) $value } if {! [info exists A(-variable)]} { error "missing the \042-variable\042 option" } # Now build our table destroy $pathName frame $pathName for {set r 0} {$r < $A(-rows)} {incr r} { for {set c 0} {$c < $A(-cols)} {incr c} { set w "$pathName.r${r},$c" if {$r < $A(-titlerows) || $c < $A(-titlecols)} { if { $::tcl_platform(platform) eq "windows" } { set bg SystemDisabledText } else { set bg darkgrey } label $w -textvariable $A(-variable)\($r,$c\) \ -relief flat -bg $bg -fg white } elseif {[lsearch $A(-readonlyrows) $r] != -1 || \ [lsearch $A(-readonlycols) $c] != -1} { label $w -textvariable $A(-variable)\($r,$c\) \ -relief sunken -bd 2 $w config -font [lindex [$w config -font] 3] } else { entry $w -textvariable $A(-variable)\($r,$c\) \ -relief sunken -bd 2 -justify center -width 9 if {[info exists A(-vcmd)]} { $w config -validate key \ -vcmd [list $A(-vcmd) $r $c %P] } } grid $pathName.r${r},$c -row $r -column $c -sticky ew } } } ################################################################ # # Demo code # package require Tk # Fill in our table variable set rows 10 unset -nocomplain table array set table { 0,0 Position 0,1 "Last Name" 0,2 "First Name" 0,3 "Home Runs" } for {set row 1} {$row < $rows} {incr row} { set table($row,0) [expr {$row == 1 ? "1st" : $row == 2 ? "2nd" : $row == 3 ? "3rd" : "${row}th"}] set table($row,1) "" set table($row,2) "" } set table(1,1) "Aaron" ; set table(1,2) "Hank" ; set table(1,3) 755 set table(2,1) "Ruth" ; set table(2,2) "Babe" ; set table(2,3) 714 set table(3,1) "Bonds" ; set table(3,2) "Barry " ; set table(3,3) 703 set table(4,1) "Mays" ; set table(4,2) "Willie " ; set table(4,3) 660 set table(5,1) "Robinson" ; set table(5,2) "Frank " ; set table(5,3) 586 set table(6,1) "McGwire" ; set table(6,2) "Mark " ; set table(6,3) 583 set table(7,1) "Sosa" ; set table(7,2) "Sammy " ; set table(7,3) 574 # validate command for our table's last column: only allow valid numbers proc vcmd {row col val} { if {$col < 3} { return 1 } if {[regexp {\s} $val]} { return 0 } return [string is double $val] } simpleTable .t -variable table -rows $rows -cols 4 \ -titlerows 1 -readonlycols 0 -vcmd vcmd pack .t -padx 1i -pady .5i return ====== ---- [EKB] As a less streamlined approach, I set up a TkTable widget to pop up an entry widget in the active cell on either a dbl-click event or a keyboard shortcut. The code is here: [Inserting an Entry Widget in TkTable] ---- [HJG] I don't understand the intention of proc vcmd: in the "First Name"-column, only numbers are allowed ? [LV] I agree. I just tried running this on a Windows XP SP2 system using Tcl 8.4.6. What I got was the first name column permitting me to put anything, including white space, the last name column not permitting me to make any changes, and the numeric field allowing numbers. Was that the intent? [KPV] Oops, a mis-copy. It should be that the last column only allows valid numbers. Fixed the code so that vcmd only does it check when the column is the last column. ---- [ICU] - 2010-03-01 02:11:56 Any idea how you could add a scrollbar to this? [Martyn Smith] Take a look at BWidget ScollableFrame then use the frame as the base for this widget. ---- '''[ICU] - 2010-03-01 07:18:44''' I was able to make it work. Still need to figure out how to make the frame fill both vertical and horizontal. Anyway thanks! <> GUI | Widget