Updated 2018-08-13 13:02:45 by pooryorick

tktable, is a 2D table widget for Tk.

See Also  edit

Displaying Tables
VUW widgets

Attributes  edit

old website

Documentation  edit

man page (alternate)
A Busy Developer's Guide to TkTable, by Scott Gamon ()

Description  edit

lm: I'm using the Tktable instead of the widget text in case of very long text (200-500 lines of 2000-5000 characters , all tagged with colors). In such case, the text widget scrolling is terrible, and the Tktable is quite correct. I put one character per cell, and no padx pady borderwidth, .... Abug remains, and yet not fixed: even if all padding between rows are set to 0, there is still one pixel added between rows, so the table doesn't look exactly as its text widget conterpart.. But it's still better than nothing !

snichols: Does anyone have any code snipits they could put together for sorting relational data in tkTable? We use Tktable to show the result set from an SQL query. It would be very nice to be able to sort records decending or ascending in Tktable (one line of data in Tktable) when a user clicks on a column header (Column title, aka metadata: data that describes data). I invision when the user clicks on a column header all the relational data is sorted ascending, if the user clicks again its sorted descending.

Scott Nichols: I am using the Tktable in a basic GUI (see tab example below). I recommend setting -sparsearray to false. Because when it is on (default) and -cache is on too the application becomes unstable and will shutdown when a user erases several cell values.

There appears to be more than one widget by this name. The one most people think of is likely this one:
 What: tkTable - Tk table widget (Hobbs)
 Where: http://tktable.sf.net/ 
 Description: Editable 2D table/matrix widget.
        Tag styles for multiple fonts, colors, etc.
        It is a complex blend of the Tk entry, listbox, and text widgets.
        Has embedded window support, multi-line cell text support.
        This is based on the Ellson/King tkTable available earlier.
        Requires Tk 8.x or newer and a C compiler.
        Supports all Unix Tcl/Tk variants as well as Windows and
        The spec and rm files are used to build Redhat Linux rpm packages.
        They require Tcl/Tk 8.3 rpm, also available on the jfontain site.
        A precompiled Tk 8.1 Windows DLL is available.
        A binary version for Windows is also available.
        Version 2.10 now available.
 Updated: 12/2001
 Contact: mailto:[email protected]  (Jeffrey Hobbs)

 What: Tk table widget (Ellson)
 Where: ftp://ftp.procplace.com/pub/tcl/sorted/packages-7.6/devel/graphics/tkTable-0.4p8.tar.gz
 Description: A table/matrix widget, written in C, variable width table columns
        and height rows, titles, attaches to an array variable,
        supports standard Tk reliefs/fonts, support scrollbars,
        has tag styles per row/column/cell for changing colors/fonts/relief or
        anchor position, in-cell editing, different editing/drawing modes,
        can have selected cell or not, optional update flashes,
        can stretch rows and columns.
        Contact John Ellson for patches to Table_Display.c and the
        tkAppInit to get it to work with Tk 4.0.
 Updated: 10/1998
 Contact: mailto:[email protected]  (current maintainer)
        mailto:[email protected]  (Roland King - original author)
        mailto:[email protected] 

