Version 6 of Displaying tables

Updated 2004-02-04 11:57:29

Arjen Markus The following script is a result of suggestions by Andreas Kupries and Jeff Hobbs: how to display tabular data.

The ::struct::matrix module in Tcllib makes it very easy to manage data in the form of a table. The Tktable extension is capable of showing data in the form of a table, but it uses a different method for storing the data. Luckily, the ::struct::matrix module has a command to link the matrix to an array (and vice versa).

Note: from my (very) limited experience I conclude that things are not quite perfect yet. But, with just twenty lines of code, one can achieve a beautiful demonstration of the ideas!


Some imperfections:

  • The order for creating the array and linking it to a matrix is fixed.
  • Updates to the matrix (via the matrix's methods) are not always reflected in the table. Changes in the table (via the widget) are.

   # Demonstrate the combination of ::struct::matrix and Tktable
   #
   package require struct
   package require Tktable

   #
   # Create a matrix called "simpleTable"
   #
   ::struct::matrix simpleTable

   #
   # The matrix must have some columns before it will accept rows
   #
   simpleTable add columns 4
   simpleTable add row {A1 A2 A3 A4}
   simpleTable add row {B1 B2 B3 B4}
   simpleTable add row {C1 C2 C3 C4}

   #
   # A small glitch in the default formatter makes it necessary to
   # force a new line
   #
   simpleTable format 2chan
   puts ""

   #
   # Note: the array table_data must be defined before the link
   # with the matrix!
   #
   table .table -variable table_data -width 4 -height 3
   pack .table -fill both

   simpleTable link -transpose table_data

   simpleTable set cell 2 2 XX

   puts "Elements: [array get table_data]"

http://Mini.net/files/table.jpg RS likes to depend on nothing (and has no Tcllib or Tktable on the iPaq, for instance). Here's a minimal solution to display a table (list of lists) in a grid of labels:

 package require Tk
 proc table {w content args} {
     frame $w -bg black
     set r 0
     foreach row $content {
         set fields {}
         set c 0
         foreach col $row {
             lappend fields [label $w.$r/$c -text $col]
             incr c
         }
         eval grid $fields -sticky news -padx 1 -pady 1
         incr r
     }
     set w
 }

#--- Test:

 table .t {
    {Row Head1 Head2}
    {1   foo   42}
    {2   bar   1234}
    {3   grill testing}
 }
 pack .t

#--- Changing the contents, given row and column number:

 after 2000 .t.3/2 config -text Coucou

 bind . <Escape> {exec [info na] $argv0 &; exit}