Sarnold: Here is a mega-widget which works together with the Object-oriented SQLite wrapper.
package require Tk package require tableview_sql package provide tableview 0.1 namespace eval tableview { class create tableview { constructor {hullname sql tbl} { my variable hull set hull $hullname my variable table set table [tableview::table create $hullname.table $sql $tbl] my variable columns set columns "" my variable height my variable start set height 10 set start 1 toplevel $hull } # for debugging purposes method delegate {args} { my variable table $table {*}$args } method column {sub args} { my column_$sub {*}$args } method column_add {name args} { my variable table my variable columns set options [$table column info options] set myoptions {-width -title} dict set columns $name "" set sql [list $table column add $name] foreach {opt val} $args { if {$opt in $options} { lappend sql $opt $val } elseif {$opt in $myoptions} { dict lappend columns $name $opt $val } else { error "unknown option $opt" } } eval $sql } method draw {args} { my variable height my variable hull set height [tableview::default $args -height $height] set title [tableview::default $args -title "SQL data"] wm title $hull $title my variable columns foreach col [dict keys $columns] { pack [frame $hull.$col] -side left label $hull.$col.title -text [tableview::default [dict get $columns $col] -title $col] pack $hull.$col.title -side top for {set i 0} {$i < $height} {incr i} { pack [label $hull.$col.row$i -text ""] -side top } } pack [scrollbar $hull.scrolling -command [list [self] yview]] -side left my redraw my sync_scrolling } method sync_scrolling {} { my variable start set len [my delegate length] if {$len == 0} {return} if {$start > $len} { # rows have been removed under the cursor set start 1 my redraw my sync_scrolling return } my variable hull my variable height $hull.scrolling set [expr {double($start-1)/$len}] [expr {min(1.,double($start+$height-1)/$len)}] } method yview {sub args} { my variable start set start [my yview_$sub {*}$args] my sync_scrolling } method yview_moveto {fraction} { my redraw [expr {[my delegate length]*$fraction}] } method yview_scroll {number type} { my yview_scroll_$type $number } method yview_scroll_units {n} { my variable start my variable height set len [my delegate length] if {$len < $height || $start+$n<1} {return [my redraw]} if {$n > 0} { if {$start+$n > $len-$height+1} { return [my redraw [expr {$len-$start-$height+1}]] } return [my redraw [expr {$start + $n}]] } my redraw [expr {$start+$n}] } method yview_scroll_pages {n} { my variable height my yview_scroll_units [expr {$n*($height-1)}] } method redraw {{mystart 1}} { my variable start my variable height my variable table my variable columns my variable hull set mystart [expr {round($mystart)}] set names [dict keys $columns] set end [expr {min($height+$mystart-1,[$table length])}] puts $mystart,$end set data [$table get range $mystart $end] for {set i 0} {$i < [llength $data]} {incr i} { set row [lindex $data $i] foreach name $names { $hull.$name.row$i configure -text [dict get $row $name] } } return $mystart } } }
Usage:
sqlite3 db my.db tableview::tableview create tbl .tbl db emp tbl column add emp_name -key yes tbl column add emp_age -type integer tbl draw