Scott Nichols: Here's a little Tktable code snipit you may find useful. This code will create keyboard tab bindings for the tktable. If the current cell is less than the number of columns when the user presses the tab key, the cursor will move to the next cell (to the right of the current cell), but if the cell is the very last cell in the row, then it will move to the first column of the next row when the user presses tab. If the cell is the very last cell in the table, the binding will create a new row and move the cursor to the first cell in the new row that was just created when the user presses the tab key:
bind $table <Tab> {
    set top  [expr {[%W cget -roworigin] + [%W cget -titlerows]}]
    set left [expr {[%W cget -colorigin] + [%W cget -titlecols]}]

    if {[catch {%W index active} result] ||
            [lassign [split $result ,] row col
            expr {$row < $top || $col < $left}]} {
        ::tk::table::BeginSelect %W $top,$left
        %W activate $top,$left
    } else {
        lassign [split $result ,] row col
        if {$col < [%W cget -cols] - 1} {
            ::tk::table::MoveCell %W 0 1
        } elseif {$row < [%W cget -rows] - 1} {
            set x [expr {[%W cget -titlecols] - [%W cget -cols] + 1}]
            ::tk::table::MoveCell %W 1 $x
        } else {
            # Open new row.  (Original behavior.)
            %W insert rows end
            ::tk::table::MoveCell %W 1 -[%W cget -cols]

            # Or return to upper-left.
            #set y [expr {[%W cget -titlerows] - [%W cget -rows] + 1}]
            #set x [expr {[%W cget -titlecols] - [%W cget -cols] + 1}]
            #::tk::table::MoveCell %W $y $x

AMG: Scott's code snippit, while a good start, had a number of problems (unnecessary nested exprs, mismatched brackets, failure to handle the case of no active cell or active cell inside the title, no consideration for -titlecols) so I rewrote it. If you want editable titles I guess you'll have to rewrite it again. :^)

snichols: Thanks for the code update. My original code I posted worked Ok for my implementation as long as there were not any embedded widgets. Sorry you had problems. AMG, were you able to fix tabbing in cells when there was a widget embedded in the cell?

The thing with lassign and the newline inside the [...] is rather weird. If someone can think of a better way of expressing this, feel free to fix the code.

AM: You can easily embed windows in a cell, using Jeff's Tktable. Here is a code snippet to show the basics:
package require Tktable

pack [table .t] -fill both
checkbutton .t.c 
.t window configure 1,1 -window .t.c


  • The checkbutton (or any other window you want to embed) must be a child of the table widget
  • The command ".t window configure" is then used to embed that window in a particular cell - you can use any of the forms for a cell index, but a constant pair "row,column" seems most practical/common

From: Eric Kemp-Benedict ([email protected]) I use TKTable in a couple of my projects (IPAT Studio and IPAT DX, both available from http://ipat-s.kb-creative.net/ and on SourceForge at http://sourceforge.net/projects/ipat-s/). I like TkTable a lot, with one exception. It doesn't seem possible to select all of the text in a cell (e.g., to completely replace it), either by dragging with the mouse or by double-clicking (usual behavior in Excel). Does this bother anyone else? And do you have a fix for it?

LV: Eric, it is surprising, to me, that the default behavior for tktable is this way. However, take a look at the Busy Developer's Guide mentioned near the top of this page and the example there shows how to set up tktable so that you can select the text.

HRB54: That's a way to get an entire cell selected. But there remains the manko, that with TkTable, you're not able to select only part of the text in a cell, like it's also impossible to move the icursor (the text cursor of the active cell) by cursor keys with the default bindings of TkTable.

Thank you. - Eric

From: Roland ([email protected]) Subject: Auto-adjust height of TkTable rows to fit multiline cells

Here's a short script to do that job (note that startrow is 1 to skip title row):
set maxr [.table cget -rows]
set maxc [.table cget -cols]
for {set r 1} {$r < $maxr} {incr r} {
    set maxh 1
    for {set c 0} {$c < $maxc} {incr c} {
        if {[set n [llength [split [.table get $r,$c] \n]]]>1 && $maxh<$n} {
            set maxh $n
    .table height $r $maxh

From: MarkE

Subject: Tktable questions on ordering

How should a table be created where rows are added at the top ? For what it's worth I'm coding via Tkinter in Python rather than tcl directly.

I want to prepend data results to a table. If I use the command call-back approach and simply increase the number of rows, I'm hoping it will work but I anticipate severe slow-ness since rather than just drawing the new row, won't the table treat this as if every single row had changed and redraw everything ? For example I'm guessing the cache (which I intended to use) is index based. Am I right in thinking this will be a problem, and if so is there any way around it ?

QUESTION: Calling "insert_rows" seems to have no effect (i.e. mytable.insert_rows(1, 1) does nothing). ANSWER: If I'd read the man page more closely, I'd have noticed "all insert or delete methods will be ignored" when the state is disabled.

Am I even using the appropriate class here (direct Tkinter support for the Tix grid is pretty non-existent as far as I can tell which is how I ended up here) ?

Similarly is the command-callback approach the best way to sort data ?

And finally, where should tktable questions be sent ? Didn't seem right to start emailing the authors out of the blue.

Thanks for any help... I'm adding to the bottom (well almost)

2004-12-21: Are people adding to the top or bottom of this page? Is Scott just now looking for code to sort a TkTable or has Mark just starting wondering about adding rows to the top of the table?

Would anyone else like to see smooth (line-at-a-time) scrolling in TkTable? I have an application that has multi-line rows and find row-at-a-time scrolling to be quite disconcerting and visually jarring. I'd like to add -scrollmode [row|line|pixel] where row is the current and new default behavior. Any thoughts? --Chris Nelson

Chris Nelson 2005-01-10 : Progress report: I'm making good progress adding smooth scrolling to TkTable. A week or so more and I may have it, at least for vertical scrolling.

Chris Nelson 2005-01-18: Progress report: I just submitted patch 1104766 [1] at SourceForge. It includes support for smooth vertical scrolling with a couple of minor exceptions.

KPV 2005-10-27 : see Simple Tktable for a simplified version of Tktable that works well for simple form-like tables.

EKB 2005-10-27 : and here's my code for Inserting an Entry Widget in TkTable. By double-clicking on a cell, it pops up an edit widget in the cell.

DLS 2005-12-13 : Could some explain how I might change the default behavior of cursor movement across the grid so that it doesn't "jump" to make the current row the second row? In my own tables, and the demos, if the window is so small that all columns cannot be seen (which is often the case for me) then if the cursor is highlighting a cell in a row low in the window, it will shift up when you get to the newly exposed column. I'd like to stay at the same vertical location in the window, to make it clear that the row is the same. A side product of this behavior is that after the active row shifts up to the second row, then vertical cursor movement makes the table shift up/down with respect to the second row (i.e. the table contents slide under the cursor) as opposed to simply moving the cursor up or down. Is there a setting I'm missing?

LV 2006-10-26: A developer just asked for an example of how to bind MouseWheel events to tktable. They are using Windows. They had tried:
bind $w <MouseWheel> [list namespace code [list MouseScroll %D $w.table]]

but MouseScroll never seemed to get called.

The $w is the toplevel window containing the table. Does anyone have any suggestions?

AEC: mouse wheel events only get dispatched to an element which has focus.

bind $widget <Enter> {focus %W}

For how to fix the daft operator of the mouse wheel, go to TIP 171: http://www.tcl.tk/cgi-bin/tct/tip/171.